diff --git a/.gitignore b/.gitignore index 4b7085e3..b358b21c 100644 --- a/.gitignore +++ b/.gitignore @@ -7,6 +7,8 @@ Phaser OSX.sublime-workspace Phaser.sublime-project Phaser.sublime-workspace *.suo +*.sublime-project +*.sublime-workspace # Vendors node_modules/ diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md new file mode 100644 index 00000000..b8bb632c --- /dev/null +++ b/CONTRIBUTING.md @@ -0,0 +1,72 @@ +#How to contribute + +It's important to us that you feel you can contribute towards the evolution of Phaser. This can take many forms: from helping to fix bugs or improve the docs, to adding in new features to the source. This guide should help you in making that process as smooth as possible. + + +##Reporting issues + +[GitHub Issues][0] is the place to report bugs you may have found in either the core library or any of the examples that are part of the repository. When submitting a bug please do the following: + +1. **Search for existing issues.** Your bug may have already been fixed or addressed in a development branch version of Phaser, so be sure to search the issues first before putting in a duplicate issue. + +2. **Create an isolated and reproducible test case.** If you are reporting a bug, make sure you also have a minimal, runnable, code example that reproduces the problem you have. + +3. **Include a live example.** After narrowing your code down to only the problem areas, make use of[jsFiddle][1], [jsBin][2], or a link to your live site so that we can view a live example of the problem. + +4. **Share as much information as possible.** Include browser version affected, your OS, version of the library, steps to reproduce, etc. "X isn't working!!!1!" will probably just be closed. + + +##Pixi and Phaser + +It's important to understand that internally Phaser uses [Pixi.js](https://github.com/GoodBoyDigital/pixi.js/) for all rendering. It's possible you may find a bug that is generated on the Pixi level rather than Phaser. You're welcome to still report the issue of course, but if you get a reply saying we think it might be a Pixi issue this is what we're talking about :) + + +##Support Forum + +We have a very active [Phaser Support Forum](http://www.html5gamedevs.com/forum/14-phaser/). If you need general support, or are struggling to understand how to do something or need your code checked over, then we would urge you to post it to our forum. There are a lot of friendly devs in there who can help, as well as the core Phaser and Pixi teams, so it's a great place to get support from. You're welcome to report bugs directly on GitHub, but for general support we'd always recommend using the forum first. + + +##Dev vs. Master + +The dev branch of Phaser is our 'current working' version. It is always ahead of the master branch in terms of features and fixes. However it's also bleeding-edge and experimental and we cannot and do not guarantee it will compile or work for you. Very often we have to break things for a few days while we rebuild and patch. So by all means please export the dev branch and contribute towards it, indeed that is where all Pull Requests should be sent, but do so understanding the API may change beneath you. + + +##Making Changes + +To take advantage of our grunt build script and jshint config it will be easiest for you if you have node.js and grunt installed locally. + +You can download node.js from[nodejs.org][3]. After it has been installed open a console and run `npm i - g grunt - cli` to install the global `grunt` executable. + +After that you can clone the repository and run `npm i` inside the cloned folder. This will install dependencies necessary for building the project. Once that is ready, +make your changes and submit a Pull Request: + +- **Send Pull Requests to the `dev` branch.** All Pull Requests must be sent to the `dev` branch, `master` is the latest release and PRs to that branch will be closed. + +- **Ensure changes are jshint validated.** Our JSHint configuration file is provided in the repository and you should check against it before submitting. + +- **Never commit new builds.** When making a code change you should always run `grunt` which will rebuild the project so you can test, *however* please do not commit these new builds or your PR will be closed. Builds by default are placed in the `dist` folder, to keep them separate from the `build` folder releases. + +- **Only commit relevant changes.** Don't include changes that are not directly relevant to the fix you are making. The more focused a PR is, the faster it will get attention and be merged. Extra files changing only whitespace or trash files will likely get your PR closed. + + +##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. + + +##Code Style Guide + +- Use 4 spaces for tabs, never tab characters. + +- No trailing whitespace, blank lines should have no whitespace. + +- Always favor strict equals` === `unless you * need * to use type coercion. + +- Follow conventions already in the code, and listen to jshint. Our config is set-up for a reason. + +Thanks to Chad for creating the original Pixi.js Contributing file which we adapted for Phaser. + +[0]: https://github.com/photonstorm/phaser/issues +[1]: http://jsfiddle.net +[2]: http://jsbin.com/ +[3]: http://nodejs.org diff --git a/Gruntfile.js b/Gruntfile.js index d44632b2..f228334f 100644 --- a/Gruntfile.js +++ b/Gruntfile.js @@ -69,6 +69,9 @@ module.exports = function (grunt) { 'src/input/Pointer.js', 'src/input/Touch.js', 'src/input/InputHandler.js', + 'src/input/Gamepad.js', + 'src/input/SinglePad.js', + 'src/input/GamepadButton.js', 'src/gameobjects/Events.js', 'src/gameobjects/GameObjectFactory.js', 'src/gameobjects/BitmapData.js', @@ -96,6 +99,7 @@ module.exports = function (grunt) { 'src/tween/Easing.js', 'src/time/Time.js', 'src/time/Timer.js', + 'src/time/TimerEvent.js', 'src/animation/AnimationManager.js', 'src/animation/Animation.js', 'src/animation/Frame.js', @@ -108,6 +112,7 @@ module.exports = function (grunt) { 'src/sound/SoundManager.js', 'src/utils/Debug.js', 'src/utils/Color.js', + 'src/physics/arcade/SAT.js', 'src/physics/arcade/ArcadePhysics.js', 'src/physics/arcade/Body.js', 'src/particles/Particles.js', diff --git a/README.md b/README.md index c7ffa4fc..5338ceda 100644 --- a/README.md +++ b/README.md @@ -1,18 +1,19 @@ ![Phaser Logo](http://www.photonstorm.com/wp-content/uploads/2013/09/phaser_10_release.jpg) -Phaser 1.1.3 +Phaser 1.1.4 ============ Phaser is a fast, free and fun open source game framework for making desktop and mobile browser HTML5 games. It uses [Pixi.js](https://github.com/GoodBoyDigital/pixi.js/) internally for fast 2D Canvas and WebGL rendering. -Version: 1.1.3 "Arafel" - Released: November 29th 2013 +Version: 1.1.4 "Kandor" - Released: February 5th 2014 By Richard Davey, [Photon Storm](http://www.photonstorm.com) -View the [Official Website](http://phaser.io)
-Follow on [Twitter](https://twitter.com/photonstorm)
-Join the [Forum](http://www.html5gamedevs.com/forum/14-phaser/)
-Try out 160+ [Phaser Examples](http://gametest.mobi/phaser/examples/) +* View the [Official Website](http://phaser.io) +* Follow on [Twitter](https://twitter.com/photonstorm) +* Join the [Forum](http://www.html5gamedevs.com/forum/14-phaser/) +* Try out 220+ [Phaser Examples](http://examples.phaser.io) +* Read the [documentation online](http://docs.phaser.io) [Subscribe to our new Phaser Newsletter](https://confirmsubscription.com/h/r/369DE48E3E86AF1E). We'll email you when new versions are released as well as send you our regular Phaser game making magazine. @@ -22,13 +23,23 @@ Try out 160+ [Phaser Examples](http://gametest.mobi/phaser/examples/) Welcome to Phaser ----------------- -Over 1000 github stars! Wow! The latest release of Phaser represents another hard months work by the development team and the community at large. We've had some great contributions and have not let-up the pace of innovating and pushing Phaser forward. As we march towards the end of 2013 we do so knowing that with every passing month more and more developers are using Phaser, and more games are being made. All while it is getting stronger with each release. +As you may know we had planned to release 1.1.4 at the end of 2013. For various reasons this didn't quite happen, but we're happy to announce it's finally out! There have been some dramatic changes internally, and if you make use of either the physics systems or tilemaps then you are going to need to update your code. Hopefully only a little bit, but there have been a number of core API changes which we detail below. There are also a host of new features, the headliners being: -Our plan is to end 2013 with one final point release (1.1.4 - "Kandor") and then we'll start planning out the features we wish to see in version 1.2 in the New Year. +* New Physics system. Uses SAT.js internally so physics bodies can now be rectangles, circles or polygons and support rotation. +* New Tilemap system. Brand new collision system for tiles, much more advanced layer handling, tile properties, multiple tilesets of layer and more. +* New Timer. This handy new class lets you create timed events easily. +* Your Game can now be configured from an external configuration object. +* Over 150 new features and updates and over 30 reported bug fixes. -As always we offer a heart-felt "Thank you!" to everyone who has encouraged us along the way. To those of you who worked with Phaser during its various incarnations, and who released full games with it despite there being zero API documentation available back then: you are our heroes. It's your kind words and enthusiasm that has kept us going. +This release also brings the TypeScript definitions file as bang up to date as possible. There are still a few areas that need looking at, but with your help hopefully we can iron those final few bits out and have a 100% accruate defs file on offer. -Phaser is everything we ever wanted from an HTML5 game framework. It powers all of our client work in build today and remains our single most important product, and we've only just scratched the surface of what we have planned for it. +There is a new Contributors Guide which we'd urge you to follow if you wish to help with Phaser development, and we've updated the doc files and added lots more details into key areas. The Examples have grown too! Now over 220 of them including several great ones from the community. + +We're going to settle on this build for a short while as we do some quick iteration bug fixing, so expect to see some small point releases very soon that do nothing but address any issues you may find. But in parallel to this we are also now rebuilding our core to bring it in-line with the latest version of Pixi.js, which has had some dramatic changes under the hood, changes will impact a lot of what Phaser does internally. But the changes are all for the better and once we upgrade Pixi you'll have a significantly faster renderer and a smaller codebase too, as we do away with stacks of linked list code :) + +As always we offer a heart-felt "Thank you!" to everyone who has encouraged us along the way. To those of you who worked with Phaser during its various incarnations. The number of games being released that were made with Phaser is staggering and we really love to see how you use it! You are our heroes. It's your kind words and enthusiasm that has keeps us going. + +Phaser is everything we ever wanted from an HTML5 game framework. It powers all of our client work in build today and remains our single most important product, and we've still only just scratched the surface of what we have planned for it. ![MiniCybernoid](http://www.photonstorm.com/wp-content/uploads/2013/10/phaser-cybernoid-640x480.png) @@ -36,83 +47,189 @@ Phaser is everything we ever wanted from an HTML5 game framework. It powers all Getting Started Guides ---------------------- -We have a new [Getting Started Guide](http://phaser.io/getting-started-js.php) which covers all you need to begin developing games with Phaser. From setting up a web server to picking an IDE. If you're new to HTML5 game development (or are coming from another language like AS3) then we recommend starting there. +We have a new [Getting Started Guide](http://phaser.io/getting-started-js.php) which covers all you need to begin developing games with Phaser. From setting up a web server to picking an IDE. If you're new to HTML5 game development, or are coming from another language like AS3, then we recommend starting there. -There is also this great [Un-official Getting Started Guide](http://www.antonoffplus.com/coding-an-html5-game-for-30-minutes-or-an-introduction-to-the-phaser-framework) which is well worth running through as well. +There is a comprehensive [How to Learn Phaser](http://gamedevelopment.tutsplus.com/articles/how-to-learn-the-phaser-html5-game-engine--gamedev-13643) guide on the GameDevTuts+ site which is a great place to learn where to find tutorials, examples and support. + +There is also an [un-official Getting Started Guide](http://www.antonoffplus.com/coding-an-html5-game-for-30-minutes-or-an-introduction-to-the-phaser-framework). Change Log ---------- -Version 1.1.3 - "Arafel" - November 29th 2013 +Version 1.1.4 - "Kandor" - February 5th 2014 + +Significant API changes: + +* Loader.tileset has been removed as it's no longer required, this was as part of the Tilemap system overhaul. +* TilemapLayers are now created via the Tilemap object itself: map.createLayer(x, y, width, height, tileset, layer, group) and no longer via the GameObjectFactory. +* Tilemap.createFromObjects can now turn a bunch of Tiled objects into Sprites in one single call, and copies across all properties as well. +* Tween.onStartCallback and onCompleteCallback have been removed to avoid confusion. You should use the onStart, onLoop and onComplete events instead. +* Button.forceOut default value has changed from true to false, so Buttons will revert to an Up state (if set) when pressed and released. +* The way the collision process callback works has changed significantly and now works as originally intended. +* The World level quadtree is no longer created, they are now built and ripped down each time you collide a Group, this helps collision accuracy. +* A SAT system has been integrated for Body collision and separation. +* Bodies are no longer added to a world quadtree, so have had all of their quadtree properties removed such as skipQuadtree, quadTreeIndex, etc. +* Body.drag has been removed. Please use the new Body.linearDamping value instead (which is a number value, not a Point object) +* Body.embedded and Body.wasTouching have been removed as they are no longer required. +* Body.customSeparateX/Y have been removed as you should now use Body.customSeparateCallback. +* Body.maxVelocity defaults have been removed from 10,000 to 2000. +* Body.customSeparateCallback allows you to set your own callback when two Bodies need to separate rather than using the built-in method. +* Body.collideCallback allows you to set a callback that is fired whenever the Body is hit on any of its active faces. +* Body.allowCollision has been renamed to Body.checkCollision. +* Body.rebound is a boolean that controls if a body will exchange velocity on collision. Set to false to allow it to be 'pushed' (see new examples). +* Removed Body.deltaAbsX and deltaAbsY as they are no longer used internally. +* Body.screenX and screenY moved to getters, no longer calculated every frame. +* ArcadePhysics now has setBounds and setBoundsToWorld, and you can specify which walls are created or not (left, right, up, down) +* Removed: Debug.renderSpriteTouching, Debug.renderLocalTransformInfo, Debug.renderWorldTransformInfo, Debug.renderSpriteCollision and Debug.dumpLinkedList. +* Body.setSize has been removed. Please use Body.setCircle, setRectangle or setPolygon instead. + New features: -* Phaser.Filter. A new way to use the new WebGL shaders/filters that the new version of Pixi supports. -* Phaser.BitmapData object. A Canvas you can freely draw to with lots of functions. Can be used as a texture for Sprites. See the new examples and docs for details. -* The entire Phaser library has been updated to match the new JSHint configuration. -* Added a .jshintrc so contributions can be run through JSHint to help retain formatting across the library (thanks kevinthompson) -* Added a new in-built texture. Sprites now use __default if no texture was provided (a 32x32 transparent PNG) or __missing if one was given but not found (a 32x32 black box with a green cross through it) -* Loader can now load JavaScript files. Just use game.load.script('key', 'url') - the file will be turned into a script tag in the document head on successful load. -* RenderTexture.render now takes a Phaser.Group. Also added renderXY for when you don't want to make a new Point object. -* Physics.overlap now supports Sprites, Groups or Emitters and can perform group vs. group (etc) overlap checks with a custom callback and process handler. -* Added Sound.externalNode which allows you to connect a Sound to an external node input rather than the SoundManager gain node. -* Added SoundManager.connectToMaster boolean. Used in conjunction with Sound.externalNode you can easily configure audio nodes to connect together for special effects. -* PluginManager.remove, added PluginManager.removeAll (thanks crazysam) -* scrollFactorX/scrollFactorY have been added to TilemapLayers (thanks jcd-as) -* Phaser.Game parent can now be an HTMLElement or a string (thanks beeglebug) -* Now using the latest version of Pixi.js. Which means you can use all the sexy new WebGL filters :) -* Sprite.animations.getAnimation will return an animation instance which was added by name. -* Added Mouse.button which is set to the button that was pressed: Phaser.Mouse.LEFT_BUTTON, MIDDLE_BUTTON or RIGHT_BUTTON (thanks wKLV) -* Added Mouse.pointerLock signal which you can listen to whenever the browser enters or leaves pointer lock mode. -* StageScaleMode.forceOrientation allows you to lock your game to one orientation and display a Sprite (i.e. a "please rotate" screen) when incorrect. -* World.visible boolean added, toggles rendering of the world on/off entirely. -* Polygon class & drawPolygon method added to Graphics (thanks rjimenezda) -* Added Group.iterate, a powerful way to count or return children that match a certain criteria. Refactored Group to use iterate, lots of repeated code cut. -* Added Group.sort. You can now sort the Group based on any given numeric property (x, y, health), finally you can do depth-sorting :) Example created to show. -* Enhanced renderTexture so it can accept a Phaser.Group object and improved documentation and examples. -* Device.littleEndian boolean added. Only safe to use if the browser supports TypedArrays (which IE9 doesn't, but nearly all others do) -* You can now call game.sound.play() and simply pass it a key. The sound will play if the audio system is unlocked and optionally destroy itself on complete. -* Mouse.capture is a boolean. If set to true then DOM mouse events will have event.preventDefault() applied, if false they will propogate fully. -* The object returned by Math.sinCosGenerator now contains a length property. +* Phaser.Timer is now feature complete and fully documented. You can create Phaser.TimerEvents on a Timer and lots of new examples have been provided. +* Gamepad API support has been added with lots of new examples (thanks Karl Macklin) +* Phaser.Game constructor can now be passed a single object containing all of your game settings + Stage settings. Useful for advanced configurations. +* The width/height given to Phaser.Game can now be percentages, i.e. "100%" will set the width to the maximum window innerWidth. +* Added a stage.fullScreenScaleMode property to determine scaling when fullscreen (thanks oysterCrusher) +* Added support for margin and spacing around a frame in Loader.spritesheet. +* Added Device.vibration to check if the Vibration API is available or not. +* Added Device.trident and Device.tridentVersion for testing IE11. +* Added Device.silk for detecting a Kindle Fire and updated desktop OS check to exclude Kindles (thanks LuckieLordie) +* TilemapLayers now have debug and debugAlpha values, this turns on the drawing of the collision edges (very handy for debugging, as the name implies!) +* Tweens have a new event: onLoop. +* You can now load any binary file via the Loader: game.load.binary(key, url, callback) - the optional callback allows for post-load processing before entering the Cache. +* Group.set will let you deep set a new propery on a single child of the Group. +* Stage.display property added. A direct reference to the root Pixi Stage object (very useful for RenderTexture manipulation) +* Added Ejecta detection to Device (thanks endel) +* Tweens can now work with relative + and - values. You can do: `tween(sprite).to( { x: '+400' })` and it will add 400 to the current sprite.x value. +* Buttons now properly use their upFrame if set. +* InputHandler now has snapOffsetX and snapOffsetY properties so your snap grid doesn't have to be 0,0 aligned (thanks srmeier) +* Loader.progressFloat contains the actual non-rounded progress value, where-as Loader.progress contains a rounded value. Use progressFloat if you've > 100 files to load. +* Groups can now be added to other Groups as children via group.add() and group.addAt() +* Groups now have an 'alive' property, which can be useful when iterating through child groups with functions like forEachAlive. +* Added a new Project Template "Full Screen Mobile" which you can find in the resources folder. Contains html / css / layout needed for a deployed Phaser game. +* Body.speed - the current speed of the body. +* Body.angle - the current angle the Body is facing based on its velocity. This is not the same as the Sprite angle that may own the body. +* Body.linearDamping - This now replaces Body.drag and provides for a much smoother damping (friction) experience. +* Body.minBounceVelocity - If a Body has bounce set, this threshold controls if it should rebound or not. Use it to stop 'jittering' on bounds/tiles with super-low velocities. +* QuadTree.populate - you can pass it a Group and it'll automatically insert all of the children ready for inspection. +* Input.setMoveCallback allows you to set a callback that will be fired each time the activePointer receives a DOM move event. +* Math.distancePow(x1,y1,x2,y2,power) returns the distance between two coordinates at the given power. +* Physics.collide now supports the 2nd parameter as an array, for when you want to collide an object against a number of sprites that aren't all in the same Group. +* Physics.overlap now supports the 2nd parameter as an array, for when you want to overlap test an object against a number of sprites that aren't all in the same Group. +* Math.reverseAngle - reverses an angle (in radians). +* Math.normalizeAngle - normalises an angle, now in radians only. +* Math.normalizeLatitude - Normalizes a latitude to the [-90,90] range. +* Math.normalizeLongitude - Normalizes a longitude to the [-180,180] range. +* Phaser.Line added to the geometry classes, with full point on line/segment and intersection tests (see new examples) +* Phaser.CANVAS_PX_ROUND is a boolean. If 'true' the Canvas renderer will Math.floor() all coordinates before drawImage, stopping pixel interpolation. Defaults to false. +* Phaser.CANVAS_CLEAR_RECT is a boolean. If 'true' (the default) it will context.clearRect() every frame. If false this is skipped (useful if you know you don't need it) +* Collision now works between Sprites positioned via sprite.x/y, sprite.body.x/y or sprite.body.velocity. +* If you are tweening a sprite and still want physics collision, set `sprite.body.moves = false` otherwise it will fight against the tween motion. +* Game.enableStep will enable core game loop stepping. When enabled you must call game.step() directly (perhaps via a DOM button?), very useful for debugging! +* Game.disableStep turns core update loop stepping off. +* Debug.renderPhysicsBody(body, color) is extremely useful for debugging the new physics bodies. Will draw the outline + points in the color given. +* Debug.renderBodyInfo(sprite, x, y, color) will display lots of Sprite body data. +* Sprite.events.onBeginContact will be fired when a Body makes contact with another Body. Once contact is over an onEndContact event will be dispatched. + + +New Examples: + +* Physics - Bounce by Patrick OReilly. +* Physics - Bounce with gravity by Patrick OReilly. +* Physics - Bounce accelerator (use the keyboard) by Patrick OReilly. +* Physics - Bounce knock (use the keyboard) by Patrick OReilly. +* Physics - Snake (use the keyboard to control the snake like creature) by Patrick OReilly and Richard Davey. +* Physics - Launcher - Angry Birds style ball launcher demo by Patrick OReilly. +* Physics - Launcher Follow - throw the sprite anywhere in the world by Patrick OReilly. +* Physics - Launcher Follow World - an advanced version of the Launcher Follow example by Patrick OReilly. +* Input - Touch Joystick example showing how to use the clay.io virtual game controller (thanks gabehollombe) +* Games - Matching Pairs by Patrick OReilly. +* Games - Simon Says by Patrick OReilly. +* Tweens - Example showing how to use the tween events, onStart, onLoop and onComplete. +* Display - Pixi Render Texture. A Phaser conversion of the Pixi.js Render Texture example. +* Input - 5 new examples showing how to use the Gamepad API (thanks Karl Macklin) +* Animation - Group Creation, showing how to create animations across all Group children in one call. +* Particles - Rain by Jens Anders Bakke. +* Particles - Snow by Jens Anders Bakke. +* Groups - Nested Groups - showing how to embed one Group into another Group. +* Time - Lots of new examples showing how to use the updated Phaser.Timer class. + Updates: -* Lots of documentation fixes and updates across nearly all files. Tilemap now documented for example and lots of instances of 'Description' filled out. -* ArcadePhysics.updateMotion applies the dt to the velocity calculations as well as position now (thanks jcs) -* RequestAnimationFrame now retains the callbackID which is passed to cancelRequestAnimationFrame. -* Button now goes back to over state when setFrames used in action (thanks beeglebug) -* plugins now have a postUpdate callback (thanks cocoademon) -* Tided up the Graphics object (thanks BorisKozo) -* If running in Canvas mode and you have a render function it will save the context and reset the transform before running your render function. -* Sprite will now check the exists property of the Group it is in, if the Group.exists = false the Sprite won't update. -* If you specify 'null' as a Group parent it will now revert to using the World as the parent (before only 'undefined' worked) -* Skip preupdate/update for PIXI hierarchies in which an ancestor doesn't exist (thanks cocoademon) -* Loader.audio can now accept either an array of URL strings or a single URL string (thanks crazysam + kevinthompson) -* MSPointer updated to support IE11 by dropping the prefix from the event listeners. -* Device.cocoonJS added to detect if the game is running under Cocoon or a native browser. -* Loader now uses a new queue system internally, meaning you can have assets with the same key spread across different types. +* Updated to latest Pixi.js dev branch build (pre 1.4 release) +* When a Sprite is destroyed any active filters are removed at the same time. +* Updated Pixi.js so that removing filters now works correctly without breaking the display list. +* Phaser.Canvas.create updated so it can be given an ID as the 3rd parameter (can also be set via new Game configuration object). +* Updated display/fullscreen example to reflect new full screen change. +* Loads of updates to the TypeScript definitions files - games fully compile now and lots of missing classes added :) (thanks Niondir) +* Removed 'null parent' check from Group constructor. Will parent to game.world only if parent value is undefined. +* The tutorials have now been translated into Spanish - thanks feiss :) +* separateY updated to re-implement the 'riding platforms' special condition (thanks cocoademon) +* SoundManager.onSoundDecode now dispatches the key followed by the sound object, also now dispatched by the Cache when doing an auto-decode on load. +* Switch method of using trimmed sprites to support scaling and rotation (thanks cocoademon) +* Most of the GameObjectFactory functions now have a group parameter, so you can do: game.add.sprite(x, y, frame, frameName, group) rather than defaulting to the World group. +* Group.countLiving and countDead used to return -1 if the Group was empty, but now return 0. +* Text can now be fixedToCamera, updated world/fixed to camera example to show this. +* ArcadePhysics.overlap and collide now recognise TileSprites in the collision checks. +* Lots of documentation fixes in the Tween class. +* Tweens fire an onLoop event if they are set to repeat. onComplete is now only fired for the final repeat (or never if the repeat is infinite) +* Pointer used to un-pause a paused game every time it was clicked/touched (this avoided some rogue browser plugins). Now only happens if Stage.disableVisibilityChange is true. +* Input doesn't set the cursor to default if it's already set to none. +* You can now collide a group against itself. This will check all children against each other, but not themselves (thanks cocoademon) +* RenderTexture.render / renderXY has a new parameter: renderHidden, a boolean which will allow you to render Sprites even if their visible is set to false. +* Added in prototype.constructor definitions to every class (thanks darkoverlordofdata) +* Group.destroy has a new parameter: destroyChildren (boolean) which will optionally call the destroy method of all Group children. +* Button.clearFrames method has been added. +* Device.quirksMode is a boolean that informs you if the page is in strict (false) or quirks (true) mode. +* Canvas.getOffset now runs a strict/quirks check and uses document.documentElement when calculating scrollTop and scrollLeft to avoid Chrome console warnings. +* The Time class now has its own Phaser.Timer which you can access through game.time.events. See the new Timer examples to show how to use them. +* Added StateManager.getCurrentState to return the currently running State object (thanks Niondir) +* Removed the console.log redirect from Utils as it was messing with Firefox. +* Body.acceleration is now much smoother and less eratic at high speeds. +* Removed ArcadePhysics binding to the QuadTree, so it can now be used independantly of the physics system. +* Removed ArcadePhysics.preUpdate and postUpdate as neither are needed any more. +* Body.bottom and Body.right are no longer rounded, so will give accurate sub-pixel values. +* Fixed lots of documentation in the Emitter class. +* The delta timer value used for physics calculations has had its cap limit modified from 1.0 to 0.05 in line with the core updates. +* Phaser.Math.min enhanced so you can now pass in either an array of numbers or lots of numbers as parameters to get the lowest. +* Phaser.Math.max added as the opposite of Math.min. +* Phaser.Math.minProperty and maxProperty added. Like Math.min/max but can be given a property an an array or list of objects to inspect. +* Added 'full' paramter to Body.reset, allowing you to control if motion or all data is reset or not. +* Exposed Group.pivot and Sprite.pivot to allow you to directly set the pivot points for rotation. +* Swapped to using the native and faster Array.isArray check. +* Added callback context parameter to Tween.onUpdateCallback(callback, context) to avoid having to bind or create anonymous functions. +* Updated TweenManager.removeAll so it flags all tweens as pendingDelete rather than nuking the array, to avoid tween callback array size errors (thanks DarkDev) + Bug Fixes: -* Lots of fixes to the TypeScript definitions file (many thanks gltovar) -* Tilemap commands use specified layer when one given (thanks Izzimach) -* Mouse.stop now uses the true useCapture, which means the event listeners stop listening correctly (thanks beeglebug) -* Input Keyboard example fix (thanks Atrodilla) -* BitmapText.destroy now checks if it has a canvas before calling parentNode on it. -* Group.swap had a hellish to find bug that only manifested when B-A upward swaps occured. Hours of debugging later = bug crushed. -* Point.rotate asDegrees fixed (thanks BorisKozo) -* ArcadePhysics.separateTile wasn't returning the value, so the custom process callback wasn't getting called (thanks flameiguana) -* StageScaleMode.forceOrientation now correctly stores the forcePortrait value (thanks haden) -* Fixes to Math and Loader (thanks theJare) -* Tween - isRunning not reset when non-looped tween completes (thanks crazysam + kevinthompson) -* Math.normalizeAngle and Math.wrapAngle (thanks theJare) -* Device.isTouch modified to test maxTouchPointers instead of MSPointer. -* InputHandler.checkPointerOver now checks the visible status of the Sprite Group before processing. -* The Sprite hulls (used for tile collision) were not being updated in sprite->sprite separations (thanks jcs) -* Plugins that had a postUpdate but no Update weren't being marked as active (thanks crazysam) -* StateManager.onPausedCallback function is not called when the game is paused (thanks haden) -* Fix for 'jitter' in scrolling where tilemaps & sprites are one frame off (thanks jcs) +* Cache.getImageKeys returned __missing in the array, now excluded. +* Fixed Group.scale so you can now scale a Group directly. +* Removed World.scale as it was preventing Group.scale from working - you can still scale the world, but you'll need to factor in Input changes yourself. +* Moved 'dirty' flag for Tilemap to a per-layer flag. Fixes #242 +* Group.length now returns the number of children in the Group regardless of their exists/alive state, or 0 if the Group has no children. +* Switch Camera.setBoundsToWorld to match world.bounds instead of world (thanks cocoademon) +* Fixed an issue where passing null as the Group parent wouldn't set it to game.world as it should have (thanks tito100) +* Fixed Pixi bug (#425) incorrect width property for multi-line BitmapText (thanks jcd-as) +* Tween.onStart is now called when the tween starts AFTER the delay value, if given (thanks stevenbouma) +* Sprites that are fixedToCamera can now be input dragged regardless of world position (thanks RafaelOliveira) +* RenderTexture now displays correctly in Canvas games. +* Canvas.addToDOM is now more robust when applying the overflowHidden style. +* Fixed Pixi.StripShader which should stop the weird TileSprite GPU issues some were reporting (thanks GoodboyDigital) +* Patched desyrel.xml so it doesn't contain any zero width/height characters, as they broke Firefox 25. +* Cache.addSound now implements a locked attribute (thanks haden) +* Sound now checks for CocoonJS during playback to avoid readyState clash (thanks haden) +* Buttons now clear previously set frames correctly if you call setFrames. +* Sounds will now loop correctly if they are paused and resumed (thanks haden) +* InputHandler.checkBoundsRect and checkBoundsSprite now take into account if the Sprite is fixedToCamera or not. +* Removed the frame property from TileSprites as it cannot use them, it tiles the whole image only, not just a section of it. +* Fixed WebGLRenderer updateGraphics bug (thanks theadam) +* Removed duplicate Timer.create line (thanks hstolte) +* Fixed issue with the camera being slightly out of sync with 'fixedToCamera' sprites. +* 1px camera jitter issue fixed where map is same size, or smaller than the game size. You can view the Change Log for all previous versions at https://github.com/photonstorm/phaser/changelog.md @@ -127,9 +244,37 @@ We also provide a Grunt script that will build Phaser from source along with all Run `grunt` in the phaser folder for a list of command-line options. + +Koding +------ + +You can [![clone the Phaser repo in Koding](http://learn.koding.com/btn/clone_d.png)][koding] and then start editing and previewing code right away using their web based VM development system. + + +Bower +----- + +If you use bowser you can install phaser with: + +`bower install phaser` + +Nice and easy :) + ![Tanks](http://www.photonstorm.com/wp-content/uploads/2013/10/phaser_tanks-640x480.png) +CDNJS +----- + +Thanks to a community member Phaser is now available on [CDNJS](http://cdnjs.com). You can include the following in your html: + +`http://cdnjs.cloudflare.com/ajax/libs/phaser/1.1.3/phaser.min.js` + +Or if you prefer you can leave the protocol off, so it works via http and https: + +`//cdnjs.cloudflare.com/ajax/libs/phaser/1.1.3/phaser.min.js` + + Requirements ------------ @@ -140,6 +285,24 @@ For developing with Phaser you can use either a plain-vanilla JavaScript approac Phaser is 321 KB minified and 72 KB gzipped. +Learn By Example +---------------- + +Phaser comes with an ever growing suite of Examples. Personally I feel that we learn better by looking at small refined code examples, so we created over 200 of them and create new ones to test every new feature added. Inside the `examples` folder you'll find the current set. If you write a particularly good example then please send it to us. + +The examples need to be run through a local web server (in order to avoid file access permission errors from your browser). You can use your own web server, or start the included web server using grunt. + +Using a locally installed web server browse to the examples folder: + + examples/index.html + +Alternatively in order to start the included web server, after you've cloned the repo, run `npm install` to install all dependencies, then `grunt connect` to start a local server. After running this command you should be able to access your local webserver at `http://127.0.0.1:8000`. Then browse to the examples folder: `http://127.0.0.1:8000/examples/index.html` + +There is a new 'Side View' example viewer as well. This loads all the examples into a left-hand frame for faster navigation. + +You can also browse all [Phaser Examples](http://gametest.mobi/phaser/) online. + + Features -------- @@ -153,7 +316,7 @@ We've made the loading of assets as simple as one line of code. Images, Sounds, **Physics** -Phaser ships with our Arcade Physics system. An extremely light-weight AABB physics library perfect for low-powered devices and fast collision response. Control velocity, acceleration, bounce, drag and full collision and separation control. +Phaser ships with our Arcade Physics system. A SAT based collision and physics library perfect for low-powered devices and fast collision response. Control velocity, acceleration, bounce, damping and full collision and separation control. As of version 1.1.4 we now support rectangles, circles and polygon collision with full rotation. **Sprites** @@ -206,7 +369,7 @@ We use Phaser every day on our many client projects. As a result it's constantly **Battle Tested** -Although Phaser 1.0 is a brand new release it is born from years of experience building some of the biggest HTML5 games out there. We're not saying it is 100% bug free, but we use it for our client work every day, so issues get resolved fast and we stay on-top of the changing browser landscape. +Although Phaser 1.0 is a brand new release it is born from years of experience building some of the biggest mobile HTML5 games out there. We're not saying it is 100% bug free, but we use it for our client work every day, so issues get resolved fast and we stay on-top of the changing browser landscape. ![FruitParty](http://www.photonstorm.com/wp-content/uploads/2013/10/phaser_fruit_particles-640x480.png) @@ -214,68 +377,60 @@ Although Phaser 1.0 is a brand new release it is born from years of experience b Road Map -------- -The 1.1 release was a massive under-taking, but we're really happy with how Phaser is progressing. It's becoming more solid and versatile with each iteration. Here is what's on our road map for future versions: +Here is what's on our road map for the coming months: -Version 1.1.4 ("Kandor") +Version 1.1.5 ("Saldaea") + +* A fast turn-around point release that will focus on addressing any bugs that occured as a result of the large changes that took place in 1.1.4. + +Version 1.2 ("Shienar") + +* Update to Pixi 1.4 - this newly released build has lots of internal changes and new features we want to take advantage of. + +Version 1.3 ("Tarabon") * Enhance the State Management, so you can perform non-destructive State swaps and persistence. -* More advanced tile map features. Better support for advanced Tiled features. Proper support for DAME tilemaps. - -Versions 1.2 ("Saldaea") - -* Integration with an advanced physics system. We've been experimenting with p2.js but have yet to conclude our research. +* Dedicated CocoonJS packaging features (screencanvas, etc) * A more advanced Particle system, one that can render to a single canvas (rather than spawn hundreds of Sprites), more advanced effects, etc. - -Version 1.2+ - -* Massively enhance the audio side of Phaser. Although it does what it does well, it could do with taking more advantage of Web Audio - echo effects, positional sound, etc. -* Comprehensive testing across Firefox OS devices, CocoonJS and Ejecta. -* Integration with third party services like Google Play Game Services and Amazon JS SDK. * Ability to control DOM elements from the core game and layer them into the game. * Touch Gestures. -* Virtual d-pad support and also support for the Joypad API. -* Test out packaging with Node-webkit. +* Support for parallel asset loading. +* Fixed width bitmap font support, plus enhanced Bitmap font rendering. + +Version 2.0 ("Aes Sedai") + +* Integrate p2.js physics system completely. +* Comprehensive testing across Firefox OS devices, CocoonJS and Ejecta. +* Integration with third party services like Google Play Game Services and Amazon JS SDK. * Flash CC HTML5 export integration. +* Massively enhance the audio side of Phaser. Although it does what it does well, it could do with taking more advantage of Web Audio - echo effects, positional sound, etc. + +Beyond version 2.0 + +* Test out packaging with Node-webkit. * Game parameters stored in Google Docs. -* Add a d-pad example (http://www.html5gamedevs.com/topic/1574-gameinputondown-question/) -* Create more touch input examples (http://www.html5gamedevs.com/topic/1556-mobile-touch-event/) * Look at HiDPI Canvas settings. - - -Learn By Example ----------------- - -Phaser comes with an ever growing suite of Examples. Personally I feel that we learn better by looking at small refined code examples, so we created over 150 of them and create new ones to test every new feature added. Inside the `examples` folder you'll find the current set. If you write a particularly good example then please send it to us. - -The examples need to be run through a local web server (in order to avoid file access permission errors from your browser). You can use your own web server, or start the included web server using grunt. - -Using a locally installed web server browse to the examples folder: - - examples/index.html - -Alternatively in order to start the included web server, after you've cloned the repo, run `npm install` to install all dependencies, then `grunt connect `to start a local server. After running this command you should be able to access your local webserver at `http://127.0.0.1:8000`. Then browse to the examples folder: `http://127.0.0.1:8000/examples/index.html` - -There is a new 'Side View' example viewer as well. This loads all the examples into a left-hand frame for faster navigation. - -You can also browse all [Phaser Examples](http://gametest.mobi/phaser/) online. +* Multiple Camera support. Contributing ------------ -If you find a bug (highly likely!) then please report it on github or our forum. +We now have a full [Contributors Guide][contribute] which goes into the process in more detail, but here are the headlines: -If you have a feature request, or have written a small game or demo that shows Phaser in use, then please get in touch. We'd love to hear from you. +- If you find a bug then please report it on [GitHub Issues][issues] or our [Support Forum][forum]. -You can do this on the Phaser board that is part of the [HTML5 Game Devs forum](http://www.html5gamedevs.com/forum/14-phaser/) or email: rich@photonstorm.com +- If you have a feature request, or have written a game or demo that shows Phaser in use, then please get in touch. We'd love to hear from you! Either post to our [forum][forum] or email: rich@photonstorm.com -Before submitting a pull request, please run your code through [JSHint](http://www.jshint.com/) to check for stylistic or formatting errors. To use JSHint, first install it by running `npm install jshint`, then test your code by running `jshint src`. This isn't a requirement, we are happy to receive pull requests that haven't been JSHinted, so don't let it put you off contributing - but do know that we'll reformat your source before going live with it. +- If you issue a Pull Request for Phaser, please only do so againt the `dev` branch and *not* against the `master` branch. + +- Before submitting a Pull Request please run your code through [JSHint](http://www.jshint.com/) to check for stylistic or formatting errors. To use JSHint, first install it by running `npm install jshint`, then test your code by running `jshint src`. This isn't a strict requirement and we are happy to receive Pull Requests that haven't been JSHinted, so don't let it put you off contributing, but do know that we'll reformat your source before going live with it. Bugs? ----- -Please add them to the [Issue Tracker][1] with as much info as possible, especially source code demonstrating the issue. +Please add them to the [Issue Tracker][issues] with as much info as possible, especially source code demonstrating the issue. ![Phaser Tilemap](http://www.photonstorm.com/wp-content/uploads/2013/04/phaser_tilemap_collision.png) @@ -287,5 +442,10 @@ License Phaser is released under the [MIT License](http://opensource.org/licenses/MIT). -[1]: https://github.com/photonstorm/phaser/issues +[issues]: https://github.com/photonstorm/phaser/issues +[contribute]: https://github.com/photonstorm/phaser/blob/master/CONTRIBUTING.md [phaser]: https://github.com/photonstorm/phaser +[forum]: http://www.html5gamedevs.com/forum/14-phaser/ +[koding]: https://koding.com/Teamwork?import=https://github.com/photonstorm/phaser/archive/master.zip&c=git1 + +[![Analytics](https://ga-beacon.appspot.com/UA-44006568-2/phaser/index)](https://github.com/igrigorik/ga-beacon) diff --git a/bower.json b/bower.json new file mode 100644 index 00000000..70ab4e24 --- /dev/null +++ b/bower.json @@ -0,0 +1,37 @@ +{ + "name": "phaser", + "version": "1.1.4", + "homepage": "http://phaser.io", + "authors": [ + "photonstorm " + ], + "description": "A fun, free and fast 2D game framework for making HTML5 games for desktop and mobile, supporting Canvas and WebGL.", + "main": "build/phaser.min.js", + "keywords": [ + "html5", + "game", + "games", + "framework", + "canvas", + "WebGL", + "tilemaps", + "physics", + "sprites", + "fonts", + "images", + "audio", + "Web", + "Audio", + "touch", + "input", + "mobile" + ], + "license": "MIT", + "ignore": [ + "**/.*", + "node_modules", + "bower_components", + "test", + "tests" + ] +} diff --git a/build/build.php b/build/build.php index e5a4e48f..b524175f 100644 --- a/build/build.php +++ b/build/build.php @@ -1,4 +1,7 @@ @@ -55,91 +55,97 @@ - - - - - - - - - - - - - + + + + + + + + + + + + + - - - - - - - - + + + + + + + + + + + - - - - - - - - - - + + + + + + + + + + - - - - + + + + - - - + + + - - - + + + + - + - - - + + + - - + + + - - - - - + + + + + - - - + + + - - + + - - + + - - + + + - - - + + + - - - - - - - + + + + + + + EOL; ?> diff --git a/build/phaser.d.ts b/build/phaser.d.ts index f7c84f8a..03393e79 100644 --- a/build/phaser.d.ts +++ b/build/phaser.d.ts @@ -1,1835 +1,2046 @@ declare class Phaser { - static VERSION: string; - static DEV_VERSION: string; - static GAMES: Array; - static AUTO: number; - static CANVAS: number; - static WEBGL: number; - static SPRITE: number; - static BUTTON: number; - static BULLET: number; - static GRAPHICS: number; - static TEXT: number; - static TILESPRITE: number; - static BITMAPTEXT: number; - static GROUP: number; - static RENDERTEXTURE: number; - static TILEMAP: number; - static TILEMAPLAYER: number; - static EMITTER: number; - static BITMAPDATA: number; - static CANVAS_FILTER: number; - static WEBGL_FILTER: number; + static VERSION: string; + static DEV_VERSION: string; + static GAMES: Array; + static AUTO: number; + static CANVAS: number; + static WEBGL: number; + static SPRITE: number; + static BUTTON: number; + static BULLET: number; + static GRAPHICS: number; + static TEXT: number; + static TILESPRITE: number; + static BITMAPTEXT: number; + static GROUP: number; + static RENDERTEXTURE: number; + static TILEMAP: number; + static TILEMAPLAYER: number; + static EMITTER: number; + static BITMAPDATA: number; + static CANVAS_FILTER: number; + static WEBGL_FILTER: number; } declare module Phaser { - class Camera { - constructor(game: Phaser.Game, id: number, x: number, y: number, width: number, height: number); - game: Phaser.Game; - world: Phaser.World; - id: number; + class Camera { + constructor(game: Phaser.Game, id: number, x: number, y: number, width: number, height: number); + game: Phaser.Game; + world: Phaser.World; + id: number; + x: number; + y: number; + width: number; + height: number; + view: Phaser.Rectangle; + screenView: Phaser.Rectangle; + bounds: Phaser.Rectangle; + deadzone: Phaser.Rectangle; + visible: boolean; + atLimit: { x: boolean; y: boolean; }; + target: Phaser.Sprite; + private _edge: number; + static FOLLOW_LOCKON: number; + static FOLLOW_PLATFORMER: number; + static FOLLOW_TOPDOWN: number; + static FOLLOW_TOPDOWN_TIGHT: number; + follow(target: Phaser.Sprite, style?: number): void; + focusOnXY(x: number, y: number): void; + update(): void; + checkWorldBounds(): void; + setPosition(x: number, y: number): void; + setSize(width: number, height: number): void; + } + + class State { + game: Phaser.Game; + add: Phaser.GameObjectFactory; + camera: Phaser.Camera; + cache: Phaser.Cache; + input: Phaser.Input; + load: Phaser.Loader; + stage: Phaser.Stage; + math: Phaser.Math; + sound: Phaser.SoundManager; + time: Phaser.Time; + tweens: Phaser.TweenManager; + world: Phaser.World; + particles: Phaser.Particles; + physics: Phaser.Physics.Arcade; + preload(); + loadUpdate(); + loadRender(); + create(); + update(); + render(); + paused(); + destroy(); + } + + class StateManager { + constructor(game: Phaser.Game, pendingState: Phaser.State); + game: Phaser.Game; + states: { [key: string]: Phaser.State }; + current: string; + onInitCallback(): void; + onPreloadCallback(): void; + onCreateCallback(): void; + onUpdateCallback(): void; + onRenderCallback(): void; + onPreRenderCallback(): void; + onLoadUpdateCallback(): void; + onLoadRenderCallback(): void; + onPausedCallback(): void; + onShutDownCallback(): void; + boot(): void; + add(key: string, state: any, autoStart?: boolean): void; + remove(key: string): void; + start(key: string, clearWorld?: boolean, clearCache?: boolean): void; + dummy(): void; + checkState(key: string): boolean; + link(key: string): void; + getCurrentState(): Phaser.State; + loadComplete(): void; + update(): void; + preRender(): void; + render(): void; + destroy(): void; + } + + class LinkedListItem { + next: LinkedListItem; + prev: LinkedListItem; + first: LinkedListItem; + last: LinkedListItem; + } + + class LinkedList extends LinkedListItem { + total: number; + add(child: LinkedListItem): LinkedListItem; + remove(child: LinkedListItem): void; + callAll(callback: string): void; + dump(): void; + } + + class Signal { + memorize: boolean; + active: boolean; + validateListener(listener: Function, fnName: string): void; + has(listener: Function, context?: any): boolean; + add(listener: Function, listenerContext?: any, priority?: number): Phaser.SignalBinding; + addOnce(listener: Function, listenerContext?: any, priority?: number): Phaser.SignalBinding; + remove(listener: Function, context?: any): Function; + removeAll(): void; + getNumListeners(): number; + halt(): void; + dispatch(...params: any[]): void; + forget(): void; + dispose(): void; + toString(): string; + } + + class SignalBinding { + constructor(signal: Phaser.Signal, listener: Function, isOnce: boolean, listenerContext: Object, priority?: number); + context: Object; + active: boolean; + params: Array; + execute(paramsArr?: Array): void; + detach(): Function; + isBound(): boolean; + isOnce(): boolean; + getListener(): Function; + getSignal(): Phaser.Signal; + toString(): string; + } + + class StateCycle { + preUpdate(): void; + update(): void; + render(): void; + postRender(): void; + destroy(): void; + } + + class Plugin extends StateCycle { + constructor(game: Phaser.Game, parent: any); + game: Phaser.Game; + parent: any; + active: boolean; + visible: boolean; + hasPreUpdate: boolean; + hasUpdate: boolean; + hasRender: boolean; + hasPostRender: boolean; + } + + class PluginManager extends StateCycle { + constructor(game: Phaser.Game, parent: any); + game: Phaser.Game; + private _parent: any; + plugins: Phaser.Plugin[]; + add(plugin: Phaser.Plugin): Phaser.Plugin; + remove(plugin: Phaser.Plugin): void; + } + + class Stage { + constructor(game: Phaser.Game, width: number, height: number); + game: Phaser.Game; + offset: Phaser.Point; + canvas: HTMLCanvasElement; + scaleMode: number; + scale: Phaser.StageScaleMode; + aspectRatio: number; + backgroundColor: string; + disableVisibilityChange: boolean; + boot(): void; + visibilityChange(event: Event): void; + } + + // Wraps a PIXI.DisplayObjectContainer + class Group { + constructor(game: Phaser.Game, parent?: any, name?: string, useStage?: boolean); + game: Phaser.Game; + name: string; + type: number; + exists: boolean; + sortIndex: string; + length: number; + x: number; + y: number; + angle: number; + rotation: number; + visible: boolean; + add(child: any): any; + addAt(child: any, index: number): any; + getAt(index: number): any; + create(x: number, y: number, key: string, frame?: any, exists?: boolean): Phaser.Sprite; + swap(child1: any, child2: any): boolean; + bringToTop(child: any): any; + getIndex(child: any): number; + replace(oldChild: any, newChild: any): void; + setProperty(child: any, key: string[], value: string, operation: number): void; + setAll(key: string, value: number, checkAlive: boolean, checkVisible: boolean, operation: number): void; + subAll(key: string, value: number, checkAlive: boolean, checkVisible: boolean, operation: number): void; + multiplyAll(key: string, value: number, checkAlive: boolean, checkVisible: boolean, operation: number): void; + divideAll(key: string, value: number, checkAlive: boolean, checkVisible: boolean, operation: number): void; + callAllExists(callback: Function, callbackContext: Object, existsValue: boolean): void; + callAll(callback: string, callbackContext?: Object): void; + forEach(callback: Function, callbackContext: Object, checkExists: boolean): void; + forEachAlive(callback: Function, callbackContext: Object): void; + forEachDead(callback: Function, callbackContext: Object): void; + getFirstExists(state: boolean): any; + getFirstAlive(): any; + getFirstDead(): any; + countLiving(): number; + countDead(): number; + getRandom(startIndex: number, length: number): any; + remove(child: any): void; + removeAll(): void; + removeBetween(startIndex: number, endIndex: number): void; + destroy(): void; + dump(full: boolean): void; + } + + class World extends Phaser.Group { + constructor(game: Phaser.Game); + game: Phaser.Game; + bounds: Phaser.Rectangle; + camera: Phaser.Camera; + currentRenderOrderID: number; + group: Phaser.Group; + width: number; + height: number; + centerX: number; + centerY: number; + randomX: number; + randomY: number; + boot(): void; + update(): void; + setBounds( x:number, y:number, width: number, height: number): void; + destroy(): void; + } + + class Game { + /* + * Defaults: + * [width=800] - The width of your game in game pixels. + * [height=600] - The height of your game in game pixels. + * [renderer=Phaser.AUTO] - Which renderer to use: Phaser.AUTO will auto-detect, Phaser.WEBGL, Phaser.CANVAS or Phaser.HEADLESS (no rendering at all). + * [parent=''] - The Games DOM parent. + * [state=null] - Description. + * [transparent=false] - Use a transparent canvas background or not. + * [antialias=true] - Anti-alias graphics. + * */ + constructor(width?: number, height?: number, renderer?: number, parent?: string, state?: Object, transparent?: boolean, antialias?: boolean); + id: number; + width: number; + height: number; + renderer: number; + transparent: boolean; + antialias: boolean; + parent: string; + state: Phaser.StateManager; + renderType: number; + isBooted: boolean; + raf: Phaser.RequestAnimationFrame; + add: Phaser.GameObjectFactory; + cache: Phaser.Cache; + input: Phaser.Input; + load: Phaser.Loader; + math: Phaser.Math; + sound: Phaser.SoundManager; + stage: Phaser.Stage; + time: Phaser.Time; + tweens: Phaser.TweenManager; + world: Phaser.World; + physics: Phaser.Physics.Arcade; + rnd: Phaser.RandomDataGenerator; + device: Phaser.Device; + camera: Phaser.Camera; + canvas: HTMLCanvasElement; + context: Object; + debug: Phaser.Utils.Debug; + particles: Phaser.Particles; + _paused: boolean; + paused: boolean; + boot(): void; + setUpRenderer(): void; + loadComplete(): void; + update(): void; + destroy(): void; + } + + class Input { + constructor(game: Phaser.Game); + static MOUSE_OVERRIDES_TOUCH: number; + static TOUCH_OVERRIDES_MOUSE: number; + static MOUSE_TOUCH_COMBINE: number; + id: number; + active: boolean; + game: Phaser.Game; + hitCanvas: any; + hitContext: any; + pollRate: number; + disabled: boolean; + multiInputOverride: number; + position: Phaser.Point; + speed: Phaser.Point; + circle: Phaser.Circle; + scale: Phaser.Point; + maxPointers: number; + currentPointers: number; + tapRate: number; + doubleTapRate: number; + holdRate: number; + justPressedRate: number; + justReleasedRate: number; + recordPointerHistory: boolean; + recordRate: number; + recordLimit: number; + x: number; + y: number; + totalInactivePointers: number; + totalActivePointers: number; + worldX: number; + worldY: number; + pollLocked: boolean; + pointer1: Phaser.Pointer; + pointer2: Phaser.Pointer; + pointer3: Phaser.Pointer; + pointer4: Phaser.Pointer; + pointer5: Phaser.Pointer; + pointer6: Phaser.Pointer; + pointer7: Phaser.Pointer; + pointer8: Phaser.Pointer; + pointer9: Phaser.Pointer; + pointer10: Phaser.Pointer; + activePointer: Phaser.Pointer; + mousePointer: Phaser.Pointer; + mouse: Phaser.Mouse; + keyboard: Phaser.Keyboard; + touch: Phaser.Touch; + mspointer: Phaser.MSPointer; + interactiveItems: Phaser.LinkedList; + onDown: Phaser.Signal; + onUp: Phaser.Signal; + onTap: Phaser.Signal; + onHold: Phaser.Signal; + boot(): void; + update(): void; + reset(hard?: boolean); + resetSpeed(x: number, y: number); + startPointer(event: Event): Phaser.Pointer; + updatePointer(event: Event): Phaser.Pointer; + stopPointer(event: Event): Phaser.Pointer; + getPointer(state: boolean): Phaser.Pointer; + getPointerFromIdentifier(identifier: number): Phaser.Pointer; + addPointer(): Phaser.Pointer; + } + + class Key { + constructor( game:Phaser.Game, keycode:number ) + isDown:boolean; + isUp:boolean; + altKey:boolean; + ctrlKey:boolean; + shiftKey:boolean; + timeDown:number; + duration:number; + timeUp:number; + repeats:number; + keycode:number; + onDown:Phaser.Signal; + onUp:Phaser.Signal; + justPressed( duration:number ):boolean; + justReleased( duration:number ):boolean; + } + + interface CursorKeys + { + up:Phaser.Key; + down:Phaser.Key; + left:Phaser.Key; + right:Phaser.Key; + } + + class Keyboard { + constructor(game: Phaser.Game); + game: Phaser.Game; + disabled: boolean; + static A: number; + static B: number; + static C: number; + static D: number; + static E: number; + static F: number; + static G: number; + static H: number; + static I: number; + static J: number; + static K: number; + static L: number; + static M: number; + static N: number; + static O: number; + static P: number; + static Q: number; + static R: number; + static S: number; + static T: number; + static U: number; + static V: number; + static W: number; + static X: number; + static Y: number; + static Z: number; + static ZERO: number; + static ONE: number; + static TWO: number; + static THREE: number; + static FOUR: number; + static FIVE: number; + static SIX: number; + static SEVEN: number; + static EIGHT: number; + static NINE: number; + static NUMPAD_0: number; + static NUMPAD_1: number; + static NUMPAD_2: number; + static NUMPAD_3: number; + static NUMPAD_4: number; + static NUMPAD_5: number; + static NUMPAD_6: number; + static NUMPAD_7: number; + static NUMPAD_8: number; + static NUMPAD_9: number; + static NUMPAD_MULTIPLY: number; + static NUMPAD_ADD: number; + static NUMPAD_ENTER: number; + static NUMPAD_SUBTRACT: number; + static NUMPAD_DECIMAL: number; + static NUMPAD_DIVIDE: number; + static F1: number; + static F2: number; + static F3: number; + static F4: number; + static F5: number; + static F6: number; + static F7: number; + static F8: number; + static F9: number; + static F10: number; + static F11: number; + static F12: number; + static F13: number; + static F14: number; + static F15: number; + static COLON: number; + static EQUALS: number; + static UNDERSCORE: number; + static QUESTION_MARK: number; + static TILDE: number; + static OPEN_BRACKET: number; + static BACKWARD_SLASH: number; + static CLOSED_BRACKET: number; + static QUOTES: number; + static BACKSPACE: number; + static TAB: number; + static CLEAR: number; + static ENTER: number; + static SHIFT: number; + static CONTROL: number; + static ALT: number; + static CAPS_LOCK: number; + static ESC: number; + static SPACEBAR: number; + static PAGE_UP: number; + static PAGE_DOWN: number; + static END: number; + static HOME: number; + static LEFT: number; + static UP: number; + static RIGHT: number; + static DOWN: number; + static INSERT: number; + static DELETE: number; + static HELP: number; + static NUM_LOCK: number; + start(): void; + stop(): void; + addKey(keycode: number): Phaser.Key; + addKeyCapture(keycode: any): void; + removeKeyCapture(keycode: number): void; + clearCaptures(): void; + onKeyDown(event: any): void; + onKeyUp(event: any): void; + reset(): void; + justPressed(keycode: number, duration?: number): boolean; + justReleased(keycode: number, duration?: number): boolean; + isDown(keycode: number): boolean; + createCursorKeys():CursorKeys; + } + + class Mouse { + constructor(game: Phaser.Game) + game: Phaser.Game; + callbackContext: Object; + disabled: boolean; + locked: boolean; + static LEFT_BUTTON: number; + static MIDDLE_BUTTON: number; + static RIGHT_BUTTON: number; + mouseDownCallback: Function; + mouseMoveCallback: Function; + mouseUpCallback: Function; + start(): void; + onMouseDown(): void; + onMouseUp(): void; + onMouseMove(): void; + requestPointerLock(): void; + pointerLockChange(): void; + releasePointerLock(): void; + stop(); + } + + class MSPointer { + constructor(game: Phaser.Game); + game: Phaser.Game; + callbackContext: Object; + disabled: boolean; + mouseDownCallback(): void; + mouseMoveCallback(): void; + mouseUpCallback(): void; + start(): void; + onPointerDown(): void; + onPointerUp(): void; + onPointerMove(): void; + stop(): void; + } + + class Pointer { + constructor(game: Phaser.Game, id: number); + game: Phaser.Game; + id: number; + active: boolean; + positionDown: Phaser.Point; + position: Phaser.Point; + circle: Phaser.Circle; + withinGame: boolean; + clientX: number; + clientY: number; + pageX: number; + pageY: number; + screenX: number; + screenY: number; + duation: number; + worldX: number; + worldY: number; + x: number; + y: number; + isMouse: boolean; + isDown: boolean; + isUp: boolean; + timeDown: number; + timeUp: number; + previousTapTime: number; + totalTouches: number; + msSinceLastClick: number; + targetObject: any; + start(event: any): Phaser.Pointer; + update(): void; + move(event: any): void; + leave(event: any): void; + stop(event: any): void; + justPressed(duration?: number): boolean; + justReleased(duration?: number): boolean; + reset(): void; + toString(): string; + } + + class Touch { + constructor(game: Phaser.Game); + game: Phaser.Game; + callbackContext: any; + touchStartCallback: Function; + touchMoveCallback: Function; + touchEndCallback: Function; + touchEnterCallback: Function; + touchLeaveCallback: Function; + touchCancelCallback: Function; + preventDefault: boolean; + disabled: boolean; + start(): void; + consumeDocumentTouches(): void; + onTouchStart(event: any): void; + onTouchCancel(event: any): void; + onTouchEnter(event: any): void; + onTouchLeave(event: any): void; + onTouchMove(event: any): void; + onTouchEnd(event: any): void; + stop(): void; + } + + class InputHandler extends LinkedListItem { + constructor(sprite: Phaser.Sprite); + game: Phaser.Game; + sprite: Phaser.Sprite; + enabled: boolean; + priorityID: number; + useHandCursor: boolean; + isDragged: boolean; + allowHorizontalDrag: boolean; + allowVerticalDrag: boolean; + bringToTop: boolean; + snapOffset: number; + snapOnDrag: boolean; + snapOnRelease: boolean; + snapX: number; + snapY: number; + pixelPerfect: boolean; + pixelPerfectAlpha: number; + draggable: boolean; + boundsSprite: Phaser.Sprite; + consumePointerEvent: boolean; + start(priority: number, useHandCursor: boolean): void; + reset(): void; + stop(): void; + destroy(): void; + pointerX(pointer: number): number; + pointerY(pointer: number): number; + pointerDown(pointer: number): boolean; + pointerUp(pointer: number): boolean; + pointerTimeDown(pointer: number): number; + pointerTimeUp(pointer: number): number; + pointerOver(pointer: number): boolean; + pointerOut(pointer: number): boolean; + pointerTimeOver(pointer: number): number; + pointerTimeOut(pointer: number): number; + pointerDragged(pointer: number): boolean; + checkPointerOver(pointer: number): boolean; + checkPixel(x: number, y: number): boolean; + update(pointer: number): void; + updateDrag(pointer: number): boolean; + justOver(pointer: number, delay: number): boolean; + justOut(pointer: number, delay: number): boolean; + justPressed(pointer: number, delay: number): boolean; + justReleased(pointer: number, delay: number): boolean; + overDuration(pointer: number): number; + downDuration(pointer: number): number; + enableDrag(lockCenter: boolean, bringToTop: boolean, pixelPerfect: boolean, alphaThreshold?: number, boundsRect?: Phaser.Rectangle, boundsSprite?: Phaser.Rectangle): void; + disableDrag(): void; + startDrag(): void; + stopDrag(): void; + setDragLock(allowHorizontal: boolean, allowVertical: boolean): void; + enableSnap(snapX: number, snapY: number, onDrag?: boolean, onRelease?: boolean): void; + disableSnap(): void; + checkBoundsRect(): void; + checkBoundsSprite(): void; + } + + class Event { + constructor(sprite: Phaser.Sprite); + parent: Phaser.Sprite; + onAddedToGroup: Phaser.Signal; + onRemovedFromGroup: Phaser.Signal; + onKilled: Phaser.Signal; + onRevived: Phaser.Signal; + onOutOfBounds: Phaser.Signal; + onInputOver: Phaser.Signal; + onInputOut: Phaser.Signal; + onInputDown: Phaser.Signal; + onInputUp: Phaser.Signal; + onDragStart: Phaser.Signal; + onDragStop: Phaser.Signal; + onAnimationStart: Phaser.Signal; + onAnimationComplete: Phaser.Signal; + onAnimationLoop: Phaser.Signal; + } + + class GameObjectFactory { + constructor(game: Phaser.Game); + game: Phaser.Game; + world: Phaser.World; + existing(object: any): any; + sprite(x: number, y: number, key?: string, frame?: any): Phaser.Sprite; + child(parent: any, x: number, y: number, key?: string, frame?: number): Phaser.Sprite; + tween(obj: Object): Phaser.Tween; + group(parent?: any, name?: string): Phaser.Group; + audio(key: string, volume?: number, loop?: boolean): Phaser.Sound; + tileSprite(x: number, y: number, width: number, height: number, key?: string, frame?: number): Phaser.TileSprite; + text(x: number, y: number, text: string, style: any): Phaser.Text; + button(x: number, y: number, key: string, callback: Function, callbackContext: Object, overFrame?: any, outFrame?: any, downFrame?: any): Phaser.Button; + graphics(x: number, y: number): Phaser.Graphics; + emitter(x: number, y: number, maxParticles: number): Phaser.Particles.Arcade.Emitter; + bitmapText(x: number, y: number, text: string, style: any): Phaser.BitmapText; + tilemap(x: number, y: number, key: string, resizeWorld: boolean, tileWidth: number, tileHeight: number): Phaser.Tilemap; + renderTexture(key: string, width: number, height: number): Phaser.RenderTexture; + } + + class Sprite { + constructor(game: Phaser.Game, x?: number, y?: number, key?: string, frame?: number); + game: Phaser.Game; + exists: boolean; + alive: boolean; + group: Phaser.Group; + name: string; + type: number; + renderOrderID: number; + lifespan: number; + events: Phaser.Events; + animations: Phaser.AnimationManager; + input: Phaser.InputHandler; + key: string; + currentFrame: number; + anchor: Phaser.Point; + x: number; + y: number; + cameraOffset:Phaser.Point; + position: Phaser.Point; + autoCull: boolean; + scale: Phaser.Point; + scrollFactor: Phaser.Point; + offset: Phaser.Point; + center: Phaser.Point; + topLeft: Phaser.Point; + topRight: Phaser.Point; + bottomRight: Phaser.Point; + bottomLeft: Phaser.Point; + bounds: Phaser.Rectangle; + body: Phaser.Physics.Arcade.Body; + inWorld: boolean; + inWorldThreshold: number; + angle: number; + frame: number; + frameName: string; + inCamera: boolean; + crop: Phaser.Rectangle; + cropEnabled: boolean; + inputEnabled: boolean; + fixedToCamera:boolean; + preUpdate(): void; + postUpdate(): void; + centerOn(x: number, y: number): void; + revive(): void; + kill(): void; + reset(x: number, y: number): void; + updateBounds(): void; + getLocalPosition(p: Phaser.Point, x: number, y: number): Phaser.Point; + getLocalUnmodifiedPosition(p: Phaser.Point, x: number, y: number): Phaser.Point; + bringToTop(): void; + getBounds(rect: Phaser.Rectangle): Phaser.Rectangle; + alpha: number; + visible: boolean; + renderable: boolean; + width: number; + health: number; + damage(amount: number): Phaser.Sprite; + } + + class Events { + parent: Phaser.Sprite; + onAddedToGroup: Phaser.Signal; + onRemovedFromGroup: Phaser.Signal; + onKilled: Phaser.Signal; + onRevived: Phaser.Signal; + onOutOfBounds: Phaser.Signal; + onInputOver: Phaser.Signal; + onInputOut: Phaser.Signal; + onInputDown: Phaser.Signal; + onInputUp: Phaser.Signal; + onDragStart: Phaser.Signal; + onDragStop: Phaser.Signal; + onAnimationStart: Phaser.Signal; + onAnimationComplete: Phaser.Signal; + onAnimationLoop: Phaser.Signal; + } + + class TileSprite extends Sprite { + constructor(game: Phaser.Game, x: number, y: number, width: number, height: number, key?: string, frame?: number); + texture: Phaser.RenderTexture; + type: number; + tileScale: Phaser.Point; + tilePosition: Phaser.Point; + } + + class Text { + constructor(game: Phaser.Game, x: number, y: number, text: string, style: any); + exists: boolean; + alive: boolean; + group: Phaser.Group; + content: string; + name: string; + game: Phaser.Game; + type: number; + text: string; + angle: number; + style: any; + visible: boolean; + position: Phaser.Point; + anchor: Phaser.Point; + scale: Phaser.Point; + scrollFactor: Phaser.Point; + renderable: boolean; + update(): void; + } + + class BitmapText extends Phaser.Text { + constructor(game: Phaser.Game, x?: number, y?: number, text?: string, style?: Object); + alive: boolean; + anchor: Phaser.Point; + angle: number; + exist: boolean; + game: Phaser.Game; + group: Phaser.Group; + name: string; + renderable: boolean; + scale: Phaser.Point; + type: number; // readonly + x: number; + y: number; + update(): void; + } + + class Button { + constructor(game: Phaser.Game, x: number, y: number, key: string, callback: Function, overFrame: number, outFrame: number, downFrame: number); + input: Phaser.InputHandler; + onInputUp: Phaser.Signal; + onInputDown: Phaser.Signal; + onInputOut: Phaser.Signal; + onInputOver: Phaser.Signal; + events: Phaser.Event[]; + setFrames(overFrame?: number, outFrame?: number, downFrame?: number): void; + onInputOverHandler(pointer: Phaser.Pointer): void; + onInputUpHandler(pointer: Phaser.Pointer): void; + onInputDownHandler(pointer: Phaser.Pointer): void; + onInputOutHandler(pointer: Phaser.Pointer): void; + } + + + // Actually extends PIXI.Graphics but we skip the abstraction here, since pixi is "part" of phaser + // PIXI.Graphics extends PIXI.DisplayObjectContainer extends DisplayObject + class Graphics extends Phaser.Sprite { + constructor(game: Phaser.Game, x: number, y: number); + angle: number; + x:number; + y:number; + + // Pixi drawing + lineStyle(lineWidth:number, color?:number, alpha?:number): void; + moveTo(x:number, y:number): void; + lineTo(x:number, y:number): void; + beginFill(color:number, alpha?:number): void; + endFill(): void; + drawRect( x:number, y:number, width:number, height:number ): void; + drawCircle( x:number, y:number, radius:number): void; + drawElipse( x:number, y:number, width:number, height:number): void; + clear(): void; + updateFilterBounds(): void; + } + + class RenderTexture { + constructor(game: Phaser.Game, key: string, width: number, height: number); + name: string; + type: number; + } + + class Canvas { + create(width: number, height: number): HTMLCanvasElement; + getOffset(element: HTMLElement, point?: Phaser.Point): Phaser.Point; + getAspectRatio(canvas: HTMLCanvasElement): number; + setBackgroundColor(canvas: HTMLCanvasElement, color: string): HTMLCanvasElement; + setTouchAction(canvas: HTMLCanvasElement, value: string): HTMLCanvasElement; + addToDOM(canvas: HTMLCanvasElement, parent: string, overflowHidden: boolean): HTMLCanvasElement; + setTransform(context: CanvasRenderingContext2D, translateX: number, translateY: number, scaleX: number, scaleY: number, skewX: number, skewY: number): CanvasRenderingContext2D; + setSmoothingEnabled(context: CanvasRenderingContext2D, value: boolean): CanvasRenderingContext2D; + setImageRenderingCrisp(canvas: HTMLCanvasElement): HTMLCanvasElement; + setImageRenderingBicubic(canvas: HTMLCanvasElement): HTMLCanvasElement; + } + + class StageScaleMode { + constructor(game: Phaser.Game, width: number, height: number); + static EXACT_FIT: number; + static NO_SCALE: number; + static SHOW_ALL: number; + forceLandscape: boolean; + forcePortrait: boolean; + incorrectOrientation: boolean; + pageAlignHorizontally: boolean; + pageAlignVertically: boolean; + minWidth: number; + maxWidth: number; + minHeight: number; + maxHeight: number; + width: number; + height: number; + maxIterations: number; + game: Phaser.Game; + enterLandscape: Phaser.Signal; + enterPortrait: Phaser.Signal; + orientation: number; + scaleFactor: Phaser.Point; + aspectRatio: number; + isFullScreen: boolean; + isPortrait: boolean; + isLandscape: boolean; + startFullScreen(): void; + stopFullScreen(): void; + checkOrientationState(): void; + checkOrientation(): void; + checkResize(event: any): void; + refresh(): void; + setScreenSize(force: boolean): void; + setSize(): void; + setMaximum(): void; + setShowAll(): void; + setExactFit(): void; + } + + class Device { + patchAndroidClearRect: boolean; + desktop: boolean; + iOS: boolean; + android: boolean; + chromeOS: boolean; + linux: boolean; + macOS: boolean; + windows: boolean; + canvas: boolean; + file: boolean; + fileSystem: boolean; + localStorage: boolean; + webGL: boolean; + worker: boolean; + touch: boolean; + mspointer: boolean; + css3D: boolean; + pointerLock: boolean; + arora: boolean; + chrome: boolean; + epiphany: boolean; + firefox: boolean; + ie: boolean; + ieVersion: number; + mobileSafari: boolean; + midori: boolean; + opera: boolean; + safari: boolean; + webApp: boolean; + audioData: boolean; + webAudio: boolean; + ogg: boolean; + opus: boolean; + mp3: boolean; + wav: boolean; + m4a: boolean; + webm: boolean; + iPhone: boolean; + iPhone4: boolean; + iPad: boolean; + pixelRatio: number; + canPlayAudio(type: string): boolean; + isConsoleOpen(): boolean; + } + + class RequestAnimationFrame { + constructor(game: Phaser.Game); + game: Phaser.Game; + isRunning: boolean; + start(): boolean; + updateRAF(time: number): void; + updateSetTimeout(): void; + stop(): void; + isSetTimeOut(): boolean; + isRAF(): boolean; + } + + class RandomDataGenerator { + constructor(seeds: Array); + c: number; + s0: number; + s1: number; + s2: number; + rnd(): number; + sow(seeds: Array): void; + hash(data: any): number; + integer(): number; + frac(): number; + real(): number; + integerInRange(min: number, max: number): number; + realInRange(min: number, max: number): number; + normal(): number; + uuid(): number; + pick(ary: number[]): number; + weightedPick(ary: number[]): number; + timestamp(a?: number, b?: number): number; + angle(): number; + } + + class Math { + static PI2: number; + static fuzzyEqual(a: number, b: number, epsilon?: number): boolean; + static fuzzyLessThan(a: number, b: number, epsilon?: number): boolean; + static fuzzyGreaterThan(a: number, b: number, epsilon?: number): boolean; + static fuzzyCeil(a: number, b: number, epsilon?: number): boolean; + static fuzzyFloor(a: number, b: number, epsilon?: number): boolean; + static average(...numbers: number[]): number; + static truncate(n: number): number; + static shear(n: number): number; + static snapTo(input: number, gap: number, start?: number): number; + static snapToFloor(input: number, gap: number, start?: number): number; + static snapToCeil(input: number, gap: number, start?: number): number; + static snapToInArray(input: number, arr: number[], sort?: boolean): number; + static roundTo(value: number, place?: number, base?: number): number; + static floorTo(value: number, place?: number, base?: number): number; + static ceilTo(value: number, place?: number, base?: number): number; + static interpolateFloat(a: number, b: number, weight: number): number; + static angleBetween(x1: number, y1: number, x2: number, y2: number): number; + static normalizeAngle(angle: number, radians?: boolean): number; + static nearestAngleBetween(a1: number, a2: number, radians?: boolean): number; + static interpolateAngles(a1: number, a2: number, weight: number, radians?: boolean, ease?: any): number; + static chanceRoll(chance?: number): boolean; + static numberArray(min: number, max: number): number[]; + static maxAdd(value: number, amount: number, max: number): number; + static minSub(value: number, amount: number, min: number): number; + static wrap(value: number, min: number, max: number): number; + static wrapValue(value: number, amount: number, max: number): number; + static randomSign(): number; + static isOdd(n: number): boolean; + static isEven(n: number): boolean; + static max(...numbers: number[]): number; + static min(...numbers: number[]): number; + static wrapAngle(angle: number): number; + static angleLimit(angle: number, min: number, max: number): number; + static linearInterpolation(v: number[], k: number): number; + static bezierInterpolation(v: number[], k: number): number; + static catmullRomInterpolation(v: number[], k: number): number; + static linear(p0: number, p1: number, t: number): number; + static bernstein(n: number, i: number): number; + static catmullRom(p0: number, p1: number, p2: number, p3: number, t: number): number; + static difference(a: number, b: number): number; + static getRandom(objects: Object[], startIndex?: number, length?: number): Object; + static floor(value: number): number; + static ceil(value: number): number; + static sinCosGenerator(length: number, sinAmplitude?: number, cosAmplitude?: number, frequency?: number): { sin: number[]; cos: number[]; }; + static shift(stack: Array): any; + static shuffleArray(array: Array): Array; + static distance(x1: number, y1: number, x2: number, y2: number): number; + static distanceRounded(x1: number, y1: number, x2: number, y2: number): number; + static clamp(x: number, a: number, b: number): number; + static clampBottom(x: number, a: number): number; + static mapLinear(x: number, a1: number, a2: number, b1: number, b2: number): number; + static smoothstep(x: number, min: number, max: number): number; + static smootherstep(x: number, min: number, max: number): number; + static sign(x: number): number; + static degToRad(degrees: number): number; + static radToDeg(radians: number): number; + } + + class QuadTree { + constructor(x: number, y: number, width: number, height: number, maxObject?: number, maxLevels?: number, level?: number); + maxObjects: number; + maxLevels: number; + level: number; + bounds: { x: number; y: number; width: number; height: number; - view: Phaser.Rectangle; - screenView: Phaser.Rectangle; - bounds: Phaser.Rectangle; - deadzone: Phaser.Rectangle; - visible: boolean; - atLimit: { x: boolean; y: boolean; }; - target: Phaser.Sprite; - private _edge: number; - static FOLLOW_LOCKON: number; - static FOLLOW_PLATFORMER: number; - static FOLLOW_TOPDOWN: number; - static FOLLOW_TOPDOWN_TIGHT: number; - follow(target: Phaser.Sprite, style?: number): void; - focusOnXY(x: number, y: number): void; - update(): void; - checkWorldBounds(): void; - setPosition(x: number, y: number): void; - setSize(width: number, height: number): void; - } + subWidth: number; + subHeight: number; + right: number; + bottom: number; + }; + objects: Array; + nodes: Array; + populate(group:Phaser.Group): void; + populateHandler(sprite:Phaser.Sprite): void; + split(): void; + insert(body: Object): void; + getIndex(rect: Object): number; + retrieve(sprite: Object): Array; + clear(): void; + } - class State { - game: Phaser.Game; - add: Phaser.GameObjectFactory; - camera: Phaser.Camera; - cache: Phaser.Cache; - input: Phaser.Input; - load: Phaser.Loader; - stage: Phaser.Stage; - math: Phaser.Math; - sound: Phaser.SoundManager; - stage: Phaser.Stage; - time: Phaser.Time; - tweens: Phaser.TweenManager; - world: Phaser.World; - particles: Phaser.Particles; - physics: Phaser.Physics.Arcade; - preload(); - loadUpdate(); - loadRender(); - create(); - update(); - render(); - paused(); - destroy(); - } + class Line { + constructor(x1?: number, y1?: number, x2?: number, y2?: number); + start: Phaser.Point; + end: Phaser.Point; + setTo(x1?: number, y1?: number, x2?: number, y2?: number): Phaser.Line; + fromSprite(startSprite: Phaser.Sprite, endSprite: Phaser.Sprite, useCenter: boolean): Phaser.Line; + intersects(line: Phaser.Line, asSegment?: boolean, result?: Phaser.Point): Phaser.Point; + pointOnLine(x: number, y: number): boolean; + pointOnSegment(x: number, y: number): boolean; + length: number; + angle: number; + slope: number; + perpSlope: number; + static intersectsPoints(a: Phaser.Point, b: Phaser.Point, e: Phaser.Point, f: Phaser.Point, asSegment?: boolean, result?: Phaser.Point): Phaser.Point; + static intersects(a: Phaser.Line, b: Phaser.Line, asSegment?: boolean, result?: Phaser.Point): Phaser.Point; + } - class StateManager { - constructor(game: Phaser.Game, pendingState: Phaser.State); - game: Phaser.Game; - states: Object; - current: Phaser.State; - onInitCallback(): void; - onPreloadCallback(): void; - onCreateCallback(): void; - onUpdateCallback(): void; - onRenderCallback(): void; - onPreRenderCallback(): void; - onLoadUpdateCallback(): void; - onLoadRenderCallback(): void; - onPausedCallback(): void; - onShutDownCallback(): void; - boot(): void; - add(key: string, state: typeof Phaser.State, autoStart?: boolean): void; - remove(key: string): void; - start(key: string, clearWorld?: boolean, clearCache?: boolean): void; - dummy(): void; - checkState(key: string): boolean; - link(key: string): void; - setCurrentState(key: string): void; - loadComplete(): void; - update(): void; - preRender(): void; - render(): void; - destroy(): void; - } + class Circle { + constructor(x?: number, y?: number, diameter?: number); + x: number; + y: number; + diameter: number; + radius: number; + left: number; + right: number; + top: number; + bottom: number; + area: number; + empty: boolean; + circumference(): number; + setTo(x: number, y: number, diameter: number): Circle; + copyFrom(source: any): Circle; + copyTo(dest: Object): Object; + distance(dest: Object, round: boolean): number; + clone(out: Phaser.Circle): Phaser.Circle; + contains(x: number, y: number): Phaser.Circle; + circumferencePoint(angle: number, asDegrees: number, output?: Phaser.Point): Phaser.Point; + offset(dx: number, dy: number): Phaser.Circle; + offsetPoint(point: Phaser.Point): Phaser.Circle; + toString(): string; + static contains(a: Phaser.Circle, x: number, y: number): boolean; + static equals(a: Phaser.Circle, b: Phaser.Circle): boolean; + static intersects(a: Phaser.Circle, b: Phaser.Circle): boolean; + static circumferencePoint(a: Phaser.Circle, angle: number, asDegrees: boolean, output?: Phaser.Point): Phaser.Point; + static intersectsRectangle(c: Phaser.Circle, r: Phaser.Rectangle): boolean; + } - class LinkedListItem { - next: LinkedListItem; - prev: LinkedListItem; - first: LinkedListItem; - last: LinkedListItem; - } + class Point { + constructor(x: number, y: number); + x: number; + y: number; + copyFrom(source: any): Phaser.Point; + invert(): Phaser.Point; + setTo(x: number, y: number): Phaser.Point; + add(x: number, y: number): Phaser.Point; + subtract(x: number, y: number): Phaser.Point; + multiply(x: number, y: number): Phaser.Point; + divide(x: number, y: number): Phaser.Point; + clampX(min: number, max: number): Phaser.Point; + clampY(min: number, max: number): Phaser.Point; + clamp(min: number, max: number): Phaser.Point; + clone(output: Phaser.Point): Phaser.Point; + copyTo(dest: any): Object; + distance(dest: Object, round?: boolean): number; + equals(a: Phaser.Point): boolean; + rotate(x: number, y: number, angle: number, asDegrees: boolean, distance: number): Phaser.Point; + toString(): string; + static add(a: Phaser.Point, b: Phaser.Point, out?: Phaser.Point): Phaser.Point; + static subtract(a: Phaser.Point, b: Phaser.Point, out?: Phaser.Point): Phaser.Point; + static multiply(a: Phaser.Point, b: Phaser.Point, out?: Phaser.Point): Phaser.Point; + static divide(a: Phaser.Point, b: Phaser.Point, out?: Phaser.Point): Phaser.Point; + static equals(a: Phaser.Point, b: Phaser.Point): boolean; + static distance(a: Phaser.Point, b: Phaser.Point, round?: boolean): number; + static rotate(a: Phaser.Point, x: number, y: number, angle: number, asDegrees: boolean, distance: boolean): Phaser.Point; + } - class LinkedList extends LinkedListItem { - total: number; - add(child: LinkedListItem): LinkedListItem; - remove(child: LinkedListItem): void; - callAll(callback: string): void; - dump(): void; - } + class Rectangle { + constructor(x: number, y: number, width: number, height: number); + x: number; + y: number; + width: number; + height: number; + halfWidth: number; + halfHeight: number; + bottom: number; + bottomRight: Phaser.Point; + left: number; + right: number; + volume: number; + perimeter: number; + centerX: number; + centerY: number; + top: number; + topLeft: Phaser.Point; + empty: boolean; + offset(dx: number, dy: number): Phaser.Rectangle; + offsetPoint(point: Phaser.Point): Phaser.Rectangle; + setTo(x: number, y: number, width: number, height: number): Phaser.Rectangle; + floor(): void; + copyFrom(source: any): Phaser.Rectangle; + copyTo(dest: any): Object; + inflate(dx: number, dy: number): Phaser.Rectangle; + size(output: Phaser.Point): Phaser.Point; + clone(output: Phaser.Rectangle): Phaser.Rectangle; + contains(x: number, y: number): boolean; + containsRect(b: Phaser.Rectangle): boolean; + equals(b: Phaser.Rectangle): boolean; + intersection(b: Phaser.Rectangle, out: Phaser.Rectangle): Phaser.Rectangle; + intersects(b: Phaser.Rectangle, tolerance: number): boolean; + intersectsRaw(left: number, right: number, top: number, bottom: number, tolerance: number): boolean; + union(b: Phaser.Rectangle, out: Phaser.Rectangle): Phaser.Rectangle; + toString(): string; + static inflate(a: Phaser.Rectangle, dx: number, dy: number): Phaser.Rectangle; + static inflatePoint(a: Phaser.Rectangle, point: Phaser.Point): Phaser.Rectangle; + static size(a: Phaser.Rectangle, output: Phaser.Point): Phaser.Point; + static clone(a: Phaser.Rectangle, output: Phaser.Rectangle): Phaser.Rectangle; + static contains(a: Phaser.Rectangle, x: number, y: number): boolean; + static containsPoint(a: Phaser.Rectangle, point: Phaser.Point): boolean; + static containsRect(a: Phaser.Rectangle, b: Phaser.Rectangle): boolean; + static equals(a: Phaser.Rectangle, b: Phaser.Rectangle): boolean; + static intersection(a: Phaser.Rectangle, b: Phaser.Rectangle, out: Phaser.Rectangle): Phaser.Rectangle; + static intersects(a: Phaser.Rectangle, b: Phaser.Rectangle, tolerance: number): boolean; + static intersectsRaw(a: Phaser.Rectangle, left: number, right: number, top: number, bottom: number, tolerance: number): boolean; + static union(a: Phaser.Rectangle, b: Phaser.Rectangle, out: Phaser.Rectangle): Phaser.Rectangle; + } - class Signal { - memorize: boolean; - active: boolean; - validateListener(listener: Function, fnName: string): void; - has(listener: Function, context?: any): boolean; - add(listener: Function, listenerContext?: any, priority?: number): Phaser.SignalBinding; - addOnce(listener: Function, listenerContext?: any, priority?: number): Phaser.SignalBinding; - remove(listener: Function, context?: any): Function; - removeAll(): void; - getNumListeners(): number; - halt(): void; - dispatch(...params: any[]): void; - forget(): void; - dispose(): void; - toString(): string; - } + class Net { + constructor(game: Phaser.Game); + game: Phaser.Game; + getHostName(): string; + checkDomainName(domain: string): string; + updateQueryString(key: string, value: any, redirect?: boolean, url?: string): string; + getQueryString(parameter?: string): string; + decodeURI(value: string): string; + } - class SignalBinding { - constructor(signal: Phaser.Signal, listener: Function, isOnce: boolean, listenerContext: Object, priority?: number); - context: Object; - active: boolean; - params: Array; - execute(paramsArr?: Array): void; - detach(): Function; - isBound(): boolean; - isOnce(): boolean; - getListener(): Function; - getSignal(): Phaser.Signal; - toString(): string; - } + class TweenManager { + constructor(game: Phaser.Game); + game: Phaser.Game; + getAll(): Phaser.Tween[]; + removeAll(): void; + add(tween: Phaser.Tween): Phaser.Tween; + create(object: Object): Phaser.Tween; + remove(tween: Phaser.Tween): void; + update(): boolean; + pauseAll(): void; + resumeAll(): void; + } - class StateCycle { - preUpdate(): void; - update(): void; - render(): void; - postRender(): void; - destroy(): void; - } + class Tween { + constructor(object: Object, game: Phaser.Game); + game: Phaser.Game; + pending: boolean; + pendingDelete: boolean; + onStart: Phaser.Signal; + onComplete: Phaser.Signal; + isRunning: boolean; + to(properties: Object, duration?: number, ease?: any, autoStart?: boolean, delay?: number, loop?: boolean): Phaser.Tween; + start(time: number): Phaser.Tween; + stop(): Phaser.Tween; + delay(amount: number): Phaser.Tween; + repeat(times: number): Phaser.Tween; + yoyo(yoyo: boolean): Phaser.Tween; + easing(easing: any): Phaser.Tween; + interpolation(interpolation: Function): Phaser.Tween; + chain(...tweens: Phaser.Tween[]): Phaser.Tween; + loop(): Phaser.Tween; + onStartCallback(callback: Function): Phaser.Tween; + onUpdateCallback(callback: Function): Phaser.Tween; + onCompleteCallback(callback: Function): Phaser.Tween; + pause(): void; + resume(): void; + update(time: number): boolean; + } - class Plugin extends StateCycle { - constructor(game: Phaser.Game, parent: any); - game: Phaser.Game; - parent: any; - active: boolean; - visible: boolean; - hasPreUpdate: boolean; - hasUpdate: boolean; - hasRender: boolean; - hasPostRender: boolean; - } + module Easing { - class PluginManager extends StateCycle { - constructor(game: Phaser.Game, parent: any); - game: Phaser.Game; - private _parent: any; - plugins: Phaser.Plugin[]; - add(plugin: Phaser.Plugin): Phaser.Plugin; - remove(plugin: Phaser.Plugin): void; - } + class Linear { + static None(k: number): number; + } - class Stage { - constructor(game: Phaser.Game, width: number, height: number); - game: Phaser.Game; - offset: Phaser.Point; - canvas: HTMLCanvasElement; - scaleMode: number; - scale: Phaser.StageScaleMode; - aspectRatio: number; - backgroundColor: string; - disableVisibilityChange: boolean; - boot(): void; - visibilityChange(event: Event): void; - } + class Quadratic { + static In(k: number): number; + static Out(k: number): number; + static InOut(k: number): number; + } - class Group { - constructor(game: Phaser.Game, parent: any, name: string, useStage: boolean); - game: Phaser.Game; - name: string; - type: number; - exists: boolean; - sortIndex: string; - length: number; - x: number; - y: number; - angle: number; - rotation: number; - visible: boolean; - add(child: any): any; - addAt(child: any, index: number): any; - getAt(index: number): any; - create(x: number, y: number, key: string, frame: string, exists?: boolean): any; - swap(child1: any, child2: any): boolean; - bringToTop(child: any): any; - getIndex(child: any): number; - replace(oldChild: any, newChild: any): void; - setProperty(child: any, key: string[], value: string, operation: number): void; - setAll(key: string, value: number, checkAlive: boolean, checkVisible: boolean, operation: number): void; - subAll(key: string, value: number, checkAlive: boolean, checkVisible: boolean, operation: number): void; - multiplyAll(key: string, value: number, checkAlive: boolean, checkVisible: boolean, operation: number): void; - divideAll(key: string, value: number, checkAlive: boolean, checkVisible: boolean, operation: number): void; - callAllExists(callback: Function, callbackContext: Object, existsValue: boolean): void; - callAll(callback: string, callbackContext?: Object): void; - forEach(callback: Function, callbackContext: Object, checkExists: boolean): void; - forEachAlive(callback: Function, callbackContext: Object): void; - forEachDead(callback: Function, callbackContext: Object): void; - getFirstExists(state: boolean): any; - getFirstAlive(): any; - getFirstDead(): any; - countLiving(): number; - countDead(): number; - getRandom(startIndex: number, length: number): any; - remove(child: any): void; - removeAll(): void; - removeBetween(startIndex: number, endIndex: number): void; - destroy(): void; - dump(full: boolean): void; - } + class Cubic { + static In(k: number): number; + static Out(k: number): number; + static InOut(k: number): number; + } - class World { + class Quartic { + static In(k: number): number; + static Out(k: number): number; + static InOut(k: number): number; + } + + class Quintic { + static In(k: number): number; + static Out(k: number): number; + static InOut(k: number): number; + } + + class Sinusoidal { + static In(k: number): number; + static Out(k: number): number; + static InOut(k: number): number; + } + + class Exponential { + static In(k: number): number; + static Out(k: number): number; + static InOut(k: number): number; + } + + class Circular { + static In(k: number): number; + static Out(k: number): number; + static InOut(k: number): number; + } + + class Elastic { + static In(k: number): number; + static Out(k: number): number; + static InOut(k: number): number; + } + + class Back { + static In(k: number): number; + static Out(k: number): number; + static InOut(k: number): number; + } + + class Bounce { + static In(k: number): number; + static Out(k: number): number; + static InOut(k: number): number; + } + + } + + class Time { + constructor(game: Phaser.Game); + game: Phaser.Game; + physicsElapsed: number; + time: number; + pausedTime: number; + now: number; + elapsed: number; + fps: number; + fpsMin: number; + fpsMax: number; + msMin: number; + msMax: number; + frames: number; + pauseDuration: number; + timeToCall: number; + lastTime: number; + events: Phaser.Timer; + create(autoDestroy: boolean): Phaser.Timer; + removeAll(): void; + update(time: number): void; + gamePaused(): void; + gameResumed(): void; + totalElapsedSeconds(): number; + elapsedSince(since: number): number; + elapsedSecondsSince(since: number): number; + reset(): void; + } + + class Timer { + constructor(game: Phaser.Game, autoDestroy: boolean); + game: Phaser.Game; + running: boolean; + autoDestroy: boolean; + expired: boolean; + events: Phaser.TimerEvent[]; + onComplete: Phaser.Signal; + nextTick: number; + paused: boolean; + static MINUTE: number; + static SECOND: number; + static HALF: number; + static QUARTER: number; + add(delay: number, callback: any, callbackContext: any, ...args: any[]): Phaser.TimerEvent; + repeat(delay: number, repeatCount: number, callback: any, callbackContext: any, ...args: any[]): Phaser.TimerEvent; + loop(delay: number, callback: any, callbackContext: any, ...args: any[]): Phaser.TimerEvent; + start(): void; + stop(): void; + remove(event: Phaser.TimerEvent): boolean; + order():void; + sortHandler():number; + update(time: number): boolean; + pause(): void; + resume(): void; + destroy(): void; + next: number; + duration: number; + length: number; + ms: number; + seconds: number; + } + + class TimerEvent { + constructor(timer: Phaser.Timer, delay: number, tick: number, repeatCount: number, loop: boolean, callback: any, callbackContext, any, args:any[]); + timer: Phaser.Timer; + delay: number; + tick: number; + repeatCount: number; + loop: boolean; + callback: any; + callbackContext: any; + args: any[]; + } + + class AnimationManager { + constructor(sprite); + sprite: Phaser.Sprite; + game: Phaser.Game; + currentFrame: Phaser.Frame; + updateIfVisible: boolean; + frameData: Phaser.FrameData; + frameTotal: number; + frame: number; + frameName: string; + loadFrameData(frameData: Phaser.FrameData): void; + add(name: string, frames?: Array, frameRate?: number, loop?: boolean, useNumericIndex?: boolean): Phaser.Animation; + getAnimation(name: string): Phaser.Animation; + validateFrames(frames: Array, useNumericIndex?: boolean): boolean; + play(name: string, frameRate?: number, loop?: boolean): Phaser.Animation; + stop(name?: string, resetFrame?: boolean): void; + update(): boolean; + destroy(): void; + } + + class Animation { + constructor(game: Phaser.Game, parent: Phaser.Sprite, name: string, frameData: Phaser.FrameData, frames: any[], delay: number, looped: boolean); + game: Phaser.Game; + name: string; + delay: number; + looped: boolean; + isFinished: boolean; + isPlaying: boolean; + currentFrame: Phaser.Frame; + frameTotal: number; + frame: number; + play(frameRate?: number, loop?: boolean): Phaser.Animation; + restart(): void; + stop(resetFrame?: boolean): void; + update(): boolean; + destroy(): void; + onComplete(): void; + } + + class Frame { + constructor(index: number, x: number, y: number, width: number, height: number, name: string, uuid: string); + index: number; + x: number; + y: number; + width: number; + height: number; + centerX: number; + centerY: number; + distance: number; + name: string; + uuid: string; + rotated: boolean; + rotationDirection: string; + trimmed: boolean; + sourceSizeW: number; + sourceSizeH: number; + spriteSourceSizeX: number; + spriteSourceSizeY: number; + spriteSourceSizeW: number; + spriteSourcesizeH: number; + setTrim(trimmed: boolean, actualWidth: number, actualHeight: number, destX: number, destY: number, destWidth: number, destHeight: number): void; + } + + class FrameData { + addFrame(frame: Frame): Frame; + getFrame(index: number): Frame; + getFrameByName(name: string): Frame; + checkFrame(name: string): boolean; + getFrameRange(start: number, end: number, output: Array): Array; + getFrames(frames: Array, useNumericIndex?: boolean, output?: Array): Array; + getFrameIndexes(frames: Array, useNumericIndex?: boolean, output?: Array): Array; + total: number; + } + + class AnimationParser { + spriteSheet(game: Phaser.Game, key: string, frameWidth: number, frameHeight: number, frameMax?: number): Phaser.FrameData; + JSONData(game: Phaser.Game, json: Object, cacheKey: string): Phaser.FrameData; + JSONDataHash(game: Phaser.Game, json: Object, cacheKey: string): Phaser.FrameData; + XMLData(game: Phaser.Game, xml: Object, cacheKey: string): Phaser.FrameData; + } + + class Cache { + constructor(game: Phaser.Game); + game: Phaser.Game; + onSoundUnlock: Phaser.Signal; + addCanvas(key: string, canvas: HTMLCanvasElement, context: CanvasRenderingContext2D): void; + addRenderTexture(key: string, texture: RenderTexture): void; + addSpriteSheet(key: string, url: string, data: Object, frameWidth: number, frameHeight: number, frameMax: number): void; + addTilemap(key: string, url: string, data: Object, mapData: Object, atlasData: Object): void; + addTextureAtlas(key: string, url: string, data: Object, atlasData: Object): void; + addBitmapFont(key: string, url: string, data: Object, xmlData: Object): void; + addDefaultImage(): void; + addImage(key: string, url: string, data: Object): void; + addSound(key: string, url: string, data: Object): void; + reloadSound(key: string): void; + reloadSoundComplete(key: string): void; + updateSound(key: string, property: string, value: Phaser.Sound): void; + decodedSound(key: string, data: Object): void; + addText(key: string, url: string, data: Object): void; + getCanvas(key: string): Object; + checkImageKey(key: string): boolean; + getImage(key: string): Object; + getTilemap(key: string): Phaser.Tilemap; + getFrameData(key: string): Phaser.FrameData; + getFrameByIndex(key: string, frame: string): Phaser.Frame; + getFrameByName(key: string, frame: string): Phaser.Frame; + getFrame(key: string): Phaser.Frame; + getTextureFrame(key: string): Phaser.Frame; + getTexture(key: string): Phaser.RenderTexture; + getSound(key: string): Phaser.Sound; + getSoundData(key: string): Object; + isSoundDecoded(key: string): boolean; + isSoundReady(key: string): boolean; + isSpriteSheet(key: string): boolean; + getText(key: string): Object; + getKeys(array: Array): Array; + getImageKeys(): string[]; + getSoundKeys(): string[]; + getTextKeys(): string[]; + removeCanvas(key: string): void; + removeImage(key: string): void; + removeSound(key: string): void; + removeText(key: string): void; + destroy(): void; + } + + class Loader { + static TEXTURE_ATLAS_JSON_ARRAY: number; + static TEXTURE_ATLAS_JSON_HASH: number; + static TEXTURE_ATLAS_XML_STARLING: number; + constructor(game: Phaser.Game); + game: Phaser.Game; + queueSize: number; + isLoading: boolean; + hasLoaded: boolean; + progress: number; + preloadSprite: Phaser.Sprite; + crossOrigin: string; + baseURL: string; + onFileComplete: Phaser.Signal; + onFileError: Phaser.Signal; + onLoadStart: Phaser.Signal; + onLoadComplete: Phaser.Signal; + setPreloadSprite(sprite: Phaser.Sprite, direction?: number): void; + checkKeyExists(type: string, key: string): boolean; + reset(): void; + addToFileList(type: string, key: string, url: string, properties: Array): void; + image(key: string, url: string, overwrite?: boolean): void; + text(key: string, url: string, overwrite?: boolean): void; + spritesheet(key: string, url: string, frameWidth: number, frameHeight: number, frameMax: number): void; + audio(key: string, urls: any, autoDecode?: boolean): void; + tilemap(key: string, tilesetURL: string, mapDataURL?: string, mapData?: Object, format?: string): void; + tileset(key: string, url: string, tileWidth: number, tileHeight: number, tileMargin?: number, tileSpacing?: number, rows?: number, columns?: number, limit?: number): void; + bitmapFont(key: string, textureURL: string, xmlURL?: string, xmlData?: Object): void; + atlasJSONArray(key: string, textureURL: string, atlasURL: string, atlasData: Object): void; + atlasJSONHash(key: string, textureURL: string, atlasURL: string, atlasData: Object): void; + atlasXML(key: string, textureURL: string, atlasURL: string, atlasData: Object): void; + atlas(key: string, textureURL: string, atlasURL?: string, atlasData?: Object, format?: number): void; + removeFile(key: string): void; + removeAll(): void; + start(): void; + loadFile(): void; + getAudioURL(urls: string[]): string; + fileError(key: string): void; + fileComplete(key: string): void; + jsonLoadComplete(key: string): void; + csvLoadComplete(key: string): void; + dataLoadError(key: string): void; + xmlLoadComplete(key: string): void; + nextFile(previousKey: string, success: boolean): void; + } + + class LoaderParser { + bitmapFont(game: Phaser.Game, xml: Object, cacheKey: Phaser.FrameData): void; + } + + class Sound { + constructor(game: Phaser.Game, key: string, volume?: number, loop?: boolean); + game: Phaser.Game; + name: string; + key: string; + loop: boolean; + markers: Object; + context: any; + autoplay: boolean; + totalDuration: number; + startTime: number; + currentTime: number; + duration: number; + stopTime: number; + paused: boolean; + isPlaying: boolean; + currentMarker: string; + pendingPlayback: boolean; + override: boolean; + usingWebAudio: boolean; + usingAudioTag: boolean; + onDecoded: Phaser.Signal; + onPlay: Phaser.Signal; + onPause: Phaser.Signal; + onResume: Phaser.Signal; + onLoop: Phaser.Signal; + onStop: Phaser.Signal; + onMute: Phaser.Signal; + isDecoded: boolean; + isDecoding: boolean; + mute: boolean; + volume: number; + onMarkerComplete: Phaser.Signal; + soundHasUnlocked(key: string): void; + addMarker(name: string, start: number, stop: number, volume?: number, loop?: boolean): void; + removeMarker(name: string): void; + update(): void; + play(marker?: string, position?: number, volume?: number, loop?: boolean): Phaser.Sound; + restart(marker: string, position: number, volume?: number, loop?: boolean): void; + pause(): void; + resume(): void; + stop(): void; + } + + class SoundManager { + constructor(game: Phaser.Game); + game: Phaser.Game; + onSoundDecode: Phaser.Signal; + context: any; + usingWebAudio: boolean; + usingAudioTag: boolean; + noAudio: boolean; + touchLocked: boolean; + channels: number; + mute: boolean; + volume: number; + boot(): void; + unlock(): void; + stopAll(): void; + pauseAll(): void; + resumeAll(): void; + decode(key: string, sound?: Phaser.Sound): void; + update(): void; + add(key: string, volume: number, loop: boolean): Phaser.Sound; + } + + module Utils { + class Debug { constructor(game: Phaser.Game); game: Phaser.Game; - bounds: Phaser.Rectangle; - camera: Phaser.Camera; - currentRenderOrderID: number; - group: Phaser.Group; - width: number; - height: number; - centerX: number; - centerY: number; - randomX: number; - randomY: number; - boot(): void; - update(): void; - setSize(width: number, height: number): void; - destroy(): void; - } - - class Game { - constructor(width: number, height: number, renderer: number, parent: string, state: Object, transparent: boolean, antialias: boolean); - id: number; - width: number; - height: number; - renderer: number; - transparent: boolean; - antialias: boolean; - parent: string; - state: Phaser.StateManager; - renderType: number; - isBooted: boolean; - raf: Phaser.RequestAnimationFrame; - add: Phaser.GameObjectFactory; - cache: Phaser.Cache; - input: Phaser.Input; - load: Phaser.Loader; - math: Phaser.Math; - sound: Phaser.SoundManager; - stage: Phaser.Stage; - time: Phaser.Time; - tweens: Phaser.TweenManager; - world: Phaser.World; - physics: Phaser.Physics.Arcade; - rnd: Phaser.RandomDataGenerator; - device: Phaser.Device; - camera: Phaser.Camera; - canvas: HTMLCanvasElement; - context: Object; - debug: Phaser.Utils.Debug; - particles: Phaser.Particles; - _paused: boolean; - paused: boolean; - boot(): void; - setUpRenderer(): void; - loadComplete(): void; - update(): void; - destroy(): void; - } - - class Input { - constructor(game: Phaser.Game); - static MOUSE_OVERRIDES_TOUCH: number; - static TOUCH_OVERRIDES_MOUSE: number; - static MOUSE_TOUCH_COMBINE: number; - id: number; - active: boolean; - game: Phaser.Game; - hitCanvas: any; - hitContext: any; - pollRate: number; - disabled: boolean; - multiInputOverride: number; - position: Phaser.Point; - speed: Phaser.Point; - circle: Phaser.Circle; - scale: Phaser.Point; - maxPointers: number; - currentPointers: number; - tapRate: number; - doubleTapRate: number; - holdRate: number; - justPressedRate: number; - justReleasedRate: number; - recordPointerHistory: boolean; - recordRate: number; - recordLimit: number; - x: number; - y: number; - totalInactivePointers: number; - totalActivePointers: number; - worldX: number; - worldY: number; - pollLocked: boolean; - pointer1: Phaser.Pointer; - pointer2: Phaser.Pointer; - pointer3: Phaser.Pointer; - pointer4: Phaser.Pointer; - pointer5: Phaser.Pointer; - pointer6: Phaser.Pointer; - pointer7: Phaser.Pointer; - pointer8: Phaser.Pointer; - pointer9: Phaser.Pointer; - pointer10: Phaser.Pointer; - activePointer: Phaser.Pointer; - mousePointer: Phaser.Pointer; - mouse: Phaser.Mouse; - keyboard: Phaser.Keyboard; - touch: Phaser.Touch; - mspointer: Phaser.MSPointer; - interactiveItems: Phaser.LinkedList; - onDown: Phaser.Signal; - onUp: Phaser.Signal; - onTap: Phaser.Signal; - onHold: Phaser.Signal; - boot(): void; - update(): void; - reset(hard?: boolean); - resetSpeed(x: number, y: number); - startPointer(event: Event): Phaser.Pointer; - updatePointer(event: Event): Phaser.Pointer; - stopPointer(event: Event): Phaser.Pointer; - getPointer(state: boolean): Phaser.Pointer; - getPointerFromIdentifier(identifier: number): Phaser.Pointer; - addPointer(): Phaser.Pointer; - } - - class Keyboard { - constructor(game: Phaser.Game); - game: Phaser.Game; - disabled: boolean; - static A: number; - static B: number; - static C: number; - static D: number; - static E: number; - static F: number; - static G: number; - static H: number; - static I: number; - static J: number; - static K: number; - static L: number; - static M: number; - static N: number; - static O: number; - static P: number; - static Q: number; - static R: number; - static S: number; - static T: number; - static U: number; - static V: number; - static W: number; - static X: number; - static Y: number; - static Z: number; - static ZERO: number; - static ONE: number; - static TWO: number; - static THREE: number; - static FOUR: number; - static FIVE: number; - static SIX: number; - static SEVEN: number; - static EIGHT: number; - static NINE: number; - static NUMPAD_0: number; - static NUMPAD_1: number; - static NUMPAD_2: number; - static NUMPAD_3: number; - static NUMPAD_4: number; - static NUMPAD_5: number; - static NUMPAD_6: number; - static NUMPAD_7: number; - static NUMPAD_8: number; - static NUMPAD_9: number; - static NUMPAD_MULTIPLY: number; - static NUMPAD_ADD: number; - static NUMPAD_ENTER: number; - static NUMPAD_SUBTRACT: number; - static NUMPAD_DECIMAL: number; - static NUMPAD_DIVIDE: number; - static F1: number; - static F2: number; - static F3: number; - static F4: number; - static F5: number; - static F6: number; - static F7: number; - static F8: number; - static F9: number; - static F10: number; - static F11: number; - static F12: number; - static F13: number; - static F14: number; - static F15: number; - static COLON: number; - static EQUALS: number; - static UNDERSCORE: number; - static QUESTION_MARK: number; - static TILDE: number; - static OPEN_BRACKET: number; - static BACKWARD_SLASH: number; - static CLOSED_BRACKET: number; - static QUOTES: number; - static BACKSPACE: number; - static TAB: number; - static CLEAR: number; - static ENTER: number; - static SHIFT: number; - static CONTROL: number; - static ALT: number; - static CAPS_LOCK: number; - static ESC: number; - static SPACEBAR: number; - static PAGE_UP: number; - static PAGE_DOWN: number; - static END: number; - static HOME: number; - static LEFT: number; - static UP: number; - static RIGHT: number; - static DOWN: number; - static INSERT: number; - static DELETE: number; - static HELP: number; - static NUM_LOCK: number; - start(): void; + font: string; + lineHeight: number; + renderShadow: boolean; + currentX: number; + currentY: number; + currentAlpha: number; + start(x?: number, y?: number, color?: string): void; stop(): void; - addKeyCapture(keycode: any): void; - removeKeyCapture(keycode: number): void; - clearCaptures(): void; - onKeyDown(event: any): void; - onKeyUp(event: any): void; - reset(): void; - justPressed(keycode: number, duration?: number): boolean; - justReleased(keycode: number, duration?: number): boolean; - isDown(keycode: number): boolean; - } + line(text: string, x: number, y: number): void; + renderQuadTree(quadtree: Phaser.QuadTree, color?: string): void; + renderSpriteCorners(sprite: Phaser.Sprite, showText?: boolean, showBounds?: boolean, color?: string): void; + renderSoundInfo(sound: Phaser.Sound, x: number, y: number, color?: string): void; + renderCameraInfo(camera: Phaser.Camera, x: number, y: number, color?: string): void; + renderPointer(pointer: Phaser.Pointer, hideIfUp?: boolean, downColor?: string, upColor?: string, color?: string): void; + renderSpriteInputInfo(sprite: Phaser.Sprite, x: number, y: number, color?: string): void; + renderSpriteCollision(sprite: Phaser.Sprite, x: number, y: number, color?: string): void; + renderInputInfo(x: number, y: number, color?: string): void; + renderSpriteInfo(sprite: Phaser.Sprite, x: number, y: number, color?: string): void; + renderWorldTransformInfo(sprite: Phaser.Sprite, x: number, y: number, color?: string): void; + renderLocalTransformInfo(sprite: Phaser.Sprite, x: number, y: number, color?: string): void; + renderPointInfo(point: Phaser.Point, x: number, y: number, color?: string): void; + renderSpriteBody(sprite: Phaser.Sprite, color?: string): void; + renderSpriteBounds(sprite: Phaser.Sprite, color?: string, fill?: boolean): void; + renderPixel(x: number, y: number, fillStyle?: string): void; + renderPoint(point: Phaser.Point, fillStyle?: string): void; + renderRectangle(rect: Phaser.Rectangle, fillStyle?: string): void; + renderCircle(circle: Phaser.Circle, fillStyle?: string): void; + renderText(text: string, x: number, y: number, color?: string, font?: string): void; + } + } - class Mouse { + class Color { + getColor32(alpha: number, red: number, green: number, blue: number): number; + getColor(red: number, green: number, blue: number): number; + hexToRGB(h: string): number; + getColorInfo(color: number): string; + RGBtoHexstring(color: number): string; + RGBtoWebstring(color: number): string; + colorToHexstring(color: number): string; + interpolateColor(color1: number, color2: number, steps: number, currentStep: number, alpha: number): number; + interpolateColorWithRGB(color: number, r: number, g: number, b: number, steps: number, currentStep: number): number; + interpolateRGB(r1: number, g1: number, b1: number, r2: number, g2: number, b2: number, steps: number, currentStep: number): number; + getRandomColor(min?: number, max?: number, alpha?: number): number; + getRGB(color: number): Object; + getWebRGB(color: number): string; + getAlpha(color: number): number; + getAlphaFloat(color: number): number; + getRed(color: number): number; + getGreen(color: number): number; + getBlue(color: number): number; + } + + module Physics { + class Arcade { constructor(game: Phaser.Game) game: Phaser.Game; - callbackContext: Object; - disabled: boolean; - locked: boolean; - static LEFT_BUTTON: number; - static MIDDLE_BUTTON: number; - static RIGHT_BUTTON: number; - mouseDownCallback(): void; - mouseMoveCallback(): void; - mouseUpCallback(): void; - start(): void; - onMouseDown(): void; - onMouseUp(): void; - onMouseMove(): void; - requestPointerLock(): void; - pointerLockChange(): void; - releasePointerLock(): void; - stop(); - } - - class MSPointer { - constructor(game: Phaser.Game); - game: Phaser.Game; - callbackContext: Object; - disabled: boolean; - mouseDownCallback(): void; - mouseMoveCallback(): void; - mouseUpCallback(): void; - start(): void; - onPointerDown(): void; - onPointerUp(): void; - onPointerMove(): void; - stop(): void; - } - - class Pointer { - constructor(game: Phaser.Game, id: number); - game: Phaser.Game; - id: number; - active: boolean; - positionDown: Phaser.Point; - position: Phaser.Point; - circle: Phaser.Circle; - withinGame: boolean; - clientX: number; - clientY: number; - pageX: number; - pageY: number; - screenX: number; - screenY: number; - duation: number; - worldX: number; - worldY: number; - x: number; - y: number; - isMouse: boolean; - isDown: boolean; - isUp: boolean; - timeDown: number; - timeUp: number; - previousTapTime: number; - totalTouches: number; - msSinceLastClick: number; - targetObject: any; - start(event: any): Phaser.Pointer; - update(): void; - move(event: any): void; - leave(event: any): void; - stop(event: any): void; - justPressed(duration?: number): boolean; - justReleased(duration?: number): boolean; - reset(): void; - toString(): string; - } - - class Touch { - constructor(game: Phaser.Game); - game: Phaser.Game; - callbackContext: any; - touchStartCallback: Function; - touchMoveCallback: Function; - touchEndCallback: Function; - touchEnterCallback: Function; - touchLeaveCallback: Function; - touchCancelCallback: Function; - preventDefault: boolean; - disabled: boolean; - start(): void; - consumeDocumentTouches(): void; - onTouchStart(event: any): void; - onTouchCancel(event: any): void; - onTouchEnter(event: any): void; - onTouchLeave(event: any): void; - onTouchMove(event: any): void; - onTouchEnd(event: any): void; - stop(): void; - } - - class InputHandler extends LinkedListItem { - constructor(sprite: Phaser.Sprite); - game: Phaser.Game; - sprite: Phaser.Sprite; - enabled: boolean; - priorityID: number; - useHandCursor: boolean; - isDragged: boolean; - allowHorizontalDrag: boolean; - allowVerticalDrag: boolean; - bringToTop: boolean; - snapOffset: number; - snapOnDrag: boolean; - snapOnRelease: boolean; - snapX: number; - snapY: number; - pixelPerfect: boolean; - pixelPerfectAlpha: number; - draggable: boolean; - boundsSprite: Phaser.Sprite; - consumePointerEvent: boolean; - start(priority: number, useHandCursor: boolean): void; - reset(): void; - stop(): void; - destroy(): void; - pointerX(pointer: number): number; - pointerY(pointer: number): number; - pointerDown(pointer: number): boolean; - pointerUp(pointer: number): boolean; - pointerTimeDown(pointer: number): number; - pointerTimeUp(pointer: number): number; - pointerOver(pointer: number): boolean; - pointerOut(pointer: number): boolean; - pointerTimeOver(pointer: number): number; - pointerTimeOut(pointer: number): number; - pointerDragged(pointer: number): boolean; - checkPointerOver(pointer: number): boolean; - checkPixel(x: number, y: number): boolean; - update(pointer: number): void; - updateDrag(pointer: number): boolean; - justOver(pointer: number, delay: number): boolean; - justOut(pointer: number, delay: number): boolean; - justPressed(pointer: number, delay: number): boolean; - justReleased(pointer: number, delay: number): boolean; - overDuration(pointer: number): number; - downDuration(pointer: number): number; - enableDrag(lockCenter: boolean, bringToTop: boolean, pixelPerfect: boolean, alphaThreshold?: number, boundsRect?: Phaser.Rectangle, boundsSprite?: Phaser.Rectangle): void; - disableDrag(): void; - startDrag(): void; - stopDrag(): void; - setDragLock(allowHorizontal: boolean, allowVertical: boolean): void; - enableSnap(snapX: number, snapY: number, onDrag?: boolean, onRelease?: boolean): void; - disableSnap(): void; - checkBoundsRect(): void; - checkBoundsSprite(): void; - } - - class Event { - constructor(sprite: Phaser.Sprite); - parent: Phaser.Sprite; - onAddedToGroup: Phaser.Signal; - onRemovedFromGroup: Phaser.Signal; - onKilled: Phaser.Signal; - onRevived: Phaser.Signal; - onOutOfBounds: Phaser.Signal; - onInputOver: Phaser.Signal; - onInputOut: Phaser.Signal; - onInputDown: Phaser.Signal; - onInputUp: Phaser.Signal; - onDragStart: Phaser.Signal; - onDragStop: Phaser.Signal; - onAnimationStart: Phaser.Signal; - onAnimationComplete: Phaser.Signal; - onAnimationLoop: Phaser.Signal; - } - - class GameObjectFactory { - constructor(game: Phaser.Game); - game: Phaser.Game; - world: Phaser.World; - existing(object: any): boolean; - sprite(x: number, y: number, key?: string, frame?: any): Phaser.Sprite; - child(parent: any, x: number, y: number, key?: string, frame?: number): Phaser.Sprite; - tween(obj: Object): Phaser.Tween; - group(parent?: any, name?: string): Phaser.Group; - audio(key: string, volume?: number, loop?: boolean): Phaser.Sound; - tileSprite(x: number, y: number, width: number, height: number, key?: string, frame?: number): Phaser.TileSprite; - text(x: number, y: number, text: string, style: any): Phaser.Text; - button(x: number, y: number, key: string, callback: Function, callbackContext: Object, overFrame?: any, outFrame?: any, downFrame?: any): Phaser.Button; - graphics(x: number, y: number): Phaser.Graphics; - emitter(x: number, y: number, maxParticles: number): Phaser.Particles.Arcade.Emitter; - bitmapText(x: number, y: number, text: string, style: string): Phaser.BitmapText; - tilemap(x: number, y: number, key: string, resizeWorld: boolean, tileWidth: number, tileHeight: number): Phaser.Tilemap; - renderTexture(key: string, width: number, height: number): Phaser.RenderTexture; - } - - class Sprite { - constructor(game: Phaser.Game, x: number, y: number, key: string, frame: number); - game: Phaser.Game; - exists: boolean; - alive: boolean; - group: Phaser.Group; - name: string; - type: number; - renderOrderID: number; - lifespan: number; - events: Phaser.Event[]; - animations: Phaser.AnimationManager; - input: Phaser.InputHandler; - key: string; - currentFrame: number; - anchor: Phaser.Point; - x: number; - y: number; - position: Phaser.Point; - autoCull: boolean; - scale: Phaser.Point; - scrollFactor: Phaser.Point; - offset: Phaser.Point; - center: Phaser.Point; - topLeft: Phaser.Point; - topRight: Phaser.Point; - bottomRight: Phaser.Point; - bottomLeft: Phaser.Point; - bounds: Phaser.Rectangle; - body: Phaser.Physics.Arcade.Body; - velocity: number; - acceleration: number; - inWorld: boolean; - inWorldThreshold: number; - angle: number; - frame: number; - frameName: string; - inCamera: boolean; - crop: boolean; - cropEnabled: boolean; - inputEnabled: boolean; - preUpdate(): void; - postUpdate(): void; - centerOn(x: number, y: number): void; - revive(): void; - kill(): void; - reset(x: number, y: number): void; - updateBounds(): void; - getLocalPosition(p: Phaser.Point, x: number, y: number): Phaser.Point; - getLocalUnmodifiedPosition(p: Phaser.Point, x: number, y: number): Phaser.Point; - bringToTop(): void; - getBounds(rect: Phaser.Rectangle): Phaser.Rectangle; - } - - class TileSprite { - constructor(game: Phaser.Game, x: number, y: number, width: number, height: number, key?: string, frame?: number); - texture: Phaser.RenderTexture; - type: number; - tileScale: Phaser.Point; - tilePosition: Phaser.Point; - } - - class Text { - constructor(game: Phaser.Game, x: number, y: number, text: string, style: string); - exists: boolean; - alive: boolean; - group: Phaser.Group; - content: string; - name: string; - game: Phaser.Game; - type: number; - text: string; - angle: number; - style: string; - visible: boolean; - position: Phaser.Point; - anchor: Phaser.Point; - scale: Phaser.Point; - scrollFactor: Phaser.Point; - renderable: boolean; - update(): void; - } - - class BitmapText extends Phaser.Text { - } - - class Button { - constructor(game: Phaser.Game, x: number, y: number, key: string, callback: Function, overFrame: number, outFrame: number, downFrame: number); - input: Phaser.InputHandler; - onInputUp: Phaser.Signal; - onInputDown: Phaser.Signal; - onInputOut: Phaser.Signal; - onInputOver: Phaser.Signal; - events: Phaser.Event[]; - setFrames(overFrame?: number, outFrame?: number, downFrame?: number): void; - onInputOverHandler(pointer: Phaser.Pointer): void; - onInputUpHandler(pointer: Phaser.Pointer): void; - onInputDownHandler(pointer: Phaser.Pointer): void; - onInputOutHandler(pointer: Phaser.Pointer): void; - } - - class Graphics extends Phaser.Sprite { - constructor(game: Phaser.Game, x: number, y: number); - angle: number; - } - - class RenderTexture { - constructor(game: Phaser.Game, key: string, width: number, height: number); - name: string; - type: number; - } - - class Canvas { - create(width: number, height: number): HTMLCanvasElement; - getOffset(element: HTMLElement, point?: Phaser.Point): Phaser.Point; - getAspectRatio(canvas: HTMLCanvasElement): number; - setBackgroundColor(canvas: HTMLCanvasElement, color: string): HTMLCanvasElement; - setTouchAction(canvas: HTMLCanvasElement, value: string): HTMLCanvasElement; - addToDOM(canvas: HTMLCanvasElement, parent: string, overflowHidden: boolean): HTMLCanvasElement; - setTransform(context: CanvasRenderingContext2D, translateX: number, translateY: number, scaleX: number, scaleY: number, skewX: number, skewY: number): CanvasRenderingContext2D; - setSmoothingEnabled(context: CanvasRenderingContext2D, value: boolean): CanvasRenderingContext2D; - setImageRenderingCrisp(canvas: HTMLCanvasElement): HTMLCanvasElement; - setImageRenderingBicubic(canvas: HTMLCanvasElement): HTMLCanvasElement; - } - - class StageScaleMode { - constructor(game: Phaser.Game, width: number, height: number); - static EXACT_FIT: number; - static NO_SCALE: number; - static SHOW_ALL: number; - forceLandscape: boolean; - forcePortrait: boolean; - incorrectOrientation: boolean; - pageAlignHorizontally: boolean; - pageAlignVeritcally: boolean; - minWidth: number; - maxWidth: number; - minHeight: number; - maxHeight: number; - width: number; - height: number; - maxIterations: number; - game: Phaser.Game; - enterLandscape: Phaser.Signal; - enterPortrait: Phaser.Signal; - orientation: number; - scaleFactor: Phaser.Point; - aspectRatio: number; - isFullScreen: boolean; - isPortrait: boolean; - isLandscape: boolean; - startFullScreen(): void; - stopFullScreen(): void; - checkOrientationState(): void; - checkOrientation(): void; - checkResize(event: any): void; - refresh(): void; - setScreenSize(force: boolean): void; - setSize(): void; - setMaximum(): void; - setShowAll(): void; - setExactFit(): void; - } - - class Device { - patchAndroidClearRect: boolean; - desktop: boolean; - iOS: boolean; - android: boolean; - chromeOS: boolean; - linux: boolean; - macOS: boolean; - windows: boolean; - canvas: boolean; - file: boolean; - fileSystem: boolean; - localStorage: boolean; - webGL: boolean; - worker: boolean; - touch: boolean; - mspointer: boolean; - css3D: boolean; - pointerLock: boolean; - arora: boolean; - chrome: boolean; - epiphany: boolean; - firefox: boolean; - ie: boolean; - ieVersion: number; - mobileSafari: boolean; - midori: boolean; - opera: boolean; - safari: boolean; - webApp: boolean; - audioData: boolean; - webAudio: boolean; - ogg: boolean; - opus: boolean; - mp3: boolean; - wav: boolean; - m4a: boolean; - webm: boolean; - iPhone: boolean; - iPhone4: boolean; - iPad: boolean; - pixelRatio: number; - canPlayAudio(type: string): boolean; - isConsoleOpen(): boolean; - } - - class RequestAnimationFrame { - constructor(game: Phaser.Game); - game: Phaser.Game; - isRunning: boolean; - start(): boolean; - updateRAF(time: number): void; - updateSetTimeout(): void; - stop(): void; - isSetTimeOut(): boolean; - isRAF(): boolean; - } - - class RandomDataGenerator { - constructor(seeds: Array); - c: number; - s0: number; - s1: number; - s2: number; - rnd(): number; - sow(seeds: Array): void; - hash(data: any): number; - integer(): number; - frac(): number; - real(): number; - integerInRange(min: number, max: number): number; - realInRange(min: number, max: number): number; - normal(): number; - uuid(): number; - pick(ary: number[]): number; - weightedPick(ary: number[]): number; - timestamp(a?: number, b?: number): number; - angle(): number; - } - - class Math { - static PI2: number; - static fuzzyEqual(a: number, b: number, epsilon?: number): boolean; - static fuzzyLessThan(a: number, b: number, epsilon?: number): boolean; - static fuzzyGreaterThan(a: number, b: number, epsilon?: number): boolean; - static fuzzyCeil(a: number, b: number, epsilon?: number): boolean; - static fuzzyFloor(a: number, b: number, epsilon?: number): boolean; - static average(...numbers: number[]): number; - static truncate(n: number): number; - static shear(n: number): number; - static snapTo(input: number, gap: number, start?: number): number; - static snapToFloor(input: number, gap: number, start?: number): number; - static snapToCeil(input: number, gap: number, start?: number): number; - static snapToInArray(input: number, arr: number[], sort?: boolean): number; - static roundTo(value: number, place?: number, base?: number): number; - static floorTo(value: number, place?: number, base?: number): number; - static ceilTo(value: number, place?: number, base?: number): number; - static interpolateFloat(a: number, b: number, weight: number): number; - static angleBetween(x1: number, y1: number, x2: number, y2: number): number; - static normalizeAngle(angle: number, radians?: boolean): number; - static nearestAngleBetween(a1: number, a2: number, radians?: boolean): number; - static interpolateAngles(a1: number, a2: number, weight: number, radians?: boolean, ease?: any): number; - static chanceRoll(chance?: number): boolean; - static numberArray(min: number, max: number): number[]; - static maxAdd(value: number, amount: number, max: number): number; - static minSub(value: number, amount: number, min: number): number; - static wrap(value: number, min: number, max: number): number; - static wrapValue(value: number, amount: number, max: number): number; - static randomSign(): number; - static isOdd(n: number): boolean; - static isEven(n: number): boolean; - static max(...numbers: number[]): number; - static min(...numbers: number[]): number; - static wrapAngle(angle: number): number; - static angleLimit(angle: number, min: number, max: number): number; - static linearInterpolation(v: number[], k: number): number; - static bezierInterpolation(v: number[], k: number): number; - static catmullRomInterpolation(v: number[], k: number): number; - static linear(p0: number, p1: number, t: number): number; - static bernstein(n: number, i: number): number; - static catmullRom(p0: number, p1: number, p2: number, p3: number, t: number): number; - static difference(a: number, b: number): number; - static getRandom(objects: Object[], startIndex?: number, length?: number): Object; - static floor(value: number): number; - static ceil(value: number): number; - static sinCosGenerator(length: number, sinAmplitude?: number, cosAmplitude?: number, frequency?: number): { sin: number[]; cos: number[]; }; - static shift(stack: Array): any; - static shuffleArray(array: Array): Array; - static distance(x1: number, y1: number, x2: number, y2: number): number; - static distanceRounded(x1: number, y1: number, x2: number, y2: number): number; - static clamp(x: number, a: number, b: number): number; - static clampBottom(x: number, a: number): number; - static mapLinear(x: number, a1: number, a2: number, b1: number, b2: number): number; - static smoothstep(x: number, min: number, max: number): number; - static smootherstep(x: number, min: number, max: number): number; - static sign(x: number): number; - static degToRad(degrees: number): number; - static radToDeg(radians: number): number; - } - - class QuadTree { - constructor(physicsManager: Phaser.Physics.Arcade, x: number, y: number, width: number, height: number, maxObject?: number, maxLevels?: number, level?: number); - physicsManager: Phaser.Physics.Arcade; - ID: number; + gravity: Phaser.Point; + worldLeft: SAT.Box; + worldRight: SAT.Box; + worldTop: SAT.Box; + worldBottom: SAT.Box; + worldPolys: any; + quadTree: Phaser.QuadTree; maxObjects: number; maxLevels: number; - level: number; - bounds: { - x: number; - y: number; - width: number; - height: number; - subWidth: number; - subHeight: number; - right: number; - bottom: number; - }; - objects: Array; - nodes: Array; - split(): void; - insert(body: Object): void; - getIndex(rect: Object): number; - retrieve(sprite: Object): Array; - clear(): void; - } + RECT: number; + CIRCLE: number; + POLYGON: number; + checkBounds(body: Phaser.Physics.Arcade.Body): boolean; + setBoundsToWorld(left: boolean, right: boolean, top: boolean, bottom: boolean): void; + setBounds(x: number, y: number, width: number, height: number, left: boolean, right: boolean, top: boolean, bottom: boolean): void; + updateMotion(body: Phaser.Physics.Arcade.Body): Phaser.Point; + overlap(object1: any, object2: any, overlapCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; + collide(object1: any, object2: any, collideCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; + collideHandler(object1: any, object2: any, collideCallback?: Function, processCallback?: Function, callbackContext?: any, overlapOnly: boolean): boolean; + collideSpriteVsSprite(sprite1: Phaser.Sprite, sprite2: Phaser.Sprite, collideCallback?: Function, processCallback?: Function, callbackContext?: any, overlapOnly: boolean): boolean; + collideSpriteVsGroup(sprite1: Phaser.Sprite, group: Phaser.Group, collideCallback?: Function, processCallback?: Function, callbackContext?: any, overlapOnly: boolean): boolean; + collideGroupVsSelf(group: Phaser.Group, collideCallback?: Function, processCallback?: Function, callbackContext?: any, overlapOnly: boolean): boolean; + collideGroupVsGroup(group: Phaser.Group, group2: Phaser.Group, collideCallback?: Function, processCallback?: Function, callbackContext?: any, overlapOnly: boolean): boolean; + collideSpriteVsTilemapLayer(sprite: Phaser.Sprite, tilemapLayer: Phaser.TilemapLayer, collideCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; + collideGroupVsTilemapLayer(group: Phaser.Group, tilemapLayer: Phaser.TilemapLayer, collideCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; + separate(body: Phaser.Physics.Arcade.Body, body2: Phaser.Physics.Arcade.Body, processCallback?: Function, callbackContext?: any, overlapOnly: boolean): boolean; + intersects(a: Phaser.Physics.Arcade.Body, b: Phaser.Physics.Arcade.Body): boolean; + tileIntersects(body: Phaser.Physics.Arcade.Body, tile: Phaser.Tile): boolean; + separateTiles(body: Phaser.Physics.Arcade.Body, tile: Array): boolean; + separateTile(body: Phaser.Physics.Arcade.Body, tile: Phaser.Tile): boolean; + processTileSeparation(body: Phaser.Physics.Arcade.Body): boolean; + moveToObject(displayObject: Phaser.Sprite, destination: Phaser.Sprite, speed?: number, maxTime?: number): number; + moveToPointer(displayObject: Phaser.Sprite, speed?: number, pointer?: Phaser.Pointer, maxTime?: number): number; + moveToXY(displayObject: Phaser.Sprite, x: number, y: number, speed?: number, maxTime?: number): number; + velocityFromAngle(angle: number, speed?: number, point?: Phaser.Point): Phaser.Point; + velocityFromRotation(rotation: number, speed?: number, point?: Phaser.Point): Phaser.Point; + accelerationFromRotation(rotation: number, speed?: number, point?: Phaser.Point): Phaser.Point; + accelerateToObject(displayObject: Phaser.Sprite, destination: Phaser.Sprite, speed?: number, xSpeedMax?: number, ySpeedMax?: number): number; + accelerateToPointer(displayObject: Phaser.Sprite, pointer: Phaser.Pointer, speed?: number, xSpeedMax?: number, ySpeedMax?: number): number; + accelerateToXY(displayObject: Phaser.Sprite, x: number, y: number, speed?: number, xSpeedMax?: number, ySpeedMax?: number): number; + distanceTo(source: Phaser.Sprite, target: Phaser.Sprite): number; + distanceToXY(displayObject: Phaser.Sprite, x: number, y: number): number; + distanceToPointer(displayObject: Phaser.Sprite, pointer: Phaser.Pointer): number; + angleBetween(source: Phaser.Sprite, target: Phaser.Sprite): number; + angleToXY(displayObject: Phaser.Sprite, x: number, y: number): number; + angleToPointer(displayObject: Phaser.Sprite, pointer: Phaser.Pointer): number; + } - class Circle { - constructor(x?: number, y?: number, diameter?: number); - x: number; - y: number; - diameter: number; - radius: number; - left: number; - right: number; - top: number; - bottom: number; - area: number; - empty: boolean; - circumference(): number; - setTo(x: number, y: number, diameter: number): Circle; - copyFrom(source: any): Circle; - copyTo(dest: Object): Object; - distance(dest: Object, round: boolean): number; - clone(out: Phaser.Circle): Phaser.Circle; - contains(x: number, y: number): Phaser.Circle; - circumferencePoint(angle: number, asDegrees: number, output?: Phaser.Point): Phaser.Point; - offset(dx: number, dy: number): Phaser.Circle; - offsetPoint(point: Phaser.Point): Phaser.Circle; - toString(): string; - static contains(a: Phaser.Circle, x: number, y: number): boolean; - static equals(a: Phaser.Circle, b: Phaser.Circle): boolean; - static intersects(a: Phaser.Circle, b: Phaser.Circle): boolean; - static circumferencePoint(a: Phaser.Circle, angle: number, asDegrees: boolean, output?: Phaser.Point): Phaser.Point; - static intersectsRectangle(c: Phaser.Circle, r: Phaser.Rectangle): boolean; - } + module Arcade { - class Point { - constructor(x: number, y: number); - x: number; - y: number; - copyFrom(source: any): Phaser.Point; - invert(): Phaser.Point; - setTo(x: number, y: number): Phaser.Point; - add(x: number, y: number): Phaser.Point; - subtract(x: number, y: number): Phaser.Point; - multiply(x: number, y: number): Phaser.Point; - divide(x: number, y: number): Phaser.Point; - clampX(min: number, max: number): Phaser.Point; - clampY(min: number, max: number): Phaser.Point; - clamp(min: number, max: number): Phaser.Point; - clone(output: Phaser.Point): Phaser.Point; - copyTo(dest: any): Object; - distance(dest: Object, round?: boolean): number; - equals(a: Phaser.Point): boolean; - rotate(x: number, y: number, angle: number, asDegrees: boolean, distance: number): Phaser.Point; - toString(): string; - static add(a: Phaser.Point, b: Phaser.Point, out?: Phaser.Point): Phaser.Point; - static subtract(a: Phaser.Point, b: Phaser.Point, out?: Phaser.Point): Phaser.Point; - static multiply(a: Phaser.Point, b: Phaser.Point, out?: Phaser.Point): Phaser.Point; - static divide(a: Phaser.Point, b: Phaser.Point, out?: Phaser.Point): Phaser.Point; - static equals(a: Phaser.Point, b: Phaser.Point): boolean; - static distance(a: Phaser.Point, b: Phaser.Point, round: boolean): number; - static rotate(a: Phaser.Point, x: number, y: number, angle: number, asDegrees: boolean, distance: boolean): Phaser.Point; - } + class FaceChoices { + none: boolean; + any: boolean; + up: boolean; + down: boolean; + left: boolean; + right: boolean; + x: number; + y: number; + } - class Rectangle { - constructor(x: number, y: number, width: number, height: number); - x: number; - y: number; - width: number; - height: number; - halfWidth: number; - halfHeight: number; - bottom: number; - bottomRight: Phaser.Point; - left: number; - right: number; - volume: number; - perimeter: number; - centerX: number; - centerY: number; - top: number; - topLeft: Phaser.Point; - empty: boolean; - offset(dx: number, dy: number): Phaser.Rectangle; - offsetPoint(point: Phaser.Point): Phaser.Rectangle; - setTo(x: number, y: number, width: number, height: number): Phaser.Rectangle; - floor(): void; - copyFrom(source: any): Phaser.Rectangle; - copyTo(dest: any): Object; - inflate(dx: number, dy: number): Phaser.Rectangle; - size(output: Phaser.Point): Phaser.Point; - clone(output: Phaser.Rectangle): Phaser.Rectangle; - contains(x: number, y: number): boolean; - containsRect(b: Phaser.Rectangle): boolean; - equals(b: Phaser.Rectangle): boolean; - intersection(b: Phaser.Rectangle, out: Phaser.Rectangle): Phaser.Rectangle; - intersects(b: Phaser.Rectangle, tolerance: number): boolean; - intersectsRaw(left: number, right: number, top: number, bottom: number, tolerance: number): boolean; - union(b: Phaser.Rectangle, out: Phaser.Rectangle): Phaser.Rectangle; - toString(): string; - static inflate(a: Phaser.Rectangle, dx: number, dy: number): Phaser.Rectangle; - static inflatePoint(a: Phaser.Rectangle, point: Phaser.Point): Phaser.Rectangle; - static size(a: Phaser.Rectangle, output: Phaser.Point): Phaser.Point; - static clone(a: Phaser.Rectangle, output: Phaser.Rectangle): Phaser.Rectangle; - static contains(a: Phaser.Rectangle, x: number, y: number): boolean; - static containsPoint(a: Phaser.Rectangle, point: Phaser.Point): boolean; - static containsRect(a: Phaser.Rectangle, b: Phaser.Rectangle): boolean; - static equals(a: Phaser.Rectangle, b: Phaser.Rectangle): boolean; - static intersection(a: Phaser.Rectangle, b: Phaser.Rectangle, out: Phaser.Rectangle): Phaser.Rectangle; - static intersects(a: Phaser.Rectangle, b: Phaser.Rectangle, tolerance: number): boolean; - static intersectsRaw(a: Phaser.Rectangle, left: number, right: number, top: number, bottom: number, tolerance: number): boolean; - static union(a: Phaser.Rectangle, b: Phaser.Rectangle, out: Phaser.Rectangle): Phaser.Rectangle; - } - - class Net { - constructor(game: Phaser.Game); - game: Phaser.Game; - getHostName(): string; - checkDomainName(domain: string): string; - updateQueryString(key: string, value: any, redirect?: boolean, url?: string): string; - getQueryString(parameter?: string): string; - decodeURI(value: string): string; - } - - class TweenManager { - constructor(game: Phaser.Game); - game: Phaser.Game; - REVISION: string; - getAll(): Phaser.Tween[]; - removeAll(): void; - add(tween: Phaser.Tween): Phaser.Tween; - create(object: Object): Phaser.Tween; - remove(tween: Phaser.Tween): void; - update(): boolean; - pauseAll(): void; - resumeAll(): void; - } - - class Tween { - constructor(object: Object, game: Phaser.Game); - game: Phaser.Game; - pending: boolean; - pendingDelete: boolean; - onStart: Phaser.Signal; - onComplete: Phaser.Signal; - isRunning: boolean; - to(properties: Object, duration?: number, ease?: any, autoStart?: boolean, delay?: number, loop?: boolean): Phaser.Tween; - start(time: number): Phaser.Tween; - stop(): Phaser.Tween; - delay(amount: number): Phaser.Tween; - repeat(times: number): Phaser.Tween; - yoyo(yoyo: boolean): Phaser.Tween; - easing(easing: any): Phaser.Tween; - interpolation(interpolation: Function): Phaser.Tween; - chain(...tweens: Phaser.Tween[]): Phaser.Tween; - loop(): Phaser.Tween; - onStartCallback(callback: Function): Phaser.Tween; - onUpdateCallback(callback: Function): Phaser.Tween; - onCompleteCallback(callback: Function): Phaser.Tween; - pause(): void; - resume(): void; - update(time: number): boolean; - } - - class Easing { - Linear: { - None: (k: number) => number; - }; - Quadratic: { - In: (k: number) => number; - Out: (k: number) => number; - InOut: (k: number) => number; - }; - Cubic: { - In: (k: number) => number; - Out: (k: number) => number; - InOut: (k: number) => number; - }; - Quartic: { - In: (k: number) => number; - Out: (k: number) => number; - InOut: (k: number) => number; - }; - Quintic: { - In: (k: number) => number; - Out: (k: number) => number; - InOut: (k: number) => number; - }; - Sinusoidal: { - In: (k: number) => number; - Out: (k: number) => number; - InOut: (k: number) => number; - }; - Exponential: { - In: (k: number) => number; - Out: (k: number) => number; - InOut: (k: number) => number; - }; - Circular: { - In: (k: number) => number; - Out: (k: number) => number; - InOut: (k: number) => number; - }; - Elastic: { - In: (k: number) => number; - Out: (k: number) => number; - InOut: (k: number) => number; - }; - Back: { - In: (k: number) => number; - Out: (k: number) => number; - InOut: (k: number) => number; - }; - Bounce: { - In: (k: number) => number; - Out: (k: number) => number; - InOut: (k: number) => number; - }; - } - - class Time { - constructor(game: Phaser.Game); - game: Phaser.Game; - physicsElapsed: number; - time: number; - pausedTime: number; - now: number; - elapsed: number; - fps: number; - fpsMin: number; - fpsMax: number; - msMin: number; - msMax: number; - frames: number; - pauseDuration: number; - timeToCall: number; - lastTime: number; - totalElapsedSeconds(): number; - update(time: number): number; - gamePaused(): void; - gameResumed(): void; - elapsedSince(since: number): number; - elapsedSecondsSince(since: number): number; - reset(): void; - } - - class AnimationManager { - constructor(sprite); - sprite: Phaser.Sprite; - game: Phaser.Game; - currentFrame: Phaser.Animation.Frame; - updateIfVisible: boolean; - frameData: Phaser.Animation.FrameData; - frameTotal: number; - frame: number; - frameName: string; - loadFrameData(frameData: Phaser.Animation.FrameData): void; - add(name: string, frames?: Array, frameRate?: number, loop?: boolean, useNumericIndex?: boolean): Phaser.Animation; - validateFrames(frames: Array, useNumericIndex?: boolean): boolean; - play(name: string, frameRate?: number, loop?: boolean): Phaser.Animation; - stop(name?: string, resetFrame?: boolean): void; - update(): boolean; - destroy(): void; - } - - class Animation { - constructor(game: Phaser.Game, parent: Phaser.Sprite, name: string, frameData: Phaser.Animation.FrameData, frames: any[], delay: number, looped: boolean); - game: Phaser.Game; - name: string; - delay: number; - looped: boolean; - isFinished: boolean; - isPlaying: boolean; - currentFrame: Phaser.Animation.Frame; - frameTotal: number; - frame: number; - play(frameRate?: number, loop?: boolean): Phaser.Animation; - restart(): void; - stop(resetFrame?: boolean): void; - update(): boolean; - destroy(): void; - onComplete(): void; - } - - module Animation { - class Frame { - constructor(index: number, x: number, y: number, width: number, height: number, name: string, uuid: string); - index: number; - x: number; - y: number; - width: number; - height: number; - centerX: number; - centerY: number; - distance: number; - name: string; - uuid: string; - rotated: boolean; - rotationDirection: string; - trimmed: boolean; - sourceSizeW: number; - sourceSizeH: number; - spriteSourceSizeX: number; - spriteSourceSizeY: number; - spriteSourceSizeW: number; - spriteSourcesizeH: number; - setTrim(trimmed: boolean, actualWidth: number, actualHeight: number, destX: number, destY: number, destWidth: number, destHeight: number): void; + class Body { + constructor(sprite: Phaser.Sprite); + sprite: Phaser.Sprite; + game: Phaser.Game; + offset: Phaser.Point; + preX: number; + preY: number; + preRotation: number; + velocity: Phaser.Point; + acceleration: Phaser.Point; + speed: number; + angle: number; + gravity: Phaser.Point; + bounce: Phaser.Point; + minVelocity: Phaser.Point; + maxVelocity: Phaser.Point; + angularVelocity: number; + angularAcceleration: number; + angularDrag: number; + maxAngular: number; + mass: number; + linearDamping: number; + checkCollision: FaceChoices; + touching: FaceChoices; + blocked: FaceChoices; + facing: number; + rebound: boolean; + immovable: boolean; + moves: boolean; + rotation: number; + allowRotation: boolean; + allowGravity: boolean; + customSeparateCallback: any; + customSeparateContext: any; + collideCallback: any; + collideCallbackContext: any; + collideWorldBounds: boolean; + type: number; + shape: any; + polygon: any; + left: number; + right: number; + top: number; + bottom: number; + width: number; + height: number; + contacts: any; + overlapX: number; + overlapY: number; + updateScale(): void; + preUpdate(): void; + checkBlocked(): void; + updateBounds(): void; + applyDamping(): void; + reboundCheck(x: number, y: number, rebound: boolean): void; + getUpwardForce(): number; + getDownwardForce(): number; + sub(x: number): void; + add(x: number): void; + give(body: Phaser.Physics.Arcade.Body, response: SAT.Response): void; + take(body: Phaser.Physics.Arcade.Body, response: SAT.Response): void; + split(body: Phaser.Physics.Arcade.Body, response: SAT.Response): void; + exchange(body: Phaser.Physics.Arcade.Body): void; + processRebound(body: Phaser.Physics.Arcade.Body): void; + overlap(body: Phaser.Physics.Arcade.Body, response: SAT.Response): boolean; + inContact(body: Phaser.Physics.Arcade.Body): boolean; + addContact(body: Phaser.Physics.Arcade.Body): boolean; + removeContact(body: Phaser.Physics.Arcade.Body): boolean; + separate(body: Phaser.Physics.Arcade.Body, response: SAT.Response): boolean; + hitLeft(body: Phaser.Physics.Arcade.Body, response: SAT.Response): void; + hitRight(body: Phaser.Physics.Arcade.Body, response: SAT.Response): void; + hitTop(body: Phaser.Physics.Arcade.Body, response: SAT.Response): void; + hitBottom(body: Phaser.Physics.Arcade.Body, response: SAT.Response): void; + integrateVelocity():void; + postUpdate(): void; + reset(full: boolean): void; + destroy(): void; + setCircle(radius: number, offsetX: number, offsetY: number): void; + setRectangle(width: number, height: number, translateX: number, translateY: number): void; + setPoints(points: any): void; + translate(x: number, y: number): void; + onFloor(): boolean; + onWall(): boolean; + deltaX(): number; + deltaY(): number; + deltaZ(): number; + x: number; + y: number; } + } + } + + class Particles { + constructor(game: Phaser.Game); + emitters: Object; + ID: number; + add(emitter: Phaser.Particles.Arcade.Emitter): Phaser.Particles.Arcade.Emitter; + remove(emitter: Phaser.Particles.Arcade.Emitter): void; + update(): void; + } + + module Particles { + module Arcade { + class Emitter extends Phaser.Group + { + constructor(game: Phaser.Game, x: number, y: number, maxParticles?: number); + name: string; + type: number; + x: number; + y: number; + width: number; + height: number; + minParticleSpeed: Phaser.Point; + maxParticleSpeed: Phaser.Point; + minParticleScale: number; + maxParticleScale: number; + minRotation: number; + maxRotation: number; + gravity: number; + particleClass: string; + particleDrag: Phaser.Point; + angularDrag: number; + frequency: number; + maxParticles: number; + lifespan: number; + bounce: Phaser.Point; + on: boolean; + exists: boolean; + emitX: number; + emitY: number; + alpha: number; + visible: boolean; + left: number; + top: number; + bottom: number; + right: number; + update(): void; + makeParticles(keys: string[], frames: string[], quantity: number, collide: boolean, collideWorldBounds: boolean): Phaser.Particles.Arcade.Emitter; + kill(): void; + revive(): void; + start(explode: boolean, lifespan: number, frequency: number, quantity: number): void; + emitParticle(): void; + setSize(width: number, height: number): void; + setXSpeed(min: number, max: number): void; + setYSpeed(min: number, max: number): void; + setRotation(min: number, max: number): void; + at(object: Object): void; - class FrameData { - addFrame(frame: Frame): Frame; - getFrame(index: number): Frame; - getFrameByName(name: string): Frame; - checkFrame(name: string): boolean; - getFrameRange(start: number, end: number, output: Array): Array; - getFrames(frames: Array, useNumericIndex?: boolean, output?: Array): Array; - getFrameIndexes(frames: Array, useNumericIndex?: boolean, output?: Array): Array; - total: number; } + } + } - class Parser { - spriteSheet(game: Phaser.Game, key: string, frameWidth: number, frameHeight: number, frameMax?: number): Phaser.Animation.FrameData; - JSONData(game: Phaser.Game, json: Object, cacheKey: string): Phaser.Animation.FrameData; - JSONDataHash(game: Phaser.Game, json: Object, cacheKey: string): Phaser.Animation.FrameData; - XMLData(game: Phaser.Game, xml: Object, cacheKey: string): Phaser.Animation.FrameData; - } - } + class Tilemap { + constructor(game: Phaser.Game, key: string, x: number, y: number, resizeWorld?: boolean, tileWidth?: number, tileHeight?: number); + game: Phaser.Game; + group: Phaser.Group; + name: string; + key: string; + renderOrderID: number; + collisionCallback: Function; + exists: boolean; + visible: boolean; + tiles: Array; + layers: Array; + position: Phaser.Point; + type: number; + renderer: Phaser.TilemapRenderer; + mapFormat: string; + widthInPixels: number; + heightInPixels: number; + static CSV: number; + static JSON: number; + parseCSV(data: string, key: string, tileWidth: number, tileHeight: number): void; + parseTiledJSON(json: string, key: string): void; + generateTiles(quantity: number): void; + setCollisionCallback(context: Object, callback: Function): void; + setCollisionRange(start: number, end: number, collision: number, resetCollisions?: boolean, separateX?: boolean, separateY?: boolean): void; + setCollisionByIndex(value: number[], collision: number, resetCollisions?: boolean, separateX?: boolean, separateY?: boolean): void; + getTileByIndex(value: number): Tile; + getTile(x: number, y: number, layer?: number): Tile; + getTileFromWorldXY(x: number, y: number, layer?: number): Tile; + getTileFromInputXY(layer?: number): Tile; + getTileOverlaps(object: Object): Array; + collide(objectOrGroup: any, callback: Function, context: Object): boolean; + collideGameObject(object: Object): boolean; + putTile(x: number, y: number, index: number, layer?: number): void; + update(): void; + destroy(): void; + } - class Cache { - constructor(game: Phaser.Game); - game: Phaser.Game; - onSoundUnlock: Phaser.Signal; - addCanvas(key: string, canvas: HTMLCanvasElement, context: CanvasRenderingContext2D): void; - addRenderTexture(key: string, texture: RenderTexture): void; - addSpriteSheet(key: string, url: string, data: Object, frameWidth: number, frameHeight: number, frameMax: number): void; - addTilemap(key: string, url: string, data: Object, mapData: Object, atlasData: Object): void; - addTextureAtlas(key: string, url: string, data: Object, atlasData: Object): void; - addBitmapFont(key: string, url: string, data: Object, xmlData: Object): void; - addDefaultImage(): void; - addImage(key: string, url: string, data: Object): void; - addSound(key: string, url: string, data: Object): void; - reloadSound(key: string): void; - reloadSoundComplete(key: string): void; - updateSound(key: string, property: string, value: Phaser.Sound): void; - decodedSound(key: string, data: Object): void; - addText(key: string, url: string, data: Object): void; - getCanvas(key: string): Object; - checkImageKey(key: string): boolean; - getImage(key: string): Object; - getTilemap(key: string): Phaser.Tilemap; - getFrameData(key: string): Phaser.Animation.FrameData; - getFrameByIndex(key: string, frame: string): Phaser.Animation.Frame; - getFrameByName(key: string, frame: string): Phaser.Animation.Frame; - getFrame(key: string): Phaser.Animation.Frame; - getTextureFrame(key: string): Phaser.Animation.Frame; - getTexture(key: string): Phaser.RenderTexture; - getSound(key: string): Phaser.Sound; - getSoundData(key: string): Object; - isSoundDecoded(key: string): boolean; - isSoundReady(key: string): boolean; - isSpriteSheet(key: string): boolean; - getText(key: string): Object; - getKeys(array: Array): Array; - getImageKeys(): string[]; - getSoundKeys(): string[]; - getTextKeys(): string[]; - removeCanvas(key: string): void; - removeImage(key: string): void; - removeSound(key: string): void; - removeText(key: string): void; - destroy(): void; - } + class TilemapLayer { + constructor(game:Phaser.Game, tilemap:Phaser.Tilemap, index:number, width:number, height:number); + //constructor(parent: Tilemap, id: number, key: string, mapFormat: number, name: string, tileWidth: number, tileHeight: number); + exists: boolean; + visible: boolean; + widthInTiles: number; + heightInTiles: number; + widthInPixels: number; + heightInPixels: number; + tileMargin: number; + tileSpacing: number; + parent: Tilemap; + game: Phaser.Game; + ID: number; + name: string; + key: string; + type: number; + mapFormat: number; + tileWidth: number; + tileHeight: number; + boundsInTiles: Phaser.Rectangle; + tileset: Object; + canvas: any; + context: any; + baseTexture: any; + texture: any; + sprite: Phaser.Sprite; + mapData: Array; + alpha: number; + putTileWorldXY(x: number, y: number, index: number): void; + putTile(x: number, y: number, index: number): void; + swapTile(tileA: number, tileB: number, x?: number, y?: number, width?: number, height?: number): void; + fillTile(index: number, x?: number, y?: number, width?: number, height?: number): void; + randomiseTiles(tiles: number[], x?: number, y?: number, width?: number, height?: number): void; + replaceTile(tileA: number, tileB: number, x?: number, y?: number, width?: number, height?: number): void; + getTileBlock(x: number, y: number, width: number, height: number): Array; + getTileFromWorldXY(x: number, y: number): Tile; + getTileOverlaps(object: Object): Array; + getTempBlock(x: number, y: number, width: number, height: number, collisionOnly?: boolean): void; + getTileIndex(x: number, y: number): number; + addColumn(column: string[]): void; + createCanvas(): void; + updateBounds(): void; + parseTileOffsets(): number; + } - class Loader { - static TEXTURE_ATLAS_JSON_ARRAY: number; - static TEXTURE_ATLAS_JSON_HASH: number; - static TEXTURE_ATLAS_XML_STARLING: number; - constructor(game: Phaser.Game); - game: Phaser.Game; - queueSize: number; - isLoading: boolean; - hasLoaded: boolean; - progress: number; - preloadSprite: Phaser.Sprite; - crossOrigin: string; - baseURL: string; - onFileComplete: Phaser.Signal; - onFileError: Phaser.Signal; - onLoadStart: Phaser.Signal; - onLoadComplete: Phaser.Signal; - setPreloadSprite(sprite: Phaser.Sprite, direction?: number): void; - checkKeyExists(key: string): boolean; - reset(): void; - addToFileList(type: string, key: string, url: string, properties: Array): void; - image(key: string, url: string, overwrite?: boolean): void; - text(key: string, url: string, overwrite?: boolean): void; - spritesheet(key: string, url: string, frameWidth: number, frameHeight: number, frameMax: number): void; - audio(key: string, urls: string[], autoDecode?: boolean): void; - tilemap(key: string, tilesetURL: string, mapDataURL?: string, mapData?: Object, format?: string): void; - bitmapFont(key: string, textureURL: string, xmlURL?: string, xmlData?: Object): void; - atlasJSONArray(key: string, textureURL: string, atlasURL: string, atlasData: Object): void; - atlasJSONHash(key: string, textureURL: string, atlasURL: string, atlasData: Object): void; - atlasXML(key: string, textureURL: string, atlasURL: string, atlasData: Object): void; - atlas(key: string, textureURL: string, atlasURL?: string, atlasData?: Object, format?: number): void; - removeFile(key: string): void; - removeAll(): void; - start(): void; - loadFile(): void; - getAudioURL(urls: string[]): string; - fileError(key: string): void; - fileComplete(key: string): void; - jsonLoadComplete(key: string): void; - csvLoadComplete(key: string): void; - dataLoadError(key: string): void; - xmlLoadComplete(key: string): void; - nextFile(previousKey: string, success: boolean): void; - } + class Tile { + constructor(game: Phaser.Game, tilemap: Tilemap, index: number, width: number, height: number); + mass: number; + collideNone: boolean; + collideLeft: boolean; + collideRight: boolean; + collideUp: boolean; + collideDown: boolean; + separateX: boolean; + separateY: boolean; + game: Phaser.Game; + tilemap: Tilemap; + index: number; + width: number; + height: number; + destroy(): void; + setCollision(left: boolean, right: boolean, up: boolean, down: boolean, reset: boolean, seperateX: boolean, seperateY: boolean): void; + resetCollsion(): void; + toString(): string; + } - module Loader { - class Parser { - bitmapFont(game: Phaser.Game, xml: Object, cacheKey: Phaser.Animation.FrameData): void; - } - } - - class Sound { - constructor(game: Phaser.Game, key: string, volume?: number, loop?: boolean); - game: Phaser.Game; - name: string; - key: string; - loop: boolean; - markers: Object; - context: any; - autoplay: boolean; - totalDuration: number; - startTime: number; - currentTime: number; - duration: number; - stopTime: number; - paused: boolean; - isPlaying: boolean; - currentMarker: string; - pendingPlayback: boolean; - override: boolean; - usingWebAudio: boolean; - usingAudioTag: boolean; - onDecoded: Phaser.Signal; - onPlay: Phaser.Signal; - onPause: Phaser.Signal; - onResume: Phaser.Signal; - onLoop: Phaser.Signal; - onStop: Phaser.Signal; - onMute: Phaser.Signal; - isDecoded: boolean; - isDecoding: boolean; - mute: boolean; - volume: number; - onMarkerComplete: Phaser.Signal; - soundHasUnlocked(key: string): void; - addMarker(name: string, start: number, stop: number, volume?: number, loop?: boolean): void; - removeMarker(name: string): void; - update(): void; - play(marker?: string, position?: number, volume?: number, loop?: boolean): Phaser.Sound; - restart(marker: string, position: number, volume?: number, loop?: boolean): void; - pause(): void; - resume(): void; - stop(): void; - } - - class SoundManager { - constructor(game: Phaser.Game); - game: Phaser.Game; - onSoundDecode: Phaser.Signal; - context: any; - usingWebAudio: boolean; - usingAudioTag: boolean; - noAudio: boolean; - touchLocked: boolean; - channels: number; - mute: boolean; - volume: number; - boot(): void; - unlock(): void; - stopAll(): void; - pauseAll(): void; - resumeAll(): void; - decode(key: string, sound?: Phaser.Sound): void; - update(): void; - add(key: string, volume: number, loop: boolean): Phaser.Sound; - } - - module Utils { - class Debug { - constructor(game: Phaser.Game); - game: Phaser.Game; - font: string; - lineHeight: number; - renderShadow: boolean; - currentX: number; - currentY: number; - currentAlpha: number; - start(x?: number, y?: number, color?: string): void; - stop(): void; - line(text: string, x: number, y: number): void; - renderQuadTree(quadtree: Phaser.QuadTree, color?: string): void; - renderSpriteCorners(sprite: Phaser.Sprite, showText?: boolean, showBounds?: boolean, color?: string): void; - renderSoundInfo(sound: Phaser.Sound, x: number, y: number, color?: string): void; - renderCameraInfo(camera: Phaser.Camera, x: number, y: number, color?: string): void; - renderPointer(pointer: Phaser.Pointer, hideIfUp?: boolean, downColor?: string, upColor?: string, color?: string): void; - renderSpriteInputInfo(sprite: Phaser.Sprite, x: number, y: number, color?: string): void; - renderSpriteCollision(sprite: Phaser.Sprite, x: number, y: number, color?: string): void; - renderInputInfo(x: number, y: number, color?: string): void; - renderSpriteInfo(sprite: Phaser.Sprite, x: number, y: number, color?: string): void; - renderWorldTransformInfo(sprite: Phaser.Sprite, x: number, y: number, color?: string): void; - renderLocalTransformInfo(sprite: Phaser.Sprite, x: number, y: number, color?: string): void; - renderPointInfo(point: Phaser.Point, x: number, y: number, color?: string): void; - renderSpriteBody(sprite: Phaser.Sprite, color?: string): void; - renderSpriteBounds(sprite: Phaser.Sprite, color?: string, fill?: boolean): void; - renderPixel(x: number, y: number, fillStyle?: string): void; - renderPoint(point: Phaser.Point, fillStyle?: string): void; - renderRectangle(rect: Phaser.Rectangle, fillStyle?: string): void; - renderCircle(circle: Phaser.Circle, fillStyle?: string): void; - renderText(text: string, x: number, y: number, color?: string, font?: string): void; - } - } - - class Color { - getColor32(alpha: number, red: number, green: number, blue: number): number; - getColor(red: number, green: number, blue: number): number; - hexToRGB(h: string): number; - getColorInfo(color: number): string; - RGBtoHexstring(color: number): string; - RGBtoWebstring(color: number): string; - colorToHexstring(color: number): string; - interpolateColor(color1: number, color2: number, steps: number, currentStep: number, alpha: number): number; - interpolateColorWithRGB(color: number, r: number, g: number, b: number, steps: number, currentStep: number): number; - interpolateRGB(r1: number, g1: number, b1: number, r2: number, g2: number, b2: number, steps: number, currentStep: number): number; - getRandomColor(min?: number, max?: number, alpha?: number): number; - getRGB(color: number): Object; - getWebRGB(color: number): string; - getAlpha(color: number): number; - getAlphaFloat(color: number): number; - getRed(color: number): number; - getGreen(color: number): number; - getBlue(color: number): number; - } - - module Physics { - class Arcade { - constructor(game: Phaser.Game) - game: Phaser.Game; - gravity: Phaser.Point; - bounds: Phaser.Rectangle; - maxObjects: number; - maxLevels: number; - OVERLAP_BIAS: number; - TILE_OVERLAP: number; - quadTree: Phaser.QuadTree; - quadTreeID: number; - updateMotion(body: Phaser.Physics.Arcade.Body); - computeVelocity(axis: number, body: Phaser.Physics.Arcade.Body, velocity: number, acceleration: number, drag: number, max: number): void; - preUpdate(): void; - postUpdate(): void; - overlap(object1: any, object2: any, overlapCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; - overlapSpriteVsSprite(sprite1: Phaser.Sprite, sprite2: Phaser.Sprite, overlapCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; - overlapSpriteVsGroup(sprite1: Phaser.Sprite, group: Phaser.Group, overlapCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; - overlapGroupVsGroup(group: Phaser.Group, group2: Phaser.Group, overlapCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; - collide(object1: any, object2: any, collideCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; - collideSpriteVsSprite(sprite1: Phaser.Sprite, sprite2: Phaser.Sprite, collideCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; - collideSpriteVsTilemap(sprite1: Phaser.Sprite, tilemap: Phaser.Tilemap, collideCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; - collideSpriteVsGroup(sprite1: Phaser.Sprite, group: Phaser.Group, collideCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; - collideGroupVsTilemap(group: Phaser.Group, tilemap: Phaser.Tilemap, collideCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; - collideGroupVsGroup(group: Phaser.Group, group2: Phaser.Group, collideCallback?: Function, processCallback?: Function, callbackContext?: any): boolean; - separate(body: Phaser.Physics.Arcade.Body, body2: Phaser.Physics.Arcade.Body): void; - separateX(body: Phaser.Physics.Arcade.Body, body2: Phaser.Physics.Arcade.Body): void; - separateY(body: Phaser.Physics.Arcade.Body, body2: Phaser.Physics.Arcade.Body): void; - separateTile(object: Object, x: number, y: number, width: number, height: number, mass: number, collideLeft: boolean, collideRight: boolean, collideUp: boolean, collideDown: boolean, separateX: boolean, separateY: boolean): boolean; - separateTileX(object: Object, x: number, y: number, width: number, height: number, mass: number, collideLeft: boolean, collideRight: boolean, collideUp: boolean, collideDown: boolean, separateX: boolean, separateY: boolean): boolean; - separateTileY(object: Object, x: number, y: number, width: number, height: number, mass: number, collideLeft: boolean, collideRight: boolean, collideUp: boolean, collideDown: boolean, separateX: boolean, separateY: boolean): boolean; - velocityFromAngle(angle: number, speed?: number, point?: Phaser.Point): Phaser.Point; - moveTowardsObject(source: Phaser.Sprite, dest: Phaser.Sprite, speed?: number, maxTime?: number): void; - accelerateTowardsObject(source: Phaser.Sprite, dest: Phaser.Sprite, speed?: number, xSpeedMax?: number, ySpeedMax?: number): void; - moveTowardsMouse(source: Phaser.Sprite, speed?: number, maxTime?: number): void; - accelerateTowardsMouse(source: Phaser.Sprite, speed: number, xSpeedMax?: number, ySpeedMax?: number): void; - moveTowardsPoint(source: Phaser.Sprite, target: Phaser.Point, speed?: number, maxTime?: number): void; - accelerateTowardsPoint(source: Phaser.Sprite, target: Phaser.Point, speed: number, xSpeedMax?: number, ySpeedMax?: number): void; - distanceBetween(a: Phaser.Sprite, b: Phaser.Sprite): number; - distanceToPoint(a: Phaser.Sprite, target: Phaser.Point): number; - distanceToMouse(a: Phaser.Sprite): number; - angleBetweenPoint(a: Phaser.Sprite, target: Phaser.Point, asDegrees?: boolean): number; - angleBetween(a: Phaser.Sprite, b: Phaser.Sprite, asDegrees?: boolean): number; - velocityFromFacing(parent: Phaser.Sprite, speed: number): Phaser.Point; - angleBetweenMouse(a: Phaser.Sprite, asDegress?: boolean): number; - } - - module Arcade { - class BorderChoices { - none: boolean; - any: boolean; - up: boolean; - down: boolean; - left: boolean; - right: boolean; - } - - class Body { - constructor(sprite: Phaser.Sprite); - sprite: Phaser.Sprite; - game: Phaser.Game; - offset: Phaser.Point; - x: number; - y: number; - lastX: number; - lastY: number; - sourceWidth: number; - sourceHeight: number; - width: number; - height: number; - halfWidth: number; - helfHeight: number; - velocity: Phaser.Point; - acceleration: Phaser.Point; - drag: Phaser.Point; - gravity: Phaser.Point; - bounce: Phaser.Point; - maxVelocity: Phaser.Point; - angularVelocity: number; - angularAcceleration: number; - angularDrag: number; - maxAngular: number; - mass: number; - quadTreeIDs: string[]; - quadTreeIndex: number; - allowCollision: BorderChoices; - touching: BorderChoices; - wasTouching: BorderChoices; - immovable: boolean; - moves: boolean; - rotation: number; - allowRotation: boolean; - allowGravity: boolean; - customSeparateX: boolean; - customSeparateY: boolean; - overlapX: number; - overlapY: number; - collideWorldBounds: boolean; - bottom: number; - right: number; - updateBounds(centerX: number, centerY: number, scaleX: number, scaleY: number): void; - update(): void; - postUpdate(): void; - checkWorldBounds(): void; - setSize(width: number, height: number, offsetX: number, offsetY: number): void; - reset(): void; - deltaAbsX(): number; - deltaAbsY(): number; - deltaX(): number; - deltaY(): number; - } - } - } - - class Particles { - constructor(game: Phaser.Game); - emitters: Object; - ID: number; - add(emitter: Phaser.Particles.Arcade.Emitter): Phaser.Particles.Arcade.Emitter; - remove(emitter: Phaser.Particles.Arcade.Emitter): void; - update(): void; - } - - module Particles { - module Arcade { - class Emitter { - constructor(game: Phaser.Game, x: number, y: number, maxParticles?: number); - name: string; - type: number; - x: number; - y: number; - width: number; - height: number; - minParticleSpeed: Phaser.Point; - maxParticleSpeed: Phaser.Point; - minParticleScale: number; - maxParticleScale: number; - minRotation: number; - maxRotation: number; - gravity: number; - particleClass: string; - particleDrag: Phaser.Point; - angularDrag: number; - frequency: number; - maxParticles: number; - lifespan: number; - bounce: Phaser.Point; - on: boolean; - exists: boolean; - emitX: number; - emitY: number; - alpha: number; - visible: boolean; - left: number; - top: number; - bottom: number; - right: number; - update(): void; - makeParticles(keys: string[], frames: string[], quantity: number, collide: boolean, collideWorldBounds: boolean): Phaser.Particles.Arcade.Emitter; - kill(): void; - revive(): void; - start(explode: boolean, lifespan: number, frequency: number, quantity: number): void; - emitParticle(): void; - setSize(width: number, height: number): void; - setXSpeed(min: number, max: number): void; - setYSpeed(min: number, max: number): void; - setRotation(min: number, max: number): void; - at(object: Object): void; - - } - } - } - - class Tilemap { - constructor(game: Phaser.Game, key: string, x: number, y: number, resizeWorld?: boolean, tileWidth?: number, tileHeight?: number); - game: Phaser.Game; - group: Phaser.Group; - name: string; - key: string; - renderOrderID: number; - collisionCallback: Function; - exists: boolean; - visible: boolean; - tiles: Array; - layers: Array; - position: Phaser.Point; - type: number; - renderer: Phaser.TilemapRenderer; - mapFormat: string; - widthInPixels: number; - heightInPixels: number; - static CSV: number; - static JSON: number; - parseCSV(data: string, key: string, tileWidth: number, tileHeight: number): void; - parseTiledJSON(json: string, key: string): void; - generateTiles(quantity: number): void; - setCollisionCallback(context: Object, callback: Function): void; - setCollisionRange(start: number, end: number, collision: number, resetCollisions?: boolean, separateX?: boolean, separateY?: boolean): void; - setCollisionByIndex(value: number[], collision: number, resetCollisions?: boolean, separateX?: boolean, separateY?: boolean): void; - getTileByIndex(value: number): Tile; - getTile(x: number, y: number, layer?: number): Tile; - getTileFromWorldXY(x: number, y: number, layer?: number): Tile; - getTileFromInputXY(layer?: number): Tile; - getTileOverlaps(object: Object): Array; - collide(objectOrGroup: any, callback: Function, context: Object): boolean; - collideGameObject(object: Object): boolean; - putTile(x: number, y: number, index: number, layer?: number): void; - update(): void; - destroy(): void; - } - - class TilemapLayer { - constructor(parent: Tilemap, id: number, key: string, mapFormat: number, name: string, tileWidth: number, tileHeight: number); - exists: boolean; - visible: boolean; - widthInTiles: number; - heightInTiles: number; - widthInPixels: number; - heightInPixels: number; - tileMargin: number; - tileSpacing: number; - parent: Tilemap; - game: Phaser.Game; - ID: number; - name: string; - key: string; - type: number; - mapFormat: number; - tileWidth: number; - tileHeight: number; - boundsInTiles: Phaser.Rectangle; - tileset: Object; - canvas: any; - context: any; - baseTexture: any; - texture: any; - sprite: Phaser.Sprite; - mapData: Array; - alpha: number; - putTileWorldXY(x: number, y: number, index: number): void; - putTile(x: number, y: number, index: number): void; - swapTile(tileA: number, tileB: number, x?: number, y?: number, width?: number, height?: number): void; - fillTile(index: number, x?: number, y?: number, width?: number, height?: number): void; - randomiseTiles(tiles: number[], x?: number, y?: number, width?: number, height?: number): void; - replaceTile(tileA: number, tileB: number, x?: number, y?: number, width?: number, height?: number): void; - getTileBlock(x: number, y: number, width: number, height: number): Array; - getTileFromWorldXY(x: number, y: number): Tile; - getTileOverlaps(object: Object): Array; - getTempBlock(x: number, y: number, width: number, height: number, collisionOnly?: boolean): void; - getTileIndex(x: number, y: number): number; - addColumn(column: string[]): void; - createCanvas(): void; - updateBounds(): void; - parseTileOffsets(): number; - } - - class Tile { - constructor(game: Phaser.Game, tilemap: Tilemap, index: number, width: number, height: number); - mass: number; - collideNone: boolean; - collideLeft: boolean; - collideRight: boolean; - collideUp: boolean; - collideDown: boolean; - separateX: boolean; - separateY: boolean; - game: Phaser.Game; - tilemap: Tilemap; - index: number; - width: number; - height: number; - destroy(): void; - setCollision(left: boolean, right: boolean, up: boolean, down: boolean, reset: boolean, seperateX: boolean, seperateY: boolean): void; - resetCollsion(): void; - toString(): string; - } - - class TilemapRenderer { - constructor(game: Phaser.Game); - game: Phaser.Game; - render(tilemap: Tilemap): void; - } -} \ No newline at end of file + class TilemapRenderer { + constructor(game: Phaser.Game); + game: Phaser.Game; + render(tilemap: Tilemap): void; + } +} diff --git a/build/phaser.js b/build/phaser.js index 29f3cfa6..d065a936 100644 --- a/build/phaser.js +++ b/build/phaser.js @@ -9,7 +9,7 @@ }(this, function() { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -18,7 +18,7 @@ * * Phaser - http://www.phaser.io * -* v1.1.3 - Built at: Fri Nov 29 2013 18:20:59 +* v1.1.4 - Built at: Wed Feb 05 2014 16:54:13 * * By Richard Davey http://www.photonstorm.com @photonstorm * @@ -29,7 +29,7 @@ * * Follow Phaser development progress at http://www.photonstorm.com * -* Many thanks to Adam Saltsman (@ADAMATOMIC) for releasing Flixel, from both which Phaser +* Many thanks to Adam Saltsman (@ADAMATOMIC) for releasing Flixel, from which both Phaser * and my love of game development originate. * * "If you want your children to be intelligent, read them fairy tales." @@ -48,7 +48,7 @@ var PIXI = PIXI || {}; /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -57,8 +57,8 @@ var PIXI = PIXI || {}; */ var Phaser = Phaser || { - VERSION: '1.1.3', - DEV_VERSION: '1.1.3', + VERSION: '1.1.4', + DEV_VERSION: '1.1.4', GAMES: [], AUTO: 0, @@ -87,7 +87,10 @@ var Phaser = Phaser || { LEFT: 1, RIGHT: 2, UP: 3, - DOWN: 4 + DOWN: 4, + + CANVAS_PX_ROUND: false, + CANVAS_CLEAR_RECT: true }; @@ -100,7 +103,7 @@ PIXI.InteractionManager = function (dummy) { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -295,53 +298,14 @@ Phaser.Utils = { }; -// Global functions that PIXI needs - -(function() { - var consoleDisabled = false; - if (consoleDisabled) { - window.console = undefined; - } - if (window.console === undefined) { - window.console = { - debug: function() { - return true; - }, - info: function() { - return false; - }, - warn: function() { - return false; - }, - log: function() { - return false; - } - } - } - debug = (function(args) { - window.console.debug(args); - }); - info = (function(args) { - window.console.info(args); - }); - warn = (function(args) { - window.console.warn(args); - }); - log = (function(args) { - window.console.log(args); - }); -})(); - -/** -* Converts a hex color number to an [R, G, B] array -* -* @param {number} hex -* @return {array} -*/ function HEXtoRGB(hex) { return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; } +PIXI.hex2rgb = function hex2rgb(hex) { + return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; +}; + /** * A polyfill for Function.prototype.bind */ @@ -379,6 +343,16 @@ if (typeof Function.prototype.bind != 'function') { })(); } +/** +* A polyfill for Array.isArray +*/ +if (!Array.isArray) { + Array.isArray = function (arg) { + return Object.prototype.toString.call(arg) == '[object Array]'; + }; +} + + /* @@ -397,112 +371,112 @@ PIXI.mat3 = {}; PIXI.mat3.create = function() { - var matrix = new PIXI.Matrix(9); + var matrix = new PIXI.Matrix(9); - matrix[0] = 1; - matrix[1] = 0; - matrix[2] = 0; - matrix[3] = 0; - matrix[4] = 1; - matrix[5] = 0; - matrix[6] = 0; - matrix[7] = 0; - matrix[8] = 1; + matrix[0] = 1; + matrix[1] = 0; + matrix[2] = 0; + matrix[3] = 0; + matrix[4] = 1; + matrix[5] = 0; + matrix[6] = 0; + matrix[7] = 0; + matrix[8] = 1; - return matrix; -} + return matrix; +}; PIXI.mat3.identity = function(matrix) { - matrix[0] = 1; - matrix[1] = 0; - matrix[2] = 0; - matrix[3] = 0; - matrix[4] = 1; - matrix[5] = 0; - matrix[6] = 0; - matrix[7] = 0; - matrix[8] = 1; + matrix[0] = 1; + matrix[1] = 0; + matrix[2] = 0; + matrix[3] = 0; + matrix[4] = 1; + matrix[5] = 0; + matrix[6] = 0; + matrix[7] = 0; + matrix[8] = 1; - return matrix; -} + return matrix; +}; PIXI.mat4 = {}; PIXI.mat4.create = function() { - var matrix = new PIXI.Matrix(16); + var matrix = new PIXI.Matrix(16); - matrix[0] = 1; - matrix[1] = 0; - matrix[2] = 0; - matrix[3] = 0; - matrix[4] = 0; - matrix[5] = 1; - matrix[6] = 0; - matrix[7] = 0; - matrix[8] = 0; - matrix[9] = 0; - matrix[10] = 1; - matrix[11] = 0; - matrix[12] = 0; - matrix[13] = 0; - matrix[14] = 0; - matrix[15] = 1; + matrix[0] = 1; + matrix[1] = 0; + matrix[2] = 0; + matrix[3] = 0; + matrix[4] = 0; + matrix[5] = 1; + matrix[6] = 0; + matrix[7] = 0; + matrix[8] = 0; + matrix[9] = 0; + matrix[10] = 1; + matrix[11] = 0; + matrix[12] = 0; + matrix[13] = 0; + matrix[14] = 0; + matrix[15] = 1; - return matrix; -} + return matrix; +}; PIXI.mat3.multiply = function (mat, mat2, dest) { - if (!dest) { dest = mat; } + if (!dest) { dest = mat; } - // Cache the matrix values (makes for huge speed increases!) - var a00 = mat[0], a01 = mat[1], a02 = mat[2], - a10 = mat[3], a11 = mat[4], a12 = mat[5], - a20 = mat[6], a21 = mat[7], a22 = mat[8], + // Cache the matrix values (makes for huge speed increases!) + var a00 = mat[0], a01 = mat[1], a02 = mat[2], + a10 = mat[3], a11 = mat[4], a12 = mat[5], + a20 = mat[6], a21 = mat[7], a22 = mat[8], - b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], - b10 = mat2[3], b11 = mat2[4], b12 = mat2[5], - b20 = mat2[6], b21 = mat2[7], b22 = mat2[8]; + b00 = mat2[0], b01 = mat2[1], b02 = mat2[2], + b10 = mat2[3], b11 = mat2[4], b12 = mat2[5], + b20 = mat2[6], b21 = mat2[7], b22 = mat2[8]; - dest[0] = b00 * a00 + b01 * a10 + b02 * a20; - dest[1] = b00 * a01 + b01 * a11 + b02 * a21; - dest[2] = b00 * a02 + b01 * a12 + b02 * a22; + dest[0] = b00 * a00 + b01 * a10 + b02 * a20; + dest[1] = b00 * a01 + b01 * a11 + b02 * a21; + dest[2] = b00 * a02 + b01 * a12 + b02 * a22; - dest[3] = b10 * a00 + b11 * a10 + b12 * a20; - dest[4] = b10 * a01 + b11 * a11 + b12 * a21; - dest[5] = b10 * a02 + b11 * a12 + b12 * a22; + dest[3] = b10 * a00 + b11 * a10 + b12 * a20; + dest[4] = b10 * a01 + b11 * a11 + b12 * a21; + dest[5] = b10 * a02 + b11 * a12 + b12 * a22; - dest[6] = b20 * a00 + b21 * a10 + b22 * a20; - dest[7] = b20 * a01 + b21 * a11 + b22 * a21; - dest[8] = b20 * a02 + b21 * a12 + b22 * a22; + dest[6] = b20 * a00 + b21 * a10 + b22 * a20; + dest[7] = b20 * a01 + b21 * a11 + b22 * a21; + dest[8] = b20 * a02 + b21 * a12 + b22 * a22; - return dest; -} + return dest; +}; PIXI.mat3.clone = function(mat) { - var matrix = new PIXI.Matrix(9); + var matrix = new PIXI.Matrix(9); - matrix[0] = mat[0]; - matrix[1] = mat[1]; - matrix[2] = mat[2]; - matrix[3] = mat[3]; - matrix[4] = mat[4]; - matrix[5] = mat[5]; - matrix[6] = mat[6]; - matrix[7] = mat[7]; - matrix[8] = mat[8]; + matrix[0] = mat[0]; + matrix[1] = mat[1]; + matrix[2] = mat[2]; + matrix[3] = mat[3]; + matrix[4] = mat[4]; + matrix[5] = mat[5]; + matrix[6] = mat[6]; + matrix[7] = mat[7]; + matrix[8] = mat[8]; - return matrix; -} + return matrix; +}; PIXI.mat3.transpose = function (mat, dest) { - // If we are transposing ourselves we can skip a few steps but have to cache some values + // If we are transposing ourselves we can skip a few steps but have to cache some values if (!dest || mat === dest) { var a01 = mat[1], a02 = mat[2], a12 = mat[5]; @@ -526,34 +500,34 @@ PIXI.mat3.transpose = function (mat, dest) dest[7] = mat[5]; dest[8] = mat[8]; return dest; -} +}; PIXI.mat3.toMat4 = function (mat, dest) { - if (!dest) { dest = PIXI.mat4.create(); } + if (!dest) { dest = PIXI.mat4.create(); } - dest[15] = 1; - dest[14] = 0; - dest[13] = 0; - dest[12] = 0; + dest[15] = 1; + dest[14] = 0; + dest[13] = 0; + dest[12] = 0; - dest[11] = 0; - dest[10] = mat[8]; - dest[9] = mat[7]; - dest[8] = mat[6]; + dest[11] = 0; + dest[10] = mat[8]; + dest[9] = mat[7]; + dest[8] = mat[6]; - dest[7] = 0; - dest[6] = mat[5]; - dest[5] = mat[4]; - dest[4] = mat[3]; + dest[7] = 0; + dest[6] = mat[5]; + dest[5] = mat[4]; + dest[4] = mat[3]; - dest[3] = 0; - dest[2] = mat[2]; - dest[1] = mat[1]; - dest[0] = mat[0]; + dest[3] = 0; + dest[2] = mat[2]; + dest[1] = mat[1]; + dest[0] = mat[0]; - return dest; -} + return dest; +}; ///// @@ -561,82 +535,82 @@ PIXI.mat3.toMat4 = function (mat, dest) PIXI.mat4.create = function() { - var matrix = new PIXI.Matrix(16); + var matrix = new PIXI.Matrix(16); - matrix[0] = 1; - matrix[1] = 0; - matrix[2] = 0; - matrix[3] = 0; - matrix[4] = 0; - matrix[5] = 1; - matrix[6] = 0; - matrix[7] = 0; - matrix[8] = 0; - matrix[9] = 0; - matrix[10] = 1; - matrix[11] = 0; - matrix[12] = 0; - matrix[13] = 0; - matrix[14] = 0; - matrix[15] = 1; + matrix[0] = 1; + matrix[1] = 0; + matrix[2] = 0; + matrix[3] = 0; + matrix[4] = 0; + matrix[5] = 1; + matrix[6] = 0; + matrix[7] = 0; + matrix[8] = 0; + matrix[9] = 0; + matrix[10] = 1; + matrix[11] = 0; + matrix[12] = 0; + matrix[13] = 0; + matrix[14] = 0; + matrix[15] = 1; - return matrix; -} + return matrix; +}; PIXI.mat4.transpose = function (mat, dest) { - // If we are transposing ourselves we can skip a few steps but have to cache some values - if (!dest || mat === dest) - { - var a01 = mat[1], a02 = mat[2], a03 = mat[3], - a12 = mat[6], a13 = mat[7], - a23 = mat[11]; + // If we are transposing ourselves we can skip a few steps but have to cache some values + if (!dest || mat === dest) + { + var a01 = mat[1], a02 = mat[2], a03 = mat[3], + a12 = mat[6], a13 = mat[7], + a23 = mat[11]; - mat[1] = mat[4]; - mat[2] = mat[8]; - mat[3] = mat[12]; - mat[4] = a01; - mat[6] = mat[9]; - mat[7] = mat[13]; - mat[8] = a02; - mat[9] = a12; - mat[11] = mat[14]; - mat[12] = a03; - mat[13] = a13; - mat[14] = a23; - return mat; - } + mat[1] = mat[4]; + mat[2] = mat[8]; + mat[3] = mat[12]; + mat[4] = a01; + mat[6] = mat[9]; + mat[7] = mat[13]; + mat[8] = a02; + mat[9] = a12; + mat[11] = mat[14]; + mat[12] = a03; + mat[13] = a13; + mat[14] = a23; + return mat; + } - dest[0] = mat[0]; - dest[1] = mat[4]; - dest[2] = mat[8]; - dest[3] = mat[12]; - dest[4] = mat[1]; - dest[5] = mat[5]; - dest[6] = mat[9]; - dest[7] = mat[13]; - dest[8] = mat[2]; - dest[9] = mat[6]; - dest[10] = mat[10]; - dest[11] = mat[14]; - dest[12] = mat[3]; - dest[13] = mat[7]; - dest[14] = mat[11]; - dest[15] = mat[15]; - return dest; -} + dest[0] = mat[0]; + dest[1] = mat[4]; + dest[2] = mat[8]; + dest[3] = mat[12]; + dest[4] = mat[1]; + dest[5] = mat[5]; + dest[6] = mat[9]; + dest[7] = mat[13]; + dest[8] = mat[2]; + dest[9] = mat[6]; + dest[10] = mat[10]; + dest[11] = mat[14]; + dest[12] = mat[3]; + dest[13] = mat[7]; + dest[14] = mat[11]; + dest[15] = mat[15]; + return dest; +}; PIXI.mat4.multiply = function (mat, mat2, dest) { - if (!dest) { dest = mat; } + if (!dest) { dest = mat; } - // Cache the matrix values (makes for huge speed increases!) - var a00 = mat[ 0], a01 = mat[ 1], a02 = mat[ 2], a03 = mat[3]; - var a10 = mat[ 4], a11 = mat[ 5], a12 = mat[ 6], a13 = mat[7]; - var a20 = mat[ 8], a21 = mat[ 9], a22 = mat[10], a23 = mat[11]; - var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15]; + // Cache the matrix values (makes for huge speed increases!) + var a00 = mat[ 0], a01 = mat[ 1], a02 = mat[ 2], a03 = mat[3]; + var a10 = mat[ 4], a11 = mat[ 5], a12 = mat[ 6], a13 = mat[7]; + var a20 = mat[ 8], a21 = mat[ 9], a22 = mat[10], a23 = mat[11]; + var a30 = mat[12], a31 = mat[13], a32 = mat[14], a33 = mat[15]; - // Cache only the current line of the second matrix + // Cache only the current line of the second matrix var b0 = mat2[0], b1 = mat2[1], b2 = mat2[2], b3 = mat2[3]; dest[0] = b0*a00 + b1*a10 + b2*a20 + b3*a30; dest[1] = b0*a01 + b1*a11 + b2*a21 + b3*a31; @@ -671,7 +645,7 @@ PIXI.mat4.multiply = function (mat, mat2, dest) dest[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33; return dest; -} +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 @@ -687,20 +661,20 @@ PIXI.mat4.multiply = function (mat, mat2, dest) */ PIXI.Point = function(x, y) { - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; + /** + * @property x + * @type Number + * @default 0 + */ + this.x = x || 0; - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; -} + /** + * @property y + * @type Number + * @default 0 + */ + this.y = y || 0; +}; /** * Creates a clone of this point @@ -710,8 +684,8 @@ PIXI.Point = function(x, y) */ PIXI.Point.prototype.clone = function() { - return new PIXI.Point(this.x, this.y); -} + return new PIXI.Point(this.x, this.y); +}; // constructor PIXI.Point.prototype.constructor = PIXI.Point; @@ -733,34 +707,34 @@ PIXI.Point.prototype.constructor = PIXI.Point; */ PIXI.Rectangle = function(x, y, width, height) { - /** - * @property x - * @type Number - * @default 0 - */ - this.x = x || 0; + /** + * @property x + * @type Number + * @default 0 + */ + this.x = x || 0; - /** - * @property y - * @type Number - * @default 0 - */ - this.y = y || 0; + /** + * @property y + * @type Number + * @default 0 + */ + this.y = y || 0; - /** - * @property width - * @type Number - * @default 0 - */ - this.width = width || 0; + /** + * @property width + * @type Number + * @default 0 + */ + this.width = width || 0; - /** - * @property height - * @type Number - * @default 0 - */ - this.height = height || 0; -} + /** + * @property height + * @type Number + * @default 0 + */ + this.height = height || 0; +}; /** * Creates a clone of this Rectangle @@ -770,8 +744,8 @@ PIXI.Rectangle = function(x, y, width, height) */ PIXI.Rectangle.prototype.clone = function() { - return new PIXI.Rectangle(this.x, this.y, this.width, this.height); -} + return new PIXI.Rectangle(this.x, this.y, this.width, this.height); +}; /** * Checks if the x, and y coords passed to this function are contained within this Rectangle @@ -786,19 +760,19 @@ PIXI.Rectangle.prototype.contains = function(x, y) if(this.width <= 0 || this.height <= 0) return false; - var x1 = this.x; - if(x >= x1 && x <= x1 + this.width) - { - var y1 = this.y; + var x1 = this.x; + if(x >= x1 && x <= x1 + this.width) + { + var y1 = this.y; - if(y >= y1 && y <= y1 + this.height) - { - return true; - } - } + if(y >= y1 && y <= y1 + this.height) + { + return true; + } + } - return false; -} + return false; +}; // constructor PIXI.Rectangle.prototype.constructor = PIXI.Rectangle; @@ -835,8 +809,8 @@ PIXI.Polygon = function(points) points = p; } - this.points = points; -} + this.points = points; +}; /** * Creates a clone of this polygon @@ -846,13 +820,13 @@ PIXI.Polygon = function(points) */ PIXI.Polygon.prototype.clone = function() { - var points = []; - for (var i=0; i y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); + intersect = ((yi > y) !== (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi); if(intersect) inside = !inside; } return inside; -} +}; // constructor PIXI.Polygon.prototype.constructor = PIXI.Polygon; @@ -894,236 +868,238 @@ PIXI.Polygon.prototype.constructor = PIXI.Polygon; */ PIXI.DisplayObject = function() { - this.last = this; - this.first = this; - /** - * The coordinate of the object relative to the local coordinates of the parent. - * - * @property position - * @type Point - */ - this.position = new PIXI.Point(); + this.last = this; + this.first = this; + /** + * The coordinate of the object relative to the local coordinates of the parent. + * + * @property position + * @type Point + */ + this.position = new PIXI.Point(); - /** - * The scale factor of the object. - * - * @property scale - * @type Point - */ - this.scale = new PIXI.Point(1,1);//{x:1, y:1}; + /** + * The scale factor of the object. + * + * @property scale + * @type Point + */ + this.scale = new PIXI.Point(1,1);//{x:1, y:1}; - /** - * The pivot point of the displayObject that it rotates around - * - * @property pivot - * @type Point - */ - this.pivot = new PIXI.Point(0,0); + /** + * The pivot point of the displayObject that it rotates around + * + * @property pivot + * @type Point + */ + this.pivot = new PIXI.Point(0,0); - /** - * The rotation of the object in radians. - * - * @property rotation - * @type Number - */ - this.rotation = 0; + /** + * The rotation of the object in radians. + * + * @property rotation + * @type Number + */ + this.rotation = 0; - /** - * The opacity of the object. - * - * @property alpha - * @type Number - */ - this.alpha = 1; + /** + * The opacity of the object. + * + * @property alpha + * @type Number + */ + this.alpha = 1; - /** - * The visibility of the object. - * - * @property visible - * @type Boolean - */ - this.visible = true; + /** + * The visibility of the object. + * + * @property visible + * @type Boolean + */ + this.visible = true; - /** - * This is the defined area that will pick up mouse / touch events. It is null by default. - * Setting it is a neat way of optimising the hitTest function that the interactionManager will use (as it will not need to hit test all the children) - * - * @property hitArea - * @type Rectangle|Circle|Ellipse|Polygon - */ - this.hitArea = null; + /** + * This is the defined area that will pick up mouse / touch events. It is null by default. + * Setting it is a neat way of optimising the hitTest function that the interactionManager will use (as it will not need to hit test all the children) + * + * @property hitArea + * @type Rectangle|Circle|Ellipse|Polygon + */ + this.hitArea = null; - /** - * This is used to indicate if the displayObject should display a mouse hand cursor on rollover - * - * @property buttonMode - * @type Boolean - */ - this.buttonMode = false; + /** + * This is used to indicate if the displayObject should display a mouse hand cursor on rollover + * + * @property buttonMode + * @type Boolean + */ + this.buttonMode = false; - /** - * Can this object be rendered - * - * @property renderable - * @type Boolean - */ - this.renderable = false; + /** + * Can this object be rendered + * + * @property renderable + * @type Boolean + */ + this.renderable = false; - /** - * [read-only] The display object container that contains this display object. - * - * @property parent - * @type DisplayObjectContainer - * @readOnly - */ - this.parent = null; + /** + * [read-only] The display object container that contains this display object. + * + * @property parent + * @type DisplayObjectContainer + * @readOnly + */ + this.parent = null; - /** - * [read-only] The stage the display object is connected to, or undefined if it is not connected to the stage. - * - * @property stage - * @type Stage - * @readOnly - */ - this.stage = null; + /** + * [read-only] The stage the display object is connected to, or undefined if it is not connected to the stage. + * + * @property stage + * @type Stage + * @readOnly + */ + this.stage = null; - /** - * [read-only] The multiplied alpha of the displayobject - * - * @property worldAlpha - * @type Number - * @readOnly - */ - this.worldAlpha = 1; + /** + * [read-only] The multiplied alpha of the displayobject + * + * @property worldAlpha + * @type Number + * @readOnly + */ + this.worldAlpha = 1; - /** - * [read-only] Whether or not the object is interactive, do not toggle directly! use the `interactive` property - * - * @property _interactive - * @type Boolean - * @readOnly - * @private - */ - this._interactive = false; + /** + * [read-only] Whether or not the object is interactive, do not toggle directly! use the `interactive` property + * + * @property _interactive + * @type Boolean + * @readOnly + * @private + */ + this._interactive = false; - /** - * [read-only] Current transform of the object based on world (parent) factors - * - * @property worldTransform - * @type Mat3 - * @readOnly - * @private - */ - this.worldTransform = PIXI.mat3.create()//mat3.identity(); + this.defaultCursor = 'pointer'; - /** - * [read-only] Current transform of the object locally - * - * @property localTransform - * @type Mat3 - * @readOnly - * @private - */ - this.localTransform = PIXI.mat3.create()//mat3.identity(); + /** + * [read-only] Current transform of the object based on world (parent) factors + * + * @property worldTransform + * @type Mat3 + * @readOnly + * @private + */ + this.worldTransform = PIXI.mat3.create(); //mat3.identity(); - /** - * [NYI] Unkown - * - * @property color - * @type Array<> - * @private - */ - this.color = []; + /** + * [read-only] Current transform of the object locally + * + * @property localTransform + * @type Mat3 + * @readOnly + * @private + */ + this.localTransform = PIXI.mat3.create(); //mat3.identity(); - /** - * [NYI] Holds whether or not this object is dynamic, for rendering optimization - * - * @property dynamic - * @type Boolean - * @private - */ - this.dynamic = true; + /** + * [NYI] Unkown + * + * @property color + * @type Array<> + * @private + */ + this.color = []; - // chach that puppy! - this._sr = 0; - this._cr = 1; + /** + * [NYI] Holds whether or not this object is dynamic, for rendering optimization + * + * @property dynamic + * @type Boolean + * @private + */ + this.dynamic = true; + + // chach that puppy! + this._sr = 0; + this._cr = 1; - this.filterArea = new PIXI.Rectangle(0,0,1,1); - - /* - * MOUSE Callbacks - */ + this.filterArea = new PIXI.Rectangle(0,0,1,1); - /** - * A callback that is used when the users clicks on the displayObject with their mouse - * @method click - * @param interactionData {InteractionData} - */ + /* + * MOUSE Callbacks + */ - /** - * A callback that is used when the user clicks the mouse down over the sprite - * @method mousedown - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the users clicks on the displayObject with their mouse + * @method click + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the user releases the mouse that was over the displayObject - * for this callback to be fired the mouse must have been pressed down over the displayObject - * @method mouseup - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the user clicks the mouse down over the sprite + * @method mousedown + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the user releases the mouse that was over the displayObject but is no longer over the displayObject - * for this callback to be fired, The touch must have started over the displayObject - * @method mouseupoutside - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the user releases the mouse that was over the displayObject + * for this callback to be fired the mouse must have been pressed down over the displayObject + * @method mouseup + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the users mouse rolls over the displayObject - * @method mouseover - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the user releases the mouse that was over the displayObject but is no longer over the displayObject + * for this callback to be fired, The touch must have started over the displayObject + * @method mouseupoutside + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the users mouse leaves the displayObject - * @method mouseout - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the users mouse rolls over the displayObject + * @method mouseover + * @param interactionData {InteractionData} + */ + + /** + * A callback that is used when the users mouse leaves the displayObject + * @method mouseout + * @param interactionData {InteractionData} + */ - /* - * TOUCH Callbacks - */ + /* + * TOUCH Callbacks + */ - /** - * A callback that is used when the users taps on the sprite with their finger - * basically a touch version of click - * @method tap - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the users taps on the sprite with their finger + * basically a touch version of click + * @method tap + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the user touch's over the displayObject - * @method touchstart - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the user touch's over the displayObject + * @method touchstart + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the user releases a touch over the displayObject - * @method touchend - * @param interactionData {InteractionData} - */ + /** + * A callback that is used when the user releases a touch over the displayObject + * @method touchend + * @param interactionData {InteractionData} + */ - /** - * A callback that is used when the user releases the touch that was over the displayObject - * for this callback to be fired, The touch must have started over the sprite - * @method touchendoutside - * @param interactionData {InteractionData} - */ -} + /** + * A callback that is used when the user releases the touch that was over the displayObject + * for this callback to be fired, The touch must have started over the sprite + * @method touchendoutside + * @param interactionData {InteractionData} + */ +}; // constructor PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject; @@ -1138,8 +1114,8 @@ PIXI.DisplayObject.prototype.constructor = PIXI.DisplayObject; */ PIXI.DisplayObject.prototype.setInteractive = function(interactive) { - this.interactive = interactive; -} + this.interactive = interactive; +}; /** * Indicates if the sprite will have touch and mouse interactivity. It is false by default @@ -1153,11 +1129,11 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', { return this._interactive; }, set: function(value) { - this._interactive = value; - - // TODO more to be done here.. - // need to sort out a re-crawl! - if(this.stage)this.stage.dirty = true; + this._interactive = value; + + // TODO more to be done here.. + // need to sort out a re-crawl! + if(this.stage)this.stage.dirty = true; } }); @@ -1174,33 +1150,33 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', { return this._mask; }, set: function(value) { - - + + if(value) { - if(this._mask) - { - value.start = this._mask.start; - value.end = this._mask.end; - } - else - { - this.addFilter(value); - value.renderable = false; - } + if(this._mask) + { + value.start = this._mask.start; + value.end = this._mask.end; + } + else + { + this.addFilter(value); + value.renderable = false; + } } else { - this.removeFilter(this._mask); - this._mask.renderable = true; + this.removeFilter(this._mask); + this._mask.renderable = true; } - + this._mask = value; } }); /** - * Sets the filters for the displayObject. + * Sets the filters for the displayObject. * * IMPORTANT: This is a webGL only feature and will be ignored by the canvas renderer. * To remove filters simply set this property to 'null' * @property filters @@ -1211,35 +1187,33 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', { return this._filters; }, set: function(value) { - + if(value) { - if(this._filters)this.removeFilter(this._filters); - this.addFilter(value); + if(this._filters)this.removeFilter(this._filters); + this.addFilter(value); - // now put all the passes in one place.. - var passes = []; - for (var i = 0; i < value.length; i++) - { - var filterPasses = value[i].passes; - for (var j = 0; j < filterPasses.length; j++) - { - passes.push(filterPasses[j]); - }; - }; + // now put all the passes in one place.. + var passes = []; + for (var i = 0; i < value.length; i++) + { + var filterPasses = value[i].passes; + for (var j = 0; j < filterPasses.length; j++) + { + passes.push(filterPasses[j]); + } + } - value.start.filterPasses = passes; + value.start.filterPasses = passes; } else { - if(this._filters)this.removeFilter(this._filters); + if(this._filters) { + this.removeFilter(this._filters); + } } - + this._filters = value; - - - - } }); @@ -1252,97 +1226,99 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', { */ PIXI.DisplayObject.prototype.addFilter = function(data) { + //if(this.filter)return; + //this.filter = true; +// data[0].target = this; - // insert a filter block.. - // TODO Onject pool thease bad boys.. - var start = new PIXI.FilterBlock(); - var end = new PIXI.FilterBlock(); - - data.start = start; - data.end = end; - - start.data = data; - end.data = data; - - start.first = start.last = this; - end.first = end.last = this; - - start.open = true; - - start.target = this; - - /* - * insert start - */ - - var childFirst = start - var childLast = start - var nextObject; - var previousObject; - - previousObject = this.first._iPrev; - - if(previousObject) - { - nextObject = previousObject._iNext; - childFirst._iPrev = previousObject; - previousObject._iNext = childFirst; - } - else - { - nextObject = this; - } - - if(nextObject) - { - nextObject._iPrev = childLast; - childLast._iNext = nextObject; - } - - - // now insert the end filter block.. - - /* - * insert end filter - */ - var childFirst = end - var childLast = end - var nextObject = null; - var previousObject = null; - - previousObject = this.last; - nextObject = previousObject._iNext; - - if(nextObject) - { - nextObject._iPrev = childLast; - childLast._iNext = nextObject; - } - - childFirst._iPrev = previousObject; - previousObject._iNext = childFirst; - - var updateLast = this; - - var prevLast = this.last; - while(updateLast) - { - if(updateLast.last == prevLast) - { - updateLast.last = end; - } - updateLast = updateLast.parent; - } - - this.first = start; - - // if webGL... - if(this.__renderGroup) - { - this.__renderGroup.addFilterBlocks(start, end); - } - -} + + // insert a filter block.. + // TODO Onject pool thease bad boys.. + var start = new PIXI.FilterBlock(); + var end = new PIXI.FilterBlock(); + + data.start = start; + data.end = end; + + start.data = data; + end.data = data; + + start.first = start.last = this; + end.first = end.last = this; + + start.open = true; + + start.target = this; + + /* + * insert start + */ + + var childFirst = start; + var childLast = start; + var nextObject; + var previousObject; + + previousObject = this.first._iPrev; + + if(previousObject) + { + nextObject = previousObject._iNext; + childFirst._iPrev = previousObject; + previousObject._iNext = childFirst; + } + else + { + nextObject = this; + } + + if(nextObject) + { + nextObject._iPrev = childLast; + childLast._iNext = nextObject; + } + + // now insert the end filter block.. + + /* + * insert end filter + */ + childFirst = end; + childLast = end; + nextObject = null; + previousObject = null; + + previousObject = this.last; + nextObject = previousObject._iNext; + + if(nextObject) + { + nextObject._iPrev = childLast; + childLast._iNext = nextObject; + } + + childFirst._iPrev = previousObject; + previousObject._iNext = childFirst; + + var updateLast = this; + + var prevLast = this.last; + while(updateLast) + { + if(updateLast.last === prevLast) + { + updateLast.last = end; + } + updateLast = updateLast.parent; + } + + this.first = start; + + // if webGL... + if(this.__renderGroup) + { + this.__renderGroup.addFilterBlocks(start, end); + } +}; /* * Removes the filter to this displayObject @@ -1352,47 +1328,47 @@ PIXI.DisplayObject.prototype.addFilter = function(data) */ PIXI.DisplayObject.prototype.removeFilter = function(data) { - //if(!this.filter)return; - //this.filter = false; - console.log("YUOIO") - // modify the list.. - var startBlock = data.start; - - - var nextObject = startBlock._iNext; - var previousObject = startBlock._iPrev; - - if(nextObject)nextObject._iPrev = previousObject; - if(previousObject)previousObject._iNext = nextObject; - - this.first = startBlock._iNext; - - // remove the end filter - var lastBlock = data.end; - - var nextObject = lastBlock._iNext; - var previousObject = lastBlock._iPrev; - - if(nextObject)nextObject._iPrev = previousObject; - previousObject._iNext = nextObject; - - // this is always true too! - var tempLast = lastBlock._iPrev; - // need to make sure the parents last is updated too - var updateLast = this; - while(updateLast.last == lastBlock) - { - updateLast.last = tempLast; - updateLast = updateLast.parent; - if(!updateLast)break; - } - - // if webGL... - if(this.__renderGroup) - { - this.__renderGroup.removeFilterBlocks(startBlock, lastBlock); - } -} + //if(!this.filter)return; + //this.filter = false; + // console.log('YUOIO') + // modify the list.. + var startBlock = data.start; + + + var nextObject = startBlock._iNext; + var previousObject = startBlock._iPrev; + + if(nextObject)nextObject._iPrev = previousObject; + if(previousObject)previousObject._iNext = nextObject; + + this.first = startBlock._iNext; + + // remove the end filter + var lastBlock = data.end; + + nextObject = lastBlock._iNext; + previousObject = lastBlock._iPrev; + + if(nextObject)nextObject._iPrev = previousObject; + previousObject._iNext = nextObject; + + // this is always true too! + var tempLast = lastBlock._iPrev; + // need to make sure the parents last is updated too + var updateLast = this; + while(updateLast.last === lastBlock) + { + updateLast.last = tempLast; + updateLast = updateLast.parent; + if(!updateLast)break; + } + + // if webGL... + if(this.__renderGroup) + { + this.__renderGroup.removeFilterBlocks(startBlock, lastBlock); + } +}; /* * Updates the object transform for rendering @@ -1402,28 +1378,28 @@ PIXI.DisplayObject.prototype.removeFilter = function(data) */ PIXI.DisplayObject.prototype.updateTransform = function() { - // TODO OPTIMIZE THIS!! with dirty - if(this.rotation !== this.rotationCache) - { - this.rotationCache = this.rotation; - this._sr = Math.sin(this.rotation); - this._cr = Math.cos(this.rotation); - } - - var localTransform = this.localTransform; - var parentTransform = this.parent.worldTransform; - var worldTransform = this.worldTransform; - //console.log(localTransform) - localTransform[0] = this._cr * this.scale.x; - localTransform[1] = -this._sr * this.scale.y - localTransform[3] = this._sr * this.scale.x; - localTransform[4] = this._cr * this.scale.y; - - // TODO --> do we even need a local matrix??? - - var px = this.pivot.x; - var py = this.pivot.y; - + // TODO OPTIMIZE THIS!! with dirty + if(this.rotation !== this.rotationCache) + { + this.rotationCache = this.rotation; + this._sr = Math.sin(this.rotation); + this._cr = Math.cos(this.rotation); + } + + var localTransform = this.localTransform; + var parentTransform = this.parent.worldTransform; + var worldTransform = this.worldTransform; + //console.log(localTransform) + localTransform[0] = this._cr * this.scale.x; + localTransform[1] = -this._sr * this.scale.y; + localTransform[3] = this._sr * this.scale.x; + localTransform[4] = this._cr * this.scale.y; + + // TODO --> do we even need a local matrix??? + + var px = this.pivot.x; + var py = this.pivot.y; + // Cache the matrix values (makes for huge speed increases!) var a00 = localTransform[0], a01 = localTransform[1], a02 = this.position.x - localTransform[0] * px - py * localTransform[1], a10 = localTransform[3], a11 = localTransform[4], a12 = this.position.y - localTransform[4] * py - px * localTransform[3], @@ -1431,9 +1407,9 @@ PIXI.DisplayObject.prototype.updateTransform = function() b00 = parentTransform[0], b01 = parentTransform[1], b02 = parentTransform[2], b10 = parentTransform[3], b11 = parentTransform[4], b12 = parentTransform[5]; - localTransform[2] = a02 - localTransform[5] = a12 - + localTransform[2] = a02; + localTransform[5] = a12; + worldTransform[0] = b00 * a00 + b01 * a10; worldTransform[1] = b00 * a01 + b01 * a11; worldTransform[2] = b00 * a02 + b01 * a12 + b02; @@ -1442,13 +1418,12 @@ PIXI.DisplayObject.prototype.updateTransform = function() worldTransform[4] = b10 * a01 + b11 * a11; worldTransform[5] = b10 * a02 + b11 * a12 + b12; - // because we are using affine transformation, we can optimise the matrix concatenation process.. wooo! - // mat3.multiply(this.localTransform, this.parent.worldTransform, this.worldTransform); - this.worldAlpha = this.alpha * this.parent.worldAlpha; - - this.vcount = PIXI.visibleCount; + // because we are using affine transformation, we can optimise the matrix concatenation process.. wooo! + // mat3.multiply(this.localTransform, this.parent.worldTransform, this.worldTransform); + this.worldAlpha = this.alpha * this.parent.worldAlpha; -} + this.vcount = PIXI.visibleCount; +}; PIXI.visibleCount = 0; /** @@ -1460,23 +1435,23 @@ PIXI.visibleCount = 0; * A DisplayObjectContainer represents a collection of display objects. * It is the base class of all display objects that act as a container for other objects. * - * @class DisplayObjectContainer + * @class DisplayObjectContainer * @extends DisplayObject * @constructor */ PIXI.DisplayObjectContainer = function() { - PIXI.DisplayObject.call( this ); - - /** - * [read-only] The of children of this container. - * - * @property children - * @type Array - * @readOnly - */ - this.children = []; -} + PIXI.DisplayObject.call( this ); + + /** + * [read-only] The of children of this container. + * + * @property children + * @type Array + * @readOnly + */ + this.children = []; +}; // constructor PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype ); @@ -1490,85 +1465,83 @@ PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer; */ PIXI.DisplayObjectContainer.prototype.addChild = function(child) { - if(child.parent != undefined) - { - - //// COULD BE THIS??? - child.parent.removeChild(child); - // return; - } + if(child.parent && child.parent !== this) + { + //// COULD BE THIS??? + child.parent.removeChild(child); + // return; + } - child.parent = this; - - this.children.push(child); - - // update the stage refference.. - - if(this.stage) - { - var tmpChild = child; - do - { - if(tmpChild.interactive)this.stage.dirty = true; - tmpChild.stage = this.stage; - tmpChild = tmpChild._iNext; - } - while(tmpChild) - } - - // LINKED LIST // - - // modify the list.. - var childFirst = child.first - var childLast = child.last; - var nextObject; - var previousObject; - - // this could be wrong if there is a filter?? - if(this._filters || this._mask) - { - previousObject = this.last._iPrev; - } - else - { - previousObject = this.last; - } + child.parent = this; - nextObject = previousObject._iNext; - - // always true in this case - // need to make sure the parents last is updated too - var updateLast = this; - var prevLast = previousObject; - - while(updateLast) - { - if(updateLast.last == prevLast) - { - updateLast.last = child.last; - } - updateLast = updateLast.parent; - } - - if(nextObject) - { - nextObject._iPrev = childLast; - childLast._iNext = nextObject; - } - - childFirst._iPrev = previousObject; - previousObject._iNext = childFirst; + this.children.push(child); - // need to remove any render groups.. - if(this.__renderGroup) - { - // being used by a renderTexture.. if it exists then it must be from a render texture; - if(child.__renderGroup)child.__renderGroup.removeDisplayObjectAndChildren(child); - // add them to the new render group.. - this.__renderGroup.addDisplayObjectAndChildren(child); - } - -} + // update the stage refference.. + + if(this.stage) + { + var tmpChild = child; + do + { + if(tmpChild.interactive)this.stage.dirty = true; + tmpChild.stage = this.stage; + tmpChild = tmpChild._iNext; + } + while(tmpChild); + } + + // LINKED LIST // + + // modify the list.. + var childFirst = child.first; + var childLast = child.last; + var nextObject; + var previousObject; + + // this could be wrong if there is a filter?? + if(this._filters || this._mask) + { + previousObject = this.last._iPrev; + } + else + { + previousObject = this.last; + } + + nextObject = previousObject._iNext; + + // always true in this case + // need to make sure the parents last is updated too + var updateLast = this; + var prevLast = previousObject; + + while(updateLast) + { + if(updateLast.last === prevLast) + { + updateLast.last = child.last; + } + updateLast = updateLast.parent; + } + + if(nextObject) + { + nextObject._iPrev = childLast; + childLast._iNext = nextObject; + } + + childFirst._iPrev = previousObject; + previousObject._iNext = childFirst; + + // need to remove any render groups.. + if(this.__renderGroup) + { + // being used by a renderTexture.. if it exists then it must be from a render texture; + if(child.__renderGroup)child.__renderGroup.removeDisplayObjectAndChildren(child); + // add them to the new render group.. + this.__renderGroup.addDisplayObjectAndChildren(child); + } +}; /** * Adds a child to the container at a specified index. If the index is out of bounds an error will be thrown @@ -1579,83 +1552,84 @@ PIXI.DisplayObjectContainer.prototype.addChild = function(child) */ PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index) { - if(index >= 0 && index <= this.children.length) - { - if(child.parent != undefined) - { - child.parent.removeChild(child); - } - child.parent = this; - - if(this.stage) - { - var tmpChild = child; - do - { - if(tmpChild.interactive)this.stage.dirty = true; - tmpChild.stage = this.stage; - tmpChild = tmpChild._iNext; - } - while(tmpChild) - } - - // modify the list.. - var childFirst = child.first; - var childLast = child.last; - var nextObject; - var previousObject; - - if(index == this.children.length) - { - previousObject = this.last; - var updateLast = this; - var prevLast = this.last; - while(updateLast) - { - if(updateLast.last == prevLast) - { - updateLast.last = child.last; - } - updateLast = updateLast.parent; - } - } - else if(index === 0) - { - previousObject = this; - } - else - { - previousObject = this.children[index-1].last; - } - - nextObject = previousObject._iNext; - - // always true in this case - if(nextObject) - { - nextObject._iPrev = childLast; - childLast._iNext = nextObject; - } - - childFirst._iPrev = previousObject; - previousObject._iNext = childFirst; + if(index >= 0 && index <= this.children.length) + { + if(child.parent !== undefined) + { + child.parent.removeChild(child); + } - this.children.splice(index, 0, child); - // need to remove any render groups.. - if(this.__renderGroup) - { - // being used by a renderTexture.. if it exists then it must be from a render texture; - if(child.__renderGroup)child.__renderGroup.removeDisplayObjectAndChildren(child); - // add them to the new render group.. - this.__renderGroup.addDisplayObjectAndChildren(child); - } - - } - else - { - throw new Error(child + " The index "+ index +" supplied is out of bounds " + this.children.length); - } -} + child.parent = this; + + if(this.stage) + { + var tmpChild = child; + do + { + if(tmpChild.interactive)this.stage.dirty = true; + tmpChild.stage = this.stage; + tmpChild = tmpChild._iNext; + } + while(tmpChild); + } + + // modify the list.. + var childFirst = child.first; + var childLast = child.last; + var nextObject; + var previousObject; + + if(index === this.children.length) + { + previousObject = this.last; + var updateLast = this; + var prevLast = this.last; + while(updateLast) + { + if(updateLast.last === prevLast) + { + updateLast.last = child.last; + } + updateLast = updateLast.parent; + } + } + else if(index === 0) + { + previousObject = this; + } + else + { + previousObject = this.children[index-1].last; + } + + nextObject = previousObject._iNext; + + // always true in this case + if(nextObject) + { + nextObject._iPrev = childLast; + childLast._iNext = nextObject; + } + + childFirst._iPrev = previousObject; + previousObject._iNext = childFirst; + + this.children.splice(index, 0, child); + // need to remove any render groups.. + if(this.__renderGroup) + { + // being used by a renderTexture.. if it exists then it must be from a render texture; + if(child.__renderGroup)child.__renderGroup.removeDisplayObjectAndChildren(child); + // add them to the new render group.. + this.__renderGroup.addDisplayObjectAndChildren(child); + } + + } + else + { + throw new Error(child + ' The index '+ index +' supplied is out of bounds ' + this.children.length); + } +}; /** * [NYI] Swaps the depth of 2 displayObjects @@ -1667,44 +1641,31 @@ PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index) */ PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2) { - /* - * this funtion needs to be recoded.. - * can be done a lot faster.. - */ - return; - - // need to fix this function :/ - /* - // TODO I already know this?? - var index = this.children.indexOf( child ); - var index2 = this.children.indexOf( child2 ); - - if ( index !== -1 && index2 !== -1 ) - { - // cool - - /* - if(this.stage) - { - // this is to satisfy the webGL batching.. - // TODO sure there is a nicer way to achieve this! - this.stage.__removeChild(child); - this.stage.__removeChild(child2); - - this.stage.__addChild(child); - this.stage.__addChild(child2); - } - - // swap the positions.. - this.children[index] = child2; - this.children[index2] = child; - - } - else - { - throw new Error(child + " Both the supplied DisplayObjects must be a child of the caller " + this); - }*/ -} + if(child === child2) { + return; + } + + var index1 = this.children.indexOf(child); + var index2 = this.children.indexOf(child2); + + if(index1 < 0 || index2 < 0) { + throw new Error('swapChildren: Both the supplied DisplayObjects must be a child of the caller.'); + } + + this.removeChild(child); + this.removeChild(child2); + + if(index1 < index2) + { + this.addChildAt(child2, index1); + this.addChildAt(child, index2); + } + else + { + this.addChildAt(child, index2); + this.addChildAt(child2, index1); + } +}; /** * Returns the Child at the specified index @@ -1714,15 +1675,15 @@ PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2) */ PIXI.DisplayObjectContainer.prototype.getChildAt = function(index) { - if(index >= 0 && index < this.children.length) - { - return this.children[index]; - } - else - { - throw new Error(child + " Both the supplied DisplayObjects must be a child of the caller " + this); - } -} + if(index >= 0 && index < this.children.length) + { + return this.children[index]; + } + else + { + throw new Error('Both the supplied DisplayObjects must be a child of the caller ' + this); + } +}; /** * Removes a child from the container. @@ -1732,63 +1693,65 @@ PIXI.DisplayObjectContainer.prototype.getChildAt = function(index) */ PIXI.DisplayObjectContainer.prototype.removeChild = function(child) { - var index = this.children.indexOf( child ); - if ( index !== -1 ) - { - // unlink // - // modify the list.. - var childFirst = child.first; - var childLast = child.last; - - var nextObject = childLast._iNext; - var previousObject = childFirst._iPrev; - - if(nextObject)nextObject._iPrev = previousObject; - previousObject._iNext = nextObject; - - if(this.last == childLast) - { - var tempLast = childFirst._iPrev; - // need to make sure the parents last is updated too - var updateLast = this; - while(updateLast.last == childLast.last) - { - updateLast.last = tempLast; - updateLast = updateLast.parent; - if(!updateLast)break; - } - } - - childLast._iNext = null; - childFirst._iPrev = null; - - // update the stage reference.. - if(this.stage) - { - var tmpChild = child; - do - { - if(tmpChild.interactive)this.stage.dirty = true; - tmpChild.stage = null; - tmpChild = tmpChild._iNext; - } - while(tmpChild) - } - - // webGL trim - if(child.__renderGroup) - { - child.__renderGroup.removeDisplayObjectAndChildren(child); - } - - child.parent = undefined; - this.children.splice( index, 1 ); - } - else - { - throw new Error(child + " The supplied DisplayObject must be a child of the caller " + this); - } -} + var index = this.children.indexOf( child ); + if ( index !== -1 ) + { + // unlink // + // modify the list.. + var childFirst = child.first; + var childLast = child.last; + + var nextObject = childLast._iNext; + var previousObject = childFirst._iPrev; + + if(nextObject)nextObject._iPrev = previousObject; + previousObject._iNext = nextObject; + + if(this.last === childLast) + { + var tempLast = childFirst._iPrev; + // need to make sure the parents last is updated too + var updateLast = this; + + while(updateLast.last === childLast) + { + updateLast.last = tempLast; + updateLast = updateLast.parent; + if(!updateLast)break; + + } + } + + childLast._iNext = null; + childFirst._iPrev = null; + + // update the stage reference.. + if(this.stage) + { + var tmpChild = child; + do + { + if(tmpChild.interactive)this.stage.dirty = true; + tmpChild.stage = null; + tmpChild = tmpChild._iNext; + } + while(tmpChild); + } + + // webGL trim + if(child.__renderGroup) + { + child.__renderGroup.removeDisplayObjectAndChildren(child); + } + + child.parent = undefined; + this.children.splice( index, 1 ); + } + else + { + throw new Error(child + ' The supplied DisplayObject must be a child of the caller ' + this); + } +}; /* * Updates the container's children's transform for rendering @@ -1798,15 +1761,16 @@ PIXI.DisplayObjectContainer.prototype.removeChild = function(child) */ PIXI.DisplayObjectContainer.prototype.updateTransform = function() { - if(!this.visible)return; - - PIXI.DisplayObject.prototype.updateTransform.call( this ); - - for(var i=0,j=this.children.length; i 1) ratio = 1; - var ratio = (1 - (i / (total-1))) * 10; - if(ratio > 1)ratio = 1; + perpLength = Math.sqrt(perp.x * perp.x + perp.y * perp.y); + num = this.texture.height / 2; //(20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio; + perp.x /= perpLength; + perp.y /= perpLength; - var perpLength = Math.sqrt(perp.x * perp.x + perp.y * perp.y); - var num = this.texture.height/2//(20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio; - perp.x /= perpLength; - perp.y /= perpLength; + perp.x *= num; + perp.y *= num; - perp.x *= num; - perp.y *= num; + verticies[index] = point.x + perp.x; + verticies[index+1] = point.y + perp.y; + verticies[index+2] = point.x - perp.x; + verticies[index+3] = point.y - perp.y; - verticies[index] = point.x + perp.x - verticies[index+1] = point.y + perp.y - verticies[index+2] = point.x - perp.x - verticies[index+3] = point.y - perp.y + lastPoint = point; + } - lastPoint = point; - } - - PIXI.DisplayObjectContainer.prototype.updateTransform.call( this ); -} + PIXI.DisplayObjectContainer.prototype.updateTransform.call( this ); +}; PIXI.Rope.prototype.setTexture = function(texture) { - // stop current texture - this.texture = texture; - this.updateFrame = true; -} - - - - + // stop current texture + this.texture = texture; + this.updateFrame = true; +}; /** * @author Mat Groves http://matgroves.com/ @@ -2479,52 +2434,52 @@ PIXI.Rope.prototype.setTexture = function(texture) */ PIXI.TilingSprite = function(texture, width, height) { - PIXI.DisplayObjectContainer.call( this ); + PIXI.DisplayObjectContainer.call( this ); - /** - * The texture that the sprite is using - * - * @property texture - * @type Texture - */ - this.texture = texture; + /** + * The texture that the sprite is using + * + * @property texture + * @type Texture + */ + this.texture = texture; - /** - * The width of the tiling sprite - * - * @property width - * @type Number - */ - this.width = width; + /** + * The width of the tiling sprite + * + * @property width + * @type Number + */ + this.width = width; - /** - * The height of the tiling sprite - * - * @property height - * @type Number - */ - this.height = height; + /** + * The height of the tiling sprite + * + * @property height + * @type Number + */ + this.height = height; - /** - * The scaling of the image that is being tiled - * - * @property tileScale - * @type Point - */ - this.tileScale = new PIXI.Point(1,1); + /** + * The scaling of the image that is being tiled + * + * @property tileScale + * @type Point + */ + this.tileScale = new PIXI.Point(1,1); - /** - * The offset position of the image that is being tiled - * - * @property tilePosition - * @type Point - */ - this.tilePosition = new PIXI.Point(0,0); + /** + * The offset position of the image that is being tiled + * + * @property tilePosition + * @type Point + */ + this.tilePosition = new PIXI.Point(0,0); - this.renderable = true; + this.renderable = true; - this.blendMode = PIXI.blendModes.NORMAL -} + this.blendMode = PIXI.blendModes.NORMAL; +}; // constructor PIXI.TilingSprite.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); @@ -2538,13 +2493,13 @@ PIXI.TilingSprite.prototype.constructor = PIXI.TilingSprite; */ PIXI.TilingSprite.prototype.setTexture = function(texture) { - //TODO SET THE TEXTURES - //TODO VISIBILITY + //TODO SET THE TEXTURES + //TODO VISIBILITY - // stop current texture - this.texture = texture; - this.updateFrame = true; -} + // stop current texture + this.texture = texture; + this.updateFrame = true; +}; /** * When the texture is updated, this event will fire to update the frame @@ -2553,49 +2508,46 @@ PIXI.TilingSprite.prototype.setTexture = function(texture) * @param event * @private */ -PIXI.TilingSprite.prototype.onTextureUpdate = function(event) +PIXI.TilingSprite.prototype.onTextureUpdate = function() { - this.updateFrame = true; -} - + this.updateFrame = true; +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ - /** * This is the base class for creating a pixi.js filter. Currently only webGL supports filters. * If you want to make a custom filter this should be your base class. * @class AbstractFilter * @constructor * @param fragmentSrc - * @param uniforms + * @param uniforms */ PIXI.AbstractFilter = function(fragmentSrc, uniforms) { - /** - * An array of passes - some filters contain a few steps this array simply stores the steps in a liniear fashion. - * For example the blur filter has two passes blurX and blurY. - * @property passes - * @type Array an array of filter objects - * @private - */ - this.passes = [this]; + /** + * An array of passes - some filters contain a few steps this array simply stores the steps in a liniear fashion. + * For example the blur filter has two passes blurX and blurY. + * @property passes + * @type Array an array of filter objects + * @private + */ + this.passes = [this]; - this.dirty = true; - this.padding = 0; + this.dirty = true; + this.padding = 0; - /** - @property uniforms - @private - */ - this.uniforms = uniforms || {}; - - this.fragmentSrc = fragmentSrc || []; -} + /** + @property uniforms + @private + */ + this.uniforms = uniforms || {}; + this.fragmentSrc = fragmentSrc || []; +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 @@ -2605,9 +2557,10 @@ PIXI.AbstractFilter = function(fragmentSrc, uniforms) PIXI.FilterBlock = function() { - this.visible = true; - this.renderable = true; -} + this.visible = true; + this.renderable = true; +}; + /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -2624,52 +2577,52 @@ PIXI.FilterBlock = function() */ PIXI.Graphics = function() { - PIXI.DisplayObjectContainer.call( this ); + PIXI.DisplayObjectContainer.call( this ); - this.renderable = true; + this.renderable = true; /** - * The alpha of the fill of this graphics object - * - * @property fillAlpha - * @type Number - */ - this.fillAlpha = 1; + * The alpha of the fill of this graphics object + * + * @property fillAlpha + * @type Number + */ + this.fillAlpha = 1; /** - * The width of any lines drawn - * - * @property lineWidth - * @type Number - */ - this.lineWidth = 0; + * The width of any lines drawn + * + * @property lineWidth + * @type Number + */ + this.lineWidth = 0; /** - * The color of any lines drawn - * - * @property lineColor - * @type String - */ - this.lineColor = "black"; + * The color of any lines drawn + * + * @property lineColor + * @type String + */ + this.lineColor = "black"; /** - * Graphics data - * - * @property graphicsData - * @type Array - * @private - */ - this.graphicsData = []; + * Graphics data + * + * @property graphicsData + * @type Array + * @private + */ + this.graphicsData = []; /** - * Current path - * - * @property currentPath - * @type Object - * @private - */ - this.currentPath = {points:[]}; -} + * Current path + * + * @property currentPath + * @type Object + * @private + */ + this.currentPath = {points:[]}; +}; // constructor PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype ); @@ -2685,17 +2638,17 @@ PIXI.Graphics.prototype.constructor = PIXI.Graphics; */ PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha) { - if(this.currentPath.points.length === 0)this.graphicsData.pop(); + if (!this.currentPath.points.length) this.graphicsData.pop(); - this.lineWidth = lineWidth || 0; - this.lineColor = color || 0; - this.lineAlpha = (alpha == undefined) ? 1 : alpha; + this.lineWidth = lineWidth || 0; + this.lineColor = color || 0; + this.lineAlpha = (arguments.length < 3) ? 1 : alpha; - this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY}; + this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY}; - this.graphicsData.push(this.currentPath); -} + this.graphicsData.push(this.currentPath); +}; /** * Moves the current drawing position to (x, y). @@ -2706,15 +2659,15 @@ PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha) */ PIXI.Graphics.prototype.moveTo = function(x, y) { - if(this.currentPath.points.length === 0)this.graphicsData.pop(); + if (!this.currentPath.points.length) this.graphicsData.pop(); - this.currentPath = this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY}; + this.currentPath = this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY}; - this.currentPath.points.push(x, y); + this.currentPath.points.push(x, y); - this.graphicsData.push(this.currentPath); -} + this.graphicsData.push(this.currentPath); +}; /** * Draws a line using the current line style from the current drawing position to (x, y); @@ -2726,9 +2679,9 @@ PIXI.Graphics.prototype.moveTo = function(x, y) */ PIXI.Graphics.prototype.lineTo = function(x, y) { - this.currentPath.points.push(x, y); - this.dirty = true; -} + this.currentPath.points.push(x, y); + this.dirty = true; +}; /** * Specifies a simple one-color fill that subsequent calls to other Graphics methods @@ -2740,10 +2693,10 @@ PIXI.Graphics.prototype.lineTo = function(x, y) */ PIXI.Graphics.prototype.beginFill = function(color, alpha) { - this.filling = true; - this.fillColor = color || 0; - this.fillAlpha = (alpha == undefined) ? 1 : alpha; -} + this.filling = true; + this.fillColor = color || 0; + this.fillAlpha = (arguments.length < 2) ? 1 : alpha; +}; /** * Applies a fill to the lines and shapes that were added since the last call to the beginFill() method. @@ -2752,10 +2705,10 @@ PIXI.Graphics.prototype.beginFill = function(color, alpha) */ PIXI.Graphics.prototype.endFill = function() { - this.filling = false; - this.fillColor = null; - this.fillAlpha = 1; -} + this.filling = false; + this.fillColor = null; + this.fillAlpha = 1; +}; /** * @method drawRect @@ -2767,15 +2720,15 @@ PIXI.Graphics.prototype.endFill = function() */ PIXI.Graphics.prototype.drawRect = function( x, y, width, height ) { - if(this.currentPath.points.length === 0)this.graphicsData.pop(); + if (!this.currentPath.points.length) this.graphicsData.pop(); - this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, - points:[x, y, width, height], type:PIXI.Graphics.RECT}; + this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, + points:[x, y, width, height], type:PIXI.Graphics.RECT}; - this.graphicsData.push(this.currentPath); - this.dirty = true; -} + this.graphicsData.push(this.currentPath); + this.dirty = true; +}; /** * Draws a circle. @@ -2787,36 +2740,36 @@ PIXI.Graphics.prototype.drawRect = function( x, y, width, height ) */ PIXI.Graphics.prototype.drawCircle = function( x, y, radius) { - if(this.currentPath.points.length === 0)this.graphicsData.pop(); + if (!this.currentPath.points.length) this.graphicsData.pop(); - this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, - points:[x, y, radius, radius], type:PIXI.Graphics.CIRC}; + this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, + points:[x, y, radius, radius], type:PIXI.Graphics.CIRC}; - this.graphicsData.push(this.currentPath); - this.dirty = true; -} + this.graphicsData.push(this.currentPath); + this.dirty = true; +}; /** - * Draws an elipse. + * Draws an ellipse. * - * @method drawElipse + * @method drawEllipse * @param x {Number} * @param y {Number} * @param width {Number} * @param height {Number} */ -PIXI.Graphics.prototype.drawElipse = function( x, y, width, height) +PIXI.Graphics.prototype.drawEllipse = function( x, y, width, height) { - if(this.currentPath.points.length === 0)this.graphicsData.pop(); + if (!this.currentPath.points.length) this.graphicsData.pop(); - this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, - fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, - points:[x, y, width, height], type:PIXI.Graphics.ELIP}; + this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha, + fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, + points:[x, y, width, height], type:PIXI.Graphics.ELIP}; - this.graphicsData.push(this.currentPath); - this.dirty = true; -} + this.graphicsData.push(this.currentPath); + this.dirty = true; +}; /** * Clears the graphics that were drawn to this Graphics object, and resets fill and line style settings. @@ -2825,88 +2778,83 @@ PIXI.Graphics.prototype.drawElipse = function( x, y, width, height) */ PIXI.Graphics.prototype.clear = function() { - this.lineWidth = 0; - this.filling = false; + this.lineWidth = 0; + this.filling = false; - this.dirty = true; - this.clearDirty = true; - this.graphicsData = []; + this.dirty = true; + this.clearDirty = true; + this.graphicsData = []; - this.bounds = null//new PIXI.Rectangle(); -} + this.bounds = null; //new PIXI.Rectangle(); +}; PIXI.Graphics.prototype.updateFilterBounds = function() { - if(!this.bounds) - { - var minX = Infinity; - var maxX = -Infinity; + if(!this.bounds) + { + var minX = Infinity; + var maxX = -Infinity; - var minY = Infinity; - var maxY = -Infinity; + var minY = Infinity; + var maxY = -Infinity; - var points, x, y; + var points, x, y; - for (var i = 0; i < this.graphicsData.length; i++) { - + for (var i = 0; i < this.graphicsData.length; i++) { + var data = this.graphicsData[i]; + var type = data.type; + var lineWidth = data.lineWidth; - var data = this.graphicsData[i]; - var type = data.type; - var lineWidth = data.lineWidth; + points = data.points; - points = data.points; + if(type === PIXI.Graphics.RECT) + { + x = points.x - lineWidth/2; + y = points.y - lineWidth/2; + var width = points.width + lineWidth; + var height = points.height + lineWidth; - if(type === PIXI.Graphics.RECT) - { - x = points.x - lineWidth/2; - y = points.y - lineWidth/2; - var width = points.width + lineWidth; - var height = points.height + lineWidth; + minX = x < minX ? x : minX; + maxX = x + width > maxX ? x + width : maxX; - minX = x < minX ? x : minX; - maxX = x + width > maxX ? x + width : maxX; + minY = y < minY ? x : minY; + maxY = y + height > maxY ? y + height : maxY; + } + else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) + { + x = points.x; + y = points.y; + var radius = points.radius + lineWidth/2; - minY = y < minY ? x : minY; - maxY = y + height > maxY ? y + height : maxY; - } - else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP) - { - x = points.x; - y = points.y; - var radius = points.radius + lineWidth/2; - - minX = x - radius < minX ? x - radius : minX; - maxX = x + radius > maxX ? x + radius : maxX; + minX = x - radius < minX ? x - radius : minX; + maxX = x + radius > maxX ? x + radius : maxX; - minY = y - radius < minY ? y - radius : minY; - maxY = y + radius > maxY ? y + radius : maxY; - } - else - { - // POLY - for (var j = 0; j < points.length; j+=2) - { - - x = points[j]; - y = points[j+1]; + minY = y - radius < minY ? y - radius : minY; + maxY = y + radius > maxY ? y + radius : maxY; + } + else + { + // POLY + for (var j = 0; j < points.length; j+=2) + { - minX = x-lineWidth < minX ? x-lineWidth : minX; - maxX = x+lineWidth > maxX ? x+lineWidth : maxX; + x = points[j]; + y = points[j+1]; - minY = y-lineWidth < minY ? y-lineWidth : minY; - maxY = y+lineWidth > maxY ? y+lineWidth : maxY; - }; - } + minX = x-lineWidth < minX ? x-lineWidth : minX; + maxX = x+lineWidth > maxX ? x+lineWidth : maxX; - }; + minY = y-lineWidth < minY ? y-lineWidth : minY; + maxY = y+lineWidth > maxY ? y+lineWidth : maxY; + } + } + } - this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); - - } - -// console.log(this.bounds); -} + this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY); + } +// console.log(this.bounds); +}; // SOME TYPES: PIXI.Graphics.POLY = 0; @@ -2927,7 +2875,7 @@ PIXI.Graphics.ELIP = 3; PIXI.CanvasGraphics = function() { -} +}; /* @@ -2941,128 +2889,128 @@ PIXI.CanvasGraphics = function() */ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) { - var worldAlpha = graphics.worldAlpha; + var worldAlpha = graphics.worldAlpha; + var color = ''; - for (var i=0; i < graphics.graphicsData.length; i++) - { - var data = graphics.graphicsData[i]; - var points = data.points; + for (var i = 0; i < graphics.graphicsData.length; i++) + { + var data = graphics.graphicsData[i]; + var points = data.points; - context.strokeStyle = color = '#' + ('00000' + ( data.lineColor | 0).toString(16)).substr(-6); + context.strokeStyle = color = '#' + ('00000' + ( data.lineColor | 0).toString(16)).substr(-6); - context.lineWidth = data.lineWidth; + context.lineWidth = data.lineWidth; - if(data.type == PIXI.Graphics.POLY) - { - context.beginPath(); + if(data.type === PIXI.Graphics.POLY) + { + context.beginPath(); - context.moveTo(points[0], points[1]); + context.moveTo(points[0], points[1]); - for (var j=1; j < points.length/2; j++) - { - context.lineTo(points[j * 2], points[j * 2 + 1]); - } + for (var j=1; j < points.length/2; j++) + { + context.lineTo(points[j * 2], points[j * 2 + 1]); + } - // if the first and last point are the same close the path - much neater :) - if(points[0] == points[points.length-2] && points[1] == points[points.length-1]) - { - context.closePath(); - } + // if the first and last point are the same close the path - much neater :) + if(points[0] === points[points.length-2] && points[1] === points[points.length-1]) + { + context.closePath(); + } - if(data.fill) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); - context.fill(); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.stroke(); - } - } - else if(data.type == PIXI.Graphics.RECT) - { + if(data.fill) + { + context.globalAlpha = data.fillAlpha * worldAlpha; + context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); + context.fill(); + } + if(data.lineWidth) + { + context.globalAlpha = data.lineAlpha * worldAlpha; + context.stroke(); + } + } + else if(data.type === PIXI.Graphics.RECT) + { - if(data.fillColor || data.fillColor === 0) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); - context.fillRect(points[0], points[1], points[2], points[3]); + if(data.fillColor || data.fillColor === 0) + { + context.globalAlpha = data.fillAlpha * worldAlpha; + context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); + context.fillRect(points[0], points[1], points[2], points[3]); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.strokeRect(points[0], points[1], points[2], points[3]); - } + } + if(data.lineWidth) + { + context.globalAlpha = data.lineAlpha * worldAlpha; + context.strokeRect(points[0], points[1], points[2], points[3]); + } - } - else if(data.type == PIXI.Graphics.CIRC) - { - // TODO - need to be Undefined! - context.beginPath(); - context.arc(points[0], points[1], points[2],0,2*Math.PI); - context.closePath(); + } + else if(data.type === PIXI.Graphics.CIRC) + { + // TODO - need to be Undefined! + context.beginPath(); + context.arc(points[0], points[1], points[2],0,2*Math.PI); + context.closePath(); - if(data.fill) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); - context.fill(); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.stroke(); - } - } - else if(data.type == PIXI.Graphics.ELIP) - { + if(data.fill) + { + context.globalAlpha = data.fillAlpha * worldAlpha; + context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); + context.fill(); + } + if(data.lineWidth) + { + context.globalAlpha = data.lineAlpha * worldAlpha; + context.stroke(); + } + } + else if(data.type === PIXI.Graphics.ELIP) + { - // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas + // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas - var elipseData = data.points; + var ellipseData = data.points; - var w = elipseData[2] * 2; - var h = elipseData[3] * 2; + var w = ellipseData[2] * 2; + var h = ellipseData[3] * 2; - var x = elipseData[0] - w/2; - var y = elipseData[1] - h/2; + var x = ellipseData[0] - w/2; + var y = ellipseData[1] - h/2; - context.beginPath(); + context.beginPath(); - var kappa = .5522848, - ox = (w / 2) * kappa, // control point offset horizontal - oy = (h / 2) * kappa, // control point offset vertical - xe = x + w, // x-end - ye = y + h, // y-end - xm = x + w / 2, // x-middle - ym = y + h / 2; // y-middle + var kappa = 0.5522848, + ox = (w / 2) * kappa, // control point offset horizontal + oy = (h / 2) * kappa, // control point offset vertical + xe = x + w, // x-end + ye = y + h, // y-end + xm = x + w / 2, // x-middle + ym = y + h / 2; // y-middle - context.moveTo(x, ym); - context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); - context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); - context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); - context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); + context.moveTo(x, ym); + context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); + context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); + context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); + context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); - context.closePath(); + context.closePath(); - if(data.fill) - { - context.globalAlpha = data.fillAlpha * worldAlpha; - context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); - context.fill(); - } - if(data.lineWidth) - { - context.globalAlpha = data.lineAlpha * worldAlpha; - context.stroke(); - } - } - - }; -} + if(data.fill) + { + context.globalAlpha = data.fillAlpha * worldAlpha; + context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6); + context.fill(); + } + if(data.lineWidth) + { + context.globalAlpha = data.lineAlpha * worldAlpha; + context.stroke(); + } + } + } +}; /* * Renders a graphics mask @@ -3075,91 +3023,87 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context) */ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context) { - var worldAlpha = graphics.worldAlpha; + var len = graphics.graphicsData.length; - var len = graphics.graphicsData.length; - if(len === 0)return; + if(len === 0) return; - if(len > 1) - { - len = 1; - console.log("Pixi.js warning: masks in canvas can only mask using the first path in the graphics object") - } + if(len > 1) + { + len = 1; + window.console.log('Pixi.js warning: masks in canvas can only mask using the first path in the graphics object'); + } - for (var i=0; i < 1; i++) - { - var data = graphics.graphicsData[i]; - var points = data.points; + for (var i = 0; i < 1; i++) + { + var data = graphics.graphicsData[i]; + var points = data.points; - if(data.type == PIXI.Graphics.POLY) - { - context.beginPath(); - context.moveTo(points[0], points[1]); + if(data.type === PIXI.Graphics.POLY) + { + context.beginPath(); + context.moveTo(points[0], points[1]); - for (var j=1; j < points.length/2; j++) - { - context.lineTo(points[j * 2], points[j * 2 + 1]); - } + for (var j=1; j < points.length/2; j++) + { + context.lineTo(points[j * 2], points[j * 2 + 1]); + } - // if the first and last point are the same close the path - much neater :) - if(points[0] == points[points.length-2] && points[1] == points[points.length-1]) - { - context.closePath(); - } + // if the first and last point are the same close the path - much neater :) + if(points[0] === points[points.length-2] && points[1] === points[points.length-1]) + { + context.closePath(); + } - } - else if(data.type == PIXI.Graphics.RECT) - { - context.beginPath(); - context.rect(points[0], points[1], points[2], points[3]); - context.closePath(); - } - else if(data.type == PIXI.Graphics.CIRC) - { - // TODO - need to be Undefined! - context.beginPath(); - context.arc(points[0], points[1], points[2],0,2*Math.PI); - context.closePath(); - } - else if(data.type == PIXI.Graphics.ELIP) - { + } + else if(data.type === PIXI.Graphics.RECT) + { + context.beginPath(); + context.rect(points[0], points[1], points[2], points[3]); + context.closePath(); + } + else if(data.type === PIXI.Graphics.CIRC) + { + // TODO - need to be Undefined! + context.beginPath(); + context.arc(points[0], points[1], points[2],0,2*Math.PI); + context.closePath(); + } + else if(data.type === PIXI.Graphics.ELIP) + { - // elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas - var elipseData = data.points; + // ellipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas + var ellipseData = data.points; - var w = elipseData[2] * 2; - var h = elipseData[3] * 2; + var w = ellipseData[2] * 2; + var h = ellipseData[3] * 2; - var x = elipseData[0] - w/2; - var y = elipseData[1] - h/2; + var x = ellipseData[0] - w/2; + var y = ellipseData[1] - h/2; - context.beginPath(); + context.beginPath(); - var kappa = .5522848, - ox = (w / 2) * kappa, // control point offset horizontal - oy = (h / 2) * kappa, // control point offset vertical - xe = x + w, // x-end - ye = y + h, // y-end - xm = x + w / 2, // x-middle - ym = y + h / 2; // y-middle + var kappa = 0.5522848, + ox = (w / 2) * kappa, // control point offset horizontal + oy = (h / 2) * kappa, // control point offset vertical + xe = x + w, // x-end + ye = y + h, // y-end + xm = x + w / 2, // x-middle + ym = y + h / 2; // y-middle - context.moveTo(x, ym); - context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); - context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); - context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); - context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); - context.closePath(); - } - - - }; -} + context.moveTo(x, ym); + context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y); + context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym); + context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye); + context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym); + context.closePath(); + } + } +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ - /** * the CanvasRenderer draws the stage and all its content onto a 2d canvas. This renderer should be used for browsers that do not support webGL. * Dont forget to add the view to your DOM or you will not see anything :) @@ -3173,49 +3117,63 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context) */ PIXI.CanvasRenderer = function(width, height, view, transparent) { - this.transparent = transparent; + this.transparent = transparent; - /** - * The width of the canvas view - * - * @property width - * @type Number - * @default 800 - */ - this.width = width || 800; + /** + * The width of the canvas view + * + * @property width + * @type Number + * @default 800 + */ + this.width = width || 800; - /** - * The height of the canvas view - * - * @property height - * @type Number - * @default 600 - */ - this.height = height || 600; + /** + * The height of the canvas view + * + * @property height + * @type Number + * @default 600 + */ + this.height = height || 600; - /** - * The canvas element that the everything is drawn to - * - * @property view - * @type Canvas - */ - this.view = view || document.createElement( 'canvas' ); + /** + * The canvas element that the everything is drawn to + * + * @property view + * @type Canvas + */ + this.view = view || document.createElement( 'canvas' ); - /** - * The canvas context that the everything is drawn to - * @property context - * @type Canvas 2d Context - */ - this.context = this.view.getContext("2d"); + /** + * The canvas context that the everything is drawn to + * @property context + * @type Canvas 2d Context + */ + this.context = this.view.getContext( '2d' ); + + //some filter variables + this.smoothProperty = null; + + if('imageSmoothingEnabled' in this.context) + this.smoothProperty = 'imageSmoothingEnabled'; + else if('webkitImageSmoothingEnabled' in this.context) + this.smoothProperty = 'webkitImageSmoothingEnabled'; + else if('mozImageSmoothingEnabled' in this.context) + this.smoothProperty = 'mozImageSmoothingEnabled'; + else if('oImageSmoothingEnabled' in this.context) + this.smoothProperty = 'oImageSmoothingEnabled'; + + this.scaleMode = null; + + this.refresh = true; + // hack to enable some hardware acceleration! + //this.view.style["transform"] = "translatez(0)"; - this.refresh = true; - // hack to enable some hardware acceleration! - //this.view.style["transform"] = "translatez(0)"; - this.view.width = this.width; - this.view.height = this.height; - this.count = 0; -} + this.view.height = this.height; + this.count = 0; +}; // constructor PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer; @@ -3228,44 +3186,42 @@ PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer; */ PIXI.CanvasRenderer.prototype.render = function(stage) { - - //stage.__childrenAdded = []; - //stage.__childrenRemoved = []; - - // update textures if need be - PIXI.texturesToUpdate = []; - PIXI.texturesToDestroy = []; - - PIXI.visibleCount++; - stage.updateTransform(); - - // update the background color - if(this.view.style.backgroundColor!=stage.backgroundColorString && !this.transparent)this.view.style.backgroundColor = stage.backgroundColorString; + //stage.__childrenAdded = []; + //stage.__childrenRemoved = []; - this.context.setTransform(1,0,0,1,0,0); - this.context.clearRect(0, 0, this.width, this.height) + // update textures if need be + PIXI.texturesToUpdate = []; + PIXI.texturesToDestroy = []; + + PIXI.visibleCount++; + stage.updateTransform(); + + // update the background color + if(this.view.style.backgroundColor !== stage.backgroundColorString && !this.transparent) + this.view.style.backgroundColor = stage.backgroundColorString; + + this.context.setTransform(1,0,0,1,0,0); + this.context.clearRect(0, 0, this.width, this.height); this.renderDisplayObject(stage); //as - + // run interaction! - if(stage.interactive) - { - //need to add some events! - if(!stage._interactiveEventsAdded) - { - stage._interactiveEventsAdded = true; - stage.interactionManager.setTarget(this); - } - } - - // remove frame updates.. - if(PIXI.Texture.frameUpdates.length > 0) - { - PIXI.Texture.frameUpdates = []; - } - - -} + if(stage.interactive) + { + //need to add some events! + if(!stage._interactiveEventsAdded) + { + stage._interactiveEventsAdded = true; + stage.interactionManager.setTarget(this); + } + } + + // remove frame updates.. + if(PIXI.Texture.frameUpdates.length > 0) + { + PIXI.Texture.frameUpdates = []; + } +}; /** * resizes the canvas view to the specified width and height @@ -3276,12 +3232,12 @@ PIXI.CanvasRenderer.prototype.render = function(stage) */ PIXI.CanvasRenderer.prototype.resize = function(width, height) { - this.width = width; - this.height = height; - - this.view.width = width; - this.view.height = height; -} + this.width = width; + this.height = height; + + this.view.width = width; + this.view.height = height; +}; /** * Renders a display object @@ -3292,117 +3248,116 @@ PIXI.CanvasRenderer.prototype.resize = function(width, height) */ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) { - // no loger recurrsive! - var transform; - var context = this.context; - - context.globalCompositeOperation = 'source-over'; - - // one the display object hits this. we can break the loop - var testObject = displayObject.last._iNext; - displayObject = displayObject.first; - - do - { - transform = displayObject.worldTransform; - - if(!displayObject.visible) - { - displayObject = displayObject.last._iNext; - continue; - } - - if(!displayObject.renderable) - { - displayObject = displayObject._iNext; - continue; - } - - if(displayObject instanceof PIXI.Sprite) - { - - var frame = displayObject.texture.frame; - - if(frame && frame.width && frame.height) - { - context.globalAlpha = displayObject.worldAlpha; - - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - - context.drawImage(displayObject.texture.baseTexture.source, - frame.x, - frame.y, - frame.width, - frame.height, - (displayObject.anchor.x) * -frame.width, - (displayObject.anchor.y) * -frame.height, - frame.width, - frame.height); - } - } - else if(displayObject instanceof PIXI.Strip) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]) - this.renderStrip(displayObject); - } - else if(displayObject instanceof PIXI.TilingSprite) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]) - this.renderTilingSprite(displayObject); - } - else if(displayObject instanceof PIXI.CustomRenderable) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); - displayObject.renderCanvas(this); - } - else if(displayObject instanceof PIXI.Graphics) - { - context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]) - PIXI.CanvasGraphics.renderGraphics(displayObject, context); - } - else if(displayObject instanceof PIXI.FilterBlock) - { - if(displayObject.data instanceof PIXI.Graphics) - { - var mask = displayObject.data; + // no loger recurrsive! + var transform; + var context = this.context; - if(displayObject.open) - { - context.save(); - - var cacheAlpha = mask.alpha; - var maskTransform = mask.worldTransform; - - context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]) - - mask.worldAlpha = 0.5; - - context.worldAlpha = 0; - - PIXI.CanvasGraphics.renderGraphicsMask(mask, context); - context.clip(); - - mask.worldAlpha = cacheAlpha; - } - else - { - context.restore(); - } - } - else - { - // only masks supported right now! - } - } - // count++ - displayObject = displayObject._iNext; - - - } - while(displayObject != testObject) + context.globalCompositeOperation = 'source-over'; - -} + // one the display object hits this. we can break the loop + var testObject = displayObject.last._iNext; + displayObject = displayObject.first; + + do + { + transform = displayObject.worldTransform; + + if(!displayObject.visible) + { + displayObject = displayObject.last._iNext; + continue; + } + + if(!displayObject.renderable) + { + displayObject = displayObject._iNext; + continue; + } + + if(displayObject instanceof PIXI.Sprite) + { + + var frame = displayObject.texture.frame; + + //ignore null sources + if(frame && frame.width && frame.height && displayObject.texture.baseTexture.source) + { + context.globalAlpha = displayObject.worldAlpha; + + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + + //if smoothingEnabled is supported and we need to change the smoothing property for this texture + if(this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) { + this.scaleMode = displayObject.texture.baseTexture.scaleMode; + context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); + } + + context.drawImage(displayObject.texture.baseTexture.source, + frame.x, + frame.y, + frame.width, + frame.height, + (displayObject.anchor.x) * -frame.width, + (displayObject.anchor.y) * -frame.height, + frame.width, + frame.height); + } + } + else if(displayObject instanceof PIXI.Strip) + { + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + this.renderStrip(displayObject); + } + else if(displayObject instanceof PIXI.TilingSprite) + { + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + this.renderTilingSprite(displayObject); + } + else if(displayObject instanceof PIXI.CustomRenderable) + { + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + displayObject.renderCanvas(this); + } + else if(displayObject instanceof PIXI.Graphics) + { + context.setTransform(transform[0], transform[3], transform[1], transform[4], transform[2], transform[5]); + PIXI.CanvasGraphics.renderGraphics(displayObject, context); + } + else if(displayObject instanceof PIXI.FilterBlock) + { + if(displayObject.data instanceof PIXI.Graphics) + { + var mask = displayObject.data; + + if(displayObject.open) + { + context.save(); + + var cacheAlpha = mask.alpha; + var maskTransform = mask.worldTransform; + + context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5]); + + mask.worldAlpha = 0.5; + + context.worldAlpha = 0; + + PIXI.CanvasGraphics.renderGraphicsMask(mask, context); + context.clip(); + + mask.worldAlpha = cacheAlpha; + } + else + { + context.restore(); + } + } + } + //count++ + displayObject = displayObject._iNext; + } + while(displayObject !== testObject); +}; /** * Renders a flat strip @@ -3413,33 +3368,30 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) */ PIXI.CanvasRenderer.prototype.renderStripFlat = function(strip) { - var context = this.context; - var verticies = strip.verticies; - var uvs = strip.uvs; - - var length = verticies.length/2; - this.count++; - - context.beginPath(); - for (var i=1; i < length-2; i++) - { - - // draw some triangles! - var index = i*2; - - var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; - var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; - - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - - }; - - context.fillStyle = "#FF0000"; - context.fill(); - context.closePath(); -} + var context = this.context; + var verticies = strip.verticies; + + var length = verticies.length/2; + this.count++; + + context.beginPath(); + for (var i=1; i < length-2; i++) + { + // draw some triangles! + var index = i*2; + + var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; + var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; + + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + } + + context.fillStyle = '#FF0000'; + context.fill(); + context.closePath(); +}; /** * Renders a tiling sprite @@ -3450,29 +3402,30 @@ PIXI.CanvasRenderer.prototype.renderStripFlat = function(strip) */ PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) { - var context = this.context; - - context.globalAlpha = sprite.worldAlpha; - - if(!sprite.__tilePattern) sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, "repeat"); - - context.beginPath(); - - var tilePosition = sprite.tilePosition; - var tileScale = sprite.tileScale; - + var context = this.context; + + context.globalAlpha = sprite.worldAlpha; + + if(!sprite.__tilePattern) + sprite.__tilePattern = context.createPattern(sprite.texture.baseTexture.source, 'repeat'); + + context.beginPath(); + + var tilePosition = sprite.tilePosition; + var tileScale = sprite.tileScale; + // offset context.scale(tileScale.x,tileScale.y); context.translate(tilePosition.x, tilePosition.y); - - context.fillStyle = sprite.__tilePattern; - context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); - - context.scale(1/tileScale.x, 1/tileScale.y); + + context.fillStyle = sprite.__tilePattern; + context.fillRect(-tilePosition.x,-tilePosition.y,sprite.width / tileScale.x, sprite.height / tileScale.y); + + context.scale(1/tileScale.x, 1/tileScale.y); context.translate(-tilePosition.x, -tilePosition.y); - + context.closePath(); -} +}; /** * Renders a strip @@ -3483,58 +3436,52 @@ PIXI.CanvasRenderer.prototype.renderTilingSprite = function(sprite) */ PIXI.CanvasRenderer.prototype.renderStrip = function(strip) { - var context = this.context; + var context = this.context; - // draw triangles!! - var verticies = strip.verticies; - var uvs = strip.uvs; - - var length = verticies.length/2; - this.count++; - for (var i=1; i < length-2; i++) - { - - // draw some triangles! - var index = i*2; - - var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; - var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; - - var u0 = uvs[index] * strip.texture.width, u1 = uvs[index+2] * strip.texture.width, u2 = uvs[index+4]* strip.texture.width; - var v0 = uvs[index+1]* strip.texture.height, v1 = uvs[index+3] * strip.texture.height, v2 = uvs[index+5]* strip.texture.height; + // draw triangles!! + var verticies = strip.verticies; + var uvs = strip.uvs; + var length = verticies.length/2; + this.count++; + + for (var i = 1; i < length-2; i++) + { + // draw some triangles! + var index = i*2; + + var x0 = verticies[index], x1 = verticies[index+2], x2 = verticies[index+4]; + var y0 = verticies[index+1], y1 = verticies[index+3], y2 = verticies[index+5]; + + var u0 = uvs[index] * strip.texture.width, u1 = uvs[index+2] * strip.texture.width, u2 = uvs[index+4]* strip.texture.width; + var v0 = uvs[index+1]* strip.texture.height, v1 = uvs[index+3] * strip.texture.height, v2 = uvs[index+5]* strip.texture.height; + + context.save(); + context.beginPath(); + context.moveTo(x0, y0); + context.lineTo(x1, y1); + context.lineTo(x2, y2); + context.closePath(); + + context.clip(); - context.save(); - context.beginPath(); - context.moveTo(x0, y0); - context.lineTo(x1, y1); - context.lineTo(x2, y2); - context.closePath(); - - context.clip(); - - // Compute matrix transform var delta = u0*v1 + v0*u2 + u1*v2 - v1*u2 - v0*u1 - u0*v2; - var delta_a = x0*v1 + v0*x2 + x1*v2 - v1*x2 - v0*x1 - x0*v2; - var delta_b = u0*x1 + x0*u2 + u1*x2 - x1*u2 - x0*u1 - u0*x2; - var delta_c = u0*v1*x2 + v0*x1*u2 + x0*u1*v2 - x0*v1*u2 - v0*u1*x2 - u0*x1*v2; - var delta_d = y0*v1 + v0*y2 + y1*v2 - v1*y2 - v0*y1 - y0*v2; - var delta_e = u0*y1 + y0*u2 + u1*y2 - y1*u2 - y0*u1 - u0*y2; - var delta_f = u0*v1*y2 + v0*y1*u2 + y0*u1*v2 - y0*v1*u2 - v0*u1*y2 - u0*y1*v2; - - - - - context.transform(delta_a/delta, delta_d/delta, - delta_b/delta, delta_e/delta, - delta_c/delta, delta_f/delta); - - context.drawImage(strip.texture.baseTexture.source, 0, 0); - context.restore(); - }; - -} + var deltaA = x0*v1 + v0*x2 + x1*v2 - v1*x2 - v0*x1 - x0*v2; + var deltaB = u0*x1 + x0*u2 + u1*x2 - x1*u2 - x0*u1 - u0*x2; + var deltaC = u0*v1*x2 + v0*x1*u2 + x0*u1*v2 - x0*v1*u2 - v0*u1*x2 - u0*x1*v2; + var deltaD = y0*v1 + v0*y2 + y1*v2 - v1*y2 - v0*y1 - y0*v2; + var deltaE = u0*y1 + y0*u2 + u1*y2 - y1*u2 - y0*u1 - u0*y2; + var deltaF = u0*v1*y2 + v0*y1*u2 + y0*u1*v2 - y0*v1*u2 - v0*u1*y2 - u0*y1*v2; + + context.transform(deltaA / delta, deltaD / delta, + deltaB / delta, deltaE / delta, + deltaC / delta, deltaF / delta); + + context.drawImage(strip.texture.baseTexture.source, 0, 0); + context.restore(); + } +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 @@ -3550,26 +3497,25 @@ PIXI.PixiShader = function() /** * @property {any} program - The WebGL program. */ - this.program; - + this.program = null; + /** * @property {array} fragmentSrc - The fragment shader. */ this.fragmentSrc = [ - "precision lowp float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform sampler2D uSampler;", - "void main(void) {", - "gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;", - "}" + 'precision lowp float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform sampler2D uSampler;', + 'void main(void) {', + ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;', + '}' ]; /** * @property {number} textureCount - A local texture counter for multi-texture shaders. */ this.textureCount = 0; - }; /** @@ -3577,23 +3523,23 @@ PIXI.PixiShader = function() */ PIXI.PixiShader.prototype.init = function() { - var program = PIXI.compileProgram(this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc) - + var program = PIXI.compileProgram(this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc); + var gl = PIXI.gl; gl.useProgram(program); - + // get and store the uniforms for the shader - this.uSampler = gl.getUniformLocation(program, "uSampler"); - this.projectionVector = gl.getUniformLocation(program, "projectionVector"); - this.offsetVector = gl.getUniformLocation(program, "offsetVector"); - this.dimensions = gl.getUniformLocation(program, "dimensions"); - + this.uSampler = gl.getUniformLocation(program, 'uSampler'); + this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); + this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.dimensions = gl.getUniformLocation(program, 'dimensions'); + // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); - this.colorAttribute = gl.getAttribLocation(program, "aColor"); - this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); - + this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); + this.colorAttribute = gl.getAttribLocation(program, 'aColor'); + this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); + // add those custom shaders! for (var key in this.uniforms) { @@ -3602,7 +3548,7 @@ PIXI.PixiShader.prototype.init = function() } this.initUniforms(); - + this.program = program; }; @@ -3618,13 +3564,14 @@ PIXI.PixiShader.prototype.initUniforms = function() this.textureCount = 1; var uniform; - - for (var key in this.uniforms) + + for (var key in this.uniforms) { - var uniform = this.uniforms[key]; + uniform = this.uniforms[key]; + var type = uniform.type; - if (type == 'sampler2D') + if (type === 'sampler2D') { uniform._init = false; @@ -3633,21 +3580,21 @@ PIXI.PixiShader.prototype.initUniforms = function() this.initSampler2D(uniform); } } - else if (type == 'mat2' || type == 'mat3' || type == 'mat4') + else if (type === 'mat2' || type === 'mat3' || type === 'mat4') { // These require special handling uniform.glMatrix = true; uniform.glValueLength = 1; - if (type == 'mat2') + if (type === 'mat2') { uniform.glFunc = PIXI.gl.uniformMatrix2fv; } - else if (type == 'mat3') + else if (type === 'mat3') { uniform.glFunc = PIXI.gl.uniformMatrix3fv; } - else if (type == 'mat4') + else if (type === 'mat4') { uniform.glFunc = PIXI.gl.uniformMatrix4fv; } @@ -3657,15 +3604,15 @@ PIXI.PixiShader.prototype.initUniforms = function() // GL function reference uniform.glFunc = PIXI.gl['uniform' + type]; - if (type == '2f' || type == '2i') + if (type === '2f' || type === '2i') { uniform.glValueLength = 2; } - else if (type == '3f' || type == '3i') + else if (type === '3f' || type === '3i') { uniform.glValueLength = 3; } - else if (type == '4f' || type == '4i') + else if (type === '4f' || type === '4i') { uniform.glValueLength = 4; } @@ -3675,7 +3622,7 @@ PIXI.PixiShader.prototype.initUniforms = function() } } } - + }; /** @@ -3762,11 +3709,12 @@ PIXI.PixiShader.prototype.syncUniforms = function() var uniform; // This would probably be faster in an array and it would guarantee key order - for (var key in this.uniforms) + for (var key in this.uniforms) { + uniform = this.uniforms[key]; - if (uniform.glValueLength == 1) + if (uniform.glValueLength === 1) { if (uniform.glMatrix === true) { @@ -3777,19 +3725,19 @@ PIXI.PixiShader.prototype.syncUniforms = function() uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value); } } - else if (uniform.glValueLength == 2) + else if (uniform.glValueLength === 2) { uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value.x, uniform.value.y); } - else if (uniform.glValueLength == 3) + else if (uniform.glValueLength === 3) { uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z); } - else if (uniform.glValueLength == 4) + else if (uniform.glValueLength === 4) { uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z, uniform.value.w); } - else if (uniform.type == 'sampler2D') + else if (uniform.type === 'sampler2D') { if (uniform._init) { @@ -3804,28 +3752,27 @@ PIXI.PixiShader.prototype.syncUniforms = function() } } } - + }; PIXI.PixiShader.defaultVertexSrc = [ - - "attribute vec2 aVertexPosition;", - "attribute vec2 aTextureCoord;", - "attribute float aColor;", + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute float aColor;', - "uniform vec2 projectionVector;", - "uniform vec2 offsetVector;", - "varying vec2 vTextureCoord;", + 'uniform vec2 projectionVector;', + 'uniform vec2 offsetVector;', + 'varying vec2 vTextureCoord;', - "varying float vColor;", + 'varying float vColor;', - "const vec2 center = vec2(-1.0, 1.0);", - - "void main(void) {", - "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);", - "vTextureCoord = aTextureCoord;", - "vColor = aColor;", - "}" + 'const vec2 center = vec2(-1.0, 1.0);', + + 'void main(void) {', + ' gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = aColor;', + '}' ]; /** @@ -3835,56 +3782,57 @@ PIXI.PixiShader.defaultVertexSrc = [ PIXI.PrimitiveShader = function() { - // the webGL program.. - this.program; - + // the webGL program.. + this.program = null; + this.fragmentSrc = [ - "precision mediump float;", - "varying vec4 vColor;", - "void main(void) {", - "gl_FragColor = vColor;", - "}" + 'precision mediump float;', + 'varying vec4 vColor;', + + 'void main(void) {', + ' gl_FragColor = vColor;', + '}' ]; this.vertexSrc = [ - "attribute vec2 aVertexPosition;", - "attribute vec4 aColor;", - "uniform mat3 translationMatrix;", - "uniform vec2 projectionVector;", - "uniform vec2 offsetVector;", - "uniform float alpha;", - "varying vec4 vColor;", - "void main(void) {", - "vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);", - "v -= offsetVector.xyx;", - "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);", - "vColor = aColor * alpha;", - "}" + 'attribute vec2 aVertexPosition;', + 'attribute vec4 aColor;', + 'uniform mat3 translationMatrix;', + 'uniform vec2 projectionVector;', + 'uniform vec2 offsetVector;', + 'uniform float alpha;', + 'varying vec4 vColor;', + + 'void main(void) {', + ' vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);', + ' v -= offsetVector.xyx;', + ' gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);', + ' vColor = aColor * alpha;', + '}' ]; - -} +}; PIXI.PrimitiveShader.prototype.init = function() { - var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc); - - var gl = PIXI.gl; - - gl.useProgram(program); - - // get and store the uniforms for the shader - this.projectionVector = gl.getUniformLocation(program, "projectionVector"); - this.offsetVector = gl.getUniformLocation(program, "offsetVector"); - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); - this.colorAttribute = gl.getAttribLocation(program, "aColor"); - - this.translationMatrix = gl.getUniformLocation(program, "translationMatrix"); - this.alpha = gl.getUniformLocation(program, "alpha"); + var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc); - this.program = program; -} + var gl = PIXI.gl; + + gl.useProgram(program); + + // get and store the uniforms for the shader + this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); + this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); + this.colorAttribute = gl.getAttribLocation(program, 'aColor'); + + this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix'); + this.alpha = gl.getUniformLocation(program, 'alpha'); + + this.program = program; +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 @@ -3893,64 +3841,66 @@ PIXI.PrimitiveShader.prototype.init = function() PIXI.StripShader = function() { - // the webGL program.. - this.program; - + // the webGL program.. + this.program = null; + this.fragmentSrc = [ - "precision mediump float;", - "varying vec2 vTextureCoord;", - "varying float vColor;", - "uniform float alpha;", - "uniform sampler2D uSampler;", - "void main(void) {", - "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));", - "gl_FragColor = gl_FragColor * alpha;", - "}" + 'precision mediump float;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + 'uniform float alpha;', + 'uniform sampler2D uSampler;', + + 'void main(void) {', + ' gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));', + ' gl_FragColor = gl_FragColor * alpha;', + '}' ]; this.vertexSrc = [ - "attribute vec2 aVertexPosition;", - "attribute vec2 aTextureCoord;", - "attribute float aColor;", - "uniform mat3 translationMatrix;", - "uniform vec2 projectionVector;", - "varying vec2 vTextureCoord;", - "varying vec2 offsetVector;", - "varying float vColor;", - "void main(void) {", - "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);", - "v -= offsetVector.xyx;", - "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);", - "vTextureCoord = aTextureCoord;", - "vColor = aColor;", - "}" + 'attribute vec2 aVertexPosition;', + 'attribute vec2 aTextureCoord;', + 'attribute float aColor;', + 'uniform mat3 translationMatrix;', + 'uniform vec2 projectionVector;', + 'uniform vec2 offsetVector;', + 'varying vec2 vTextureCoord;', + 'varying float vColor;', + + 'void main(void) {', + ' vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);', + ' v -= offsetVector.xyx;', + ' gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);', + ' vTextureCoord = aTextureCoord;', + ' vColor = aColor;', + '}' ]; -} +}; PIXI.StripShader.prototype.init = function() { - var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc) - - var gl = PIXI.gl; - + var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc); + + var gl = PIXI.gl; + gl.useProgram(program); - // get and store the uniforms for the shader - this.uSampler = gl.getUniformLocation(program, "uSampler"); - this.projectionVector = gl.getUniformLocation(program, "projectionVector"); - this.offsetVector = gl.getUniformLocation(program, "offsetVector"); - this.colorAttribute = gl.getAttribLocation(program, "aColor"); - //this.dimensions = gl.getUniformLocation(this.program, "dimensions"); - - // get and store the attributes - this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition"); - this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord"); - - this.translationMatrix = gl.getUniformLocation(program, "translationMatrix"); - this.alpha = gl.getUniformLocation(program, "alpha"); - - this.program = program; -} + // get and store the uniforms for the shader + this.uSampler = gl.getUniformLocation(program, 'uSampler'); + this.projectionVector = gl.getUniformLocation(program, 'projectionVector'); + this.offsetVector = gl.getUniformLocation(program, 'offsetVector'); + this.colorAttribute = gl.getAttribLocation(program, 'aColor'); + //this.dimensions = gl.getUniformLocation(this.program, 'dimensions'); + + // get and store the attributes + this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition'); + this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord'); + + this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix'); + this.alpha = gl.getUniformLocation(program, 'alpha'); + + this.program = program; +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 @@ -3963,35 +3913,35 @@ PIXI._batchs = []; */ PIXI._getBatch = function(gl) { - if(PIXI._batchs.length === 0) - { - return new PIXI.WebGLBatch(gl); - } - else - { - return PIXI._batchs.pop(); - } -} + if(PIXI._batchs.length === 0) + { + return new PIXI.WebGLBatch(gl); + } + else + { + return PIXI._batchs.pop(); + } +}; /** * @private */ PIXI._returnBatch = function(batch) { - batch.clean(); - PIXI._batchs.push(batch); -} + batch.clean(); + PIXI._batchs.push(batch); +}; /** * @private */ PIXI._restoreBatchs = function(gl) { - for (var i=0; i < PIXI._batchs.length; i++) - { - PIXI._batchs[i].restoreLostContext(gl); - }; -} + for (var i=0; i < PIXI._batchs.length; i++) + { + PIXI._batchs[i].restoreLostContext(gl); + } +}; /** * A WebGLBatch Enables a group of sprites to be drawn using the same settings. @@ -4007,17 +3957,17 @@ PIXI._restoreBatchs = function(gl) */ PIXI.WebGLBatch = function(gl) { - this.gl = gl; - - this.size = 0; + this.gl = gl; - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); - this.blendMode = PIXI.blendModes.NORMAL; - this.dynamicSize = 1; -} + this.size = 0; + + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + this.uvBuffer = gl.createBuffer(); + this.colorBuffer = gl.createBuffer(); + this.blendMode = PIXI.blendModes.NORMAL; + this.dynamicSize = 1; +}; // constructor PIXI.WebGLBatch.prototype.constructor = PIXI.WebGLBatch; @@ -4029,17 +3979,17 @@ PIXI.WebGLBatch.prototype.constructor = PIXI.WebGLBatch; */ PIXI.WebGLBatch.prototype.clean = function() { - this.verticies = []; - this.uvs = []; - this.indices = []; - this.colors = []; - this.dynamicSize = 1; - this.texture = null; - this.last = null; - this.size = 0; - this.head; - this.tail; -} + this.verticies = []; + this.uvs = []; + this.indices = []; + this.colors = []; + this.dynamicSize = 1; + this.texture = null; + this.last = null; + this.size = 0; + this.head = null; + this.tail = null; +}; /** * Recreates the buffers in the event of a context loss @@ -4049,32 +3999,32 @@ PIXI.WebGLBatch.prototype.clean = function() */ PIXI.WebGLBatch.prototype.restoreLostContext = function(gl) { - this.gl = gl; - this.vertexBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.colorBuffer = gl.createBuffer(); -} + this.gl = gl; + this.vertexBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + this.uvBuffer = gl.createBuffer(); + this.colorBuffer = gl.createBuffer(); +}; /** * inits the batch's texture and blend mode based if the supplied sprite * * @method init * @param sprite {Sprite} the first sprite to be added to the batch. Only sprites with - * the same base texture and blend mode will be allowed to be added to this batch - */ + * the same base texture and blend mode will be allowed to be added to this batch + */ PIXI.WebGLBatch.prototype.init = function(sprite) { - sprite.batch = this; - this.dirty = true; - this.blendMode = sprite.blendMode; - this.texture = sprite.texture.baseTexture; - this.head = sprite; - this.tail = sprite; - this.size = 1; + sprite.batch = this; + this.dirty = true; + this.blendMode = sprite.blendMode; + this.texture = sprite.texture.baseTexture; + this.head = sprite; + this.tail = sprite; + this.size = 1; - this.growBatch(); -} + this.growBatch(); +}; /** * inserts a sprite before the specified sprite @@ -4082,27 +4032,27 @@ PIXI.WebGLBatch.prototype.init = function(sprite) * @method insertBefore * @param sprite {Sprite} the sprite to be added * @param nextSprite {nextSprite} the first sprite will be inserted before this sprite - */ + */ PIXI.WebGLBatch.prototype.insertBefore = function(sprite, nextSprite) { - this.size++; + this.size++; - sprite.batch = this; - this.dirty = true; - var tempPrev = nextSprite.__prev; - nextSprite.__prev = sprite; - sprite.__next = nextSprite; + sprite.batch = this; + this.dirty = true; + var tempPrev = nextSprite.__prev; + nextSprite.__prev = sprite; + sprite.__next = nextSprite; - if(tempPrev) - { - sprite.__prev = tempPrev; - tempPrev.__next = sprite; - } - else - { - this.head = sprite; - } -} + if(tempPrev) + { + sprite.__prev = tempPrev; + tempPrev.__next = sprite; + } + else + { + this.head = sprite; + } +}; /** * inserts a sprite after the specified sprite @@ -4110,72 +4060,72 @@ PIXI.WebGLBatch.prototype.insertBefore = function(sprite, nextSprite) * @method insertAfter * @param sprite {Sprite} the sprite to be added * @param previousSprite {Sprite} the first sprite will be inserted after this sprite - */ + */ PIXI.WebGLBatch.prototype.insertAfter = function(sprite, previousSprite) { - this.size++; + this.size++; - sprite.batch = this; - this.dirty = true; + sprite.batch = this; + this.dirty = true; - var tempNext = previousSprite.__next; - previousSprite.__next = sprite; - sprite.__prev = previousSprite; + var tempNext = previousSprite.__next; + previousSprite.__next = sprite; + sprite.__prev = previousSprite; - if(tempNext) - { - sprite.__next = tempNext; - tempNext.__prev = sprite; - } - else - { - this.tail = sprite - } -} + if(tempNext) + { + sprite.__next = tempNext; + tempNext.__prev = sprite; + } + else + { + this.tail = sprite; + } +}; /** * removes a sprite from the batch * * @method remove * @param sprite {Sprite} the sprite to be removed - */ + */ PIXI.WebGLBatch.prototype.remove = function(sprite) { - this.size--; + this.size--; - if(this.size === 0) - { - sprite.batch = null; - sprite.__prev = null; - sprite.__next = null; - return; - } + if(this.size === 0) + { + sprite.batch = null; + sprite.__prev = null; + sprite.__next = null; + return; + } - if(sprite.__prev) - { - sprite.__prev.__next = sprite.__next; - } - else - { - this.head = sprite.__next; - this.head.__prev = null; - } + if(sprite.__prev) + { + sprite.__prev.__next = sprite.__next; + } + else + { + this.head = sprite.__next; + this.head.__prev = null; + } - if(sprite.__next) - { - sprite.__next.__prev = sprite.__prev; - } - else - { - this.tail = sprite.__prev; - this.tail.__next = null - } + if(sprite.__next) + { + sprite.__next.__prev = sprite.__prev; + } + else + { + this.tail = sprite.__prev; + this.tail.__next = null; + } - sprite.batch = null; - sprite.__next = null; - sprite.__prev = null; - this.dirty = true; -} + sprite.batch = null; + sprite.__next = null; + sprite.__prev = null; + this.dirty = true; +}; /** * Splits the batch into two with the specified sprite being the start of the new batch. @@ -4186,62 +4136,62 @@ PIXI.WebGLBatch.prototype.remove = function(sprite) */ PIXI.WebGLBatch.prototype.split = function(sprite) { - this.dirty = true; + this.dirty = true; - var batch = new PIXI.WebGLBatch(this.gl); - batch.init(sprite); - batch.texture = this.texture; - batch.tail = this.tail; + var batch = new PIXI.WebGLBatch(this.gl); + batch.init(sprite); + batch.texture = this.texture; + batch.tail = this.tail; - this.tail = sprite.__prev; - this.tail.__next = null; + this.tail = sprite.__prev; + this.tail.__next = null; - sprite.__prev = null; - // return a splite batch! + sprite.__prev = null; + // return a splite batch! - // TODO this size is wrong! - // need to recalculate :/ problem with a linked list! - // unless it gets calculated in the "clean"? + // TODO this size is wrong! + // need to recalculate :/ problem with a linked list! + // unless it gets calculated in the "clean"? - // need to loop through items as there is no way to know the length on a linked list :/ - var tempSize = 0; - while(sprite) - { - tempSize++; - sprite.batch = batch; - sprite = sprite.__next; - } + // need to loop through items as there is no way to know the length on a linked list :/ + var tempSize = 0; + while(sprite) + { + tempSize++; + sprite.batch = batch; + sprite = sprite.__next; + } - batch.size = tempSize; - this.size -= tempSize; + batch.size = tempSize; + this.size -= tempSize; - return batch; -} + return batch; +}; /** * Merges two batchs together * * @method merge - * @param batch {WebGLBatch} the batch that will be merged + * @param batch {WebGLBatch} the batch that will be merged */ PIXI.WebGLBatch.prototype.merge = function(batch) { - this.dirty = true; + this.dirty = true; - this.tail.__next = batch.head; - batch.head.__prev = this.tail; + this.tail.__next = batch.head; + batch.head.__prev = this.tail; - this.size += batch.size; + this.size += batch.size; - this.tail = batch.tail; + this.tail = batch.tail; - var sprite = batch.head; - while(sprite) - { - sprite.batch = this; - sprite = sprite.__next; - } -} + var sprite = batch.head; + while(sprite) + { + sprite.batch = this; + sprite = sprite.__next; + } +}; /** * Grows the size of the batch. As the elements in the batch cannot have a dynamic size this @@ -4252,51 +4202,52 @@ PIXI.WebGLBatch.prototype.merge = function(batch) */ PIXI.WebGLBatch.prototype.growBatch = function() { - var gl = this.gl; - if( this.size == 1) - { - this.dynamicSize = 1; - } - else - { - this.dynamicSize = this.size * 1.5 - } - // grow verts - this.verticies = new Float32Array(this.dynamicSize * 8); + var gl = this.gl; + if( this.size === 1) + { + this.dynamicSize = 1; + } + else + { + this.dynamicSize = this.size * 1.5; + } - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW); + // grow verts + this.verticies = new Float32Array(this.dynamicSize * 8); - this.uvs = new Float32Array( this.dynamicSize * 8 ); - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.uvs , gl.DYNAMIC_DRAW); + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW); - this.dirtyUVS = true; + this.uvs = new Float32Array( this.dynamicSize * 8 ); + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + gl.bufferData(gl.ARRAY_BUFFER, this.uvs , gl.DYNAMIC_DRAW); - this.colors = new Float32Array( this.dynamicSize * 4 ); - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - gl.bufferData(gl.ARRAY_BUFFER, this.colors , gl.DYNAMIC_DRAW); + this.dirtyUVS = true; - this.dirtyColors = true; + this.colors = new Float32Array( this.dynamicSize * 4 ); + gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); + gl.bufferData(gl.ARRAY_BUFFER, this.colors , gl.DYNAMIC_DRAW); - this.indices = new Uint16Array(this.dynamicSize * 6); - var length = this.indices.length/6; + this.dirtyColors = true; - for (var i=0; i < length; i++) - { - var index2 = i * 6; - var index3 = i * 4; - this.indices[index2 + 0] = index3 + 0; - this.indices[index2 + 1] = index3 + 1; - this.indices[index2 + 2] = index3 + 2; - this.indices[index2 + 3] = index3 + 0; - this.indices[index2 + 4] = index3 + 2; - this.indices[index2 + 5] = index3 + 3; - }; + this.indices = new Uint16Array(this.dynamicSize * 6); + var length = this.indices.length/6; - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + for (var i = 0; i < length; i++) + { + var index2 = i * 6; + var index3 = i * 4; + this.indices[index2 + 0] = index3 + 0; + this.indices[index2 + 1] = index3 + 1; + this.indices[index2 + 2] = index3 + 2; + this.indices[index2 + 3] = index3 + 0; + this.indices[index2 + 4] = index3 + 2; + this.indices[index2 + 5] = index3 + 3; + } + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW); -} +}; /** * Refresh's all the data in the batch and sync's it with the webGL buffers @@ -4305,54 +4256,51 @@ PIXI.WebGLBatch.prototype.growBatch = function() */ PIXI.WebGLBatch.prototype.refresh = function() { - var gl = this.gl; + if (this.dynamicSize < this.size) + { + this.growBatch(); + } - if (this.dynamicSize < this.size) - { - this.growBatch(); - } + var indexRun = 0; + var index, colorIndex; - var indexRun = 0; - var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index; - var a, b, c, d, tx, ty; + var displayObject = this.head; - var displayObject = this.head; + while(displayObject) + { + index = indexRun * 8; - while(displayObject) - { - index = indexRun * 8; + var texture = displayObject.texture; - var texture = displayObject.texture; + var frame = texture.frame; + var tw = texture.baseTexture.width; + var th = texture.baseTexture.height; - var frame = texture.frame; - var tw = texture.baseTexture.width; - var th = texture.baseTexture.height; + this.uvs[index + 0] = frame.x / tw; + this.uvs[index +1] = frame.y / th; - this.uvs[index + 0] = frame.x / tw; - this.uvs[index +1] = frame.y / th; + this.uvs[index +2] = (frame.x + frame.width) / tw; + this.uvs[index +3] = frame.y / th; - this.uvs[index +2] = (frame.x + frame.width) / tw; - this.uvs[index +3] = frame.y / th; + this.uvs[index +4] = (frame.x + frame.width) / tw; + this.uvs[index +5] = (frame.y + frame.height) / th; - this.uvs[index +4] = (frame.x + frame.width) / tw; - this.uvs[index +5] = (frame.y + frame.height) / th; + this.uvs[index +6] = frame.x / tw; + this.uvs[index +7] = (frame.y + frame.height) / th; - this.uvs[index +6] = frame.x / tw; - this.uvs[index +7] = (frame.y + frame.height) / th; + displayObject.updateFrame = false; - displayObject.updateFrame = false; + colorIndex = indexRun * 4; + this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha; - colorIndex = indexRun * 4; - this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha; + displayObject = displayObject.__next; - displayObject = displayObject.__next; + indexRun++; + } - indexRun ++; - } - - this.dirtyUVS = true; - this.dirtyColors = true; -} + this.dirtyUVS = true; + this.dirtyColors = true; +}; /** * Updates all the relevant geometry and uploads the data to the GPU @@ -4361,103 +4309,102 @@ PIXI.WebGLBatch.prototype.refresh = function() */ PIXI.WebGLBatch.prototype.update = function() { - var gl = this.gl; - var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, index2, index3 + var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index; - var a, b, c, d, tx, ty; + var a, b, c, d, tx, ty; - var indexRun = 0; + var indexRun = 0; - var displayObject = this.head; - var verticies = this.verticies; - var uvs = this.uvs; - var colors = this.colors; - - while(displayObject) - { - if(displayObject.vcount === PIXI.visibleCount) - { - width = displayObject.texture.frame.width; - height = displayObject.texture.frame.height; + var displayObject = this.head; + var verticies = this.verticies; + var uvs = this.uvs; + var colors = this.colors; - // TODO trim?? - aX = displayObject.anchor.x;// - displayObject.texture.trim.x - aY = displayObject.anchor.y; //- displayObject.texture.trim.y - w0 = width * (1-aX); - w1 = width * -aX; + while(displayObject) + { + if(displayObject.vcount === PIXI.visibleCount) + { + width = displayObject.texture.frame.width; + height = displayObject.texture.frame.height; - h0 = height * (1-aY); - h1 = height * -aY; + // TODO trim?? + aX = displayObject.anchor.x;// - displayObject.texture.trim.x + aY = displayObject.anchor.y; //- displayObject.texture.trim.y + w0 = width * (1-aX); + w1 = width * -aX; - index = indexRun * 8; + h0 = height * (1-aY); + h1 = height * -aY; - worldTransform = displayObject.worldTransform; + index = indexRun * 8; - a = worldTransform[0]; - b = worldTransform[3]; - c = worldTransform[1]; - d = worldTransform[4]; - tx = worldTransform[2]; - ty = worldTransform[5]; + worldTransform = displayObject.worldTransform; - verticies[index + 0 ] = a * w1 + c * h1 + tx; - verticies[index + 1 ] = d * h1 + b * w1 + ty; + a = worldTransform[0]; + b = worldTransform[3]; + c = worldTransform[1]; + d = worldTransform[4]; + tx = worldTransform[2]; + ty = worldTransform[5]; - verticies[index + 2 ] = a * w0 + c * h1 + tx; - verticies[index + 3 ] = d * h1 + b * w0 + ty; + verticies[index + 0 ] = a * w1 + c * h1 + tx; + verticies[index + 1 ] = d * h1 + b * w1 + ty; - verticies[index + 4 ] = a * w0 + c * h0 + tx; - verticies[index + 5 ] = d * h0 + b * w0 + ty; + verticies[index + 2 ] = a * w0 + c * h1 + tx; + verticies[index + 3 ] = d * h1 + b * w0 + ty; - verticies[index + 6] = a * w1 + c * h0 + tx; - verticies[index + 7] = d * h0 + b * w1 + ty; + verticies[index + 4 ] = a * w0 + c * h0 + tx; + verticies[index + 5 ] = d * h0 + b * w0 + ty; - if(displayObject.updateFrame || displayObject.texture.updateFrame) - { - this.dirtyUVS = true; + verticies[index + 6] = a * w1 + c * h0 + tx; + verticies[index + 7] = d * h0 + b * w1 + ty; - var texture = displayObject.texture; + if(displayObject.updateFrame || displayObject.texture.updateFrame) + { + this.dirtyUVS = true; - var frame = texture.frame; - var tw = texture.baseTexture.width; - var th = texture.baseTexture.height; + var texture = displayObject.texture; - uvs[index + 0] = frame.x / tw; - uvs[index +1] = frame.y / th; + var frame = texture.frame; + var tw = texture.baseTexture.width; + var th = texture.baseTexture.height; - uvs[index +2] = (frame.x + frame.width) / tw; - uvs[index +3] = frame.y / th; + uvs[index + 0] = frame.x / tw; + uvs[index +1] = frame.y / th; - uvs[index +4] = (frame.x + frame.width) / tw; - uvs[index +5] = (frame.y + frame.height) / th; + uvs[index +2] = (frame.x + frame.width) / tw; + uvs[index +3] = frame.y / th; - uvs[index +6] = frame.x / tw; - uvs[index +7] = (frame.y + frame.height) / th; + uvs[index +4] = (frame.x + frame.width) / tw; + uvs[index +5] = (frame.y + frame.height) / th; - displayObject.updateFrame = false; - } + uvs[index +6] = frame.x / tw; + uvs[index +7] = (frame.y + frame.height) / th; - // TODO this probably could do with some optimisation.... - if(displayObject.cacheAlpha != displayObject.worldAlpha) - { - displayObject.cacheAlpha = displayObject.worldAlpha; + displayObject.updateFrame = false; + } - var colorIndex = indexRun * 4; - colors[colorIndex] = colors[colorIndex + 1] = colors[colorIndex + 2] = colors[colorIndex + 3] = displayObject.worldAlpha; - this.dirtyColors = true; - } - } - else - { - index = indexRun * 8; + // TODO this probably could do with some optimisation.... + if(displayObject.cacheAlpha !== displayObject.worldAlpha) + { + displayObject.cacheAlpha = displayObject.worldAlpha; - verticies[index + 0 ] = verticies[index + 1 ] = verticies[index + 2 ] = verticies[index + 3 ] = verticies[index + 4 ] = verticies[index + 5 ] = verticies[index + 6] = verticies[index + 7] = 0; - } + var colorIndex = indexRun * 4; + colors[colorIndex] = colors[colorIndex + 1] = colors[colorIndex + 2] = colors[colorIndex + 3] = displayObject.worldAlpha; + this.dirtyColors = true; + } + } + else + { + index = indexRun * 8; - indexRun++; - displayObject = displayObject.__next; - } -} + verticies[index + 0 ] = verticies[index + 1 ] = verticies[index + 2 ] = verticies[index + 3 ] = verticies[index + 4 ] = verticies[index + 5 ] = verticies[index + 6] = verticies[index + 7] = 0; + } + + indexRun++; + displayObject = displayObject.__next; + } +}; /** * Draws the batch to the frame buffer @@ -4466,41 +4413,42 @@ PIXI.WebGLBatch.prototype.update = function() */ PIXI.WebGLBatch.prototype.render = function(start, end) { - start = start || 0; + start = start || 0; - if(end == undefined)end = this.size; - - if(this.dirty) - { - this.refresh(); - this.dirty = false; - } + if(end === undefined) + end = this.size; - if (this.size === 0)return; + if(this.dirty) + { + this.refresh(); + this.dirty = false; + } - this.update(); - var gl = this.gl; + if (this.size === 0)return; - //TODO optimize this! + this.update(); + var gl = this.gl; - var shaderProgram = PIXI.defaultShader; - - //gl.useProgram(shaderProgram); + //TODO optimize this! - // update the verts.. - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - // ok.. - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.verticies) + var shaderProgram = PIXI.defaultShader; + + //gl.useProgram(shaderProgram); + + // update the verts.. + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + // ok.. + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.verticies); gl.vertexAttribPointer(shaderProgram.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - // update the uvs - //var isDefault = (shaderProgram == PIXI.shaderProgram) + // update the uvs + //var isDefault = (shaderProgram == PIXI.shaderProgram) - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); if(this.dirtyUVS) { - this.dirtyUVS = false; - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs); + this.dirtyUVS = false; + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs); } gl.vertexAttribPointer(shaderProgram.aTextureCoord, 2, gl.FLOAT, false, 0, 0); @@ -4508,24 +4456,24 @@ PIXI.WebGLBatch.prototype.render = function(start, end) gl.activeTexture(gl.TEXTURE0); gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture); - // update color! - gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); + // update color! + gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer); - if(this.dirtyColors) + if(this.dirtyColors) { - this.dirtyColors = false; - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.colors); - } + this.dirtyColors = false; + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.colors); + } gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0); - // dont need to upload! + // dont need to upload! gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - var len = end - start; + var len = end - start; // DRAW THAT this! gl.drawElements(gl.TRIANGLES, len * 6, gl.UNSIGNED_SHORT, start * 2 * 6 ); -} +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 @@ -4534,518 +4482,496 @@ PIXI.WebGLBatch.prototype.render = function(start, end) PIXI.WebGLFilterManager = function(transparent) { - this.transparent = transparent; - - this.filterStack = []; - this.texturePool = []; - - this.offsetX = 0; - this.offsetY = 0; - - this.initShaderBuffers(); -} + this.transparent = transparent; + + this.filterStack = []; + this.texturePool = []; + + this.offsetX = 0; + this.offsetY = 0; + + this.initShaderBuffers(); +}; // API PIXI.WebGLFilterManager.prototype.begin = function(projection, buffer) { - this.width = projection.x * 2; - this.height = -projection.y * 2; - this.buffer = buffer; -} + this.width = projection.x * 2; + this.height = -projection.y * 2; + this.buffer = buffer; +}; PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock) { - var gl = PIXI.gl; + var gl = PIXI.gl; - // filter program - // OPTIMISATION - the first filter is free if its a simple color change? - this.filterStack.push(filterBlock); + // filter program + // OPTIMISATION - the first filter is free if its a simple color change? + this.filterStack.push(filterBlock); - var filter = filterBlock.filterPasses[0]; + var filter = filterBlock.filterPasses[0]; - + this.offsetX += filterBlock.target.filterArea.x; + this.offsetY += filterBlock.target.filterArea.y; - this.offsetX += filterBlock.target.filterArea.x; - this.offsetY += filterBlock.target.filterArea.y; - - - - - - var texture = this.texturePool.pop(); - if(!texture)texture = new PIXI.FilterTexture(this.width, this.height); - - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - this.getBounds(filterBlock.target); - - // addpadding? - //displayObject.filterArea.x + var texture = this.texturePool.pop(); + if(!texture) + { + texture = new PIXI.FilterTexture(this.width, this.height); + } + else + { + texture.resize(this.width, this.height); + } - var filterArea = filterBlock.target.filterArea; + gl.bindTexture(gl.TEXTURE_2D, texture.texture); - var padidng = filter.padding; - filterArea.x -= padidng; - filterArea.y -= padidng; - filterArea.width += padidng * 2; - filterArea.height += padidng * 2; + this.getBounds(filterBlock.target); - // cap filter to screen size.. - if(filterArea.x < 0)filterArea.x = 0; - if(filterArea.width > this.width)filterArea.width = this.width; - if(filterArea.y < 0)filterArea.y = 0; - if(filterArea.height > this.height)filterArea.height = this.height; + var filterArea = filterBlock.target.filterArea; + var padidng = filter.padding; + filterArea.x -= padidng; + filterArea.y -= padidng; + filterArea.width += padidng * 2; + filterArea.height += padidng * 2; - //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - - // console.log(filterArea) - // set view port - gl.viewport(0, 0, filterArea.width, filterArea.height); - - PIXI.projection.x = filterArea.width/2; - PIXI.projection.y = -filterArea.height/2; - - PIXI.offset.x = -filterArea.x; - PIXI.offset.y = -filterArea.y; + // cap filter to screen size.. + if(filterArea.x < 0)filterArea.x = 0; + if(filterArea.width > this.width)filterArea.width = this.width; + if(filterArea.y < 0)filterArea.y = 0; + if(filterArea.height > this.height)filterArea.height = this.height; - //console.log(PIXI.defaultShader.projectionVector) - // update projection - gl.uniform2f(PIXI.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); - gl.uniform2f(PIXI.defaultShader.offsetVector, -filterArea.x, -filterArea.y); - //PIXI.primitiveProgram + //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer); - gl.colorMask(true, true, true, true); - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - - //filter.texture = texture; - filterBlock._glFilterTexture = texture; + // set view port + gl.viewport(0, 0, filterArea.width, filterArea.height); - //console.log("PUSH") -} + PIXI.projection.x = filterArea.width/2; + PIXI.projection.y = -filterArea.height/2; + + PIXI.offset.x = -filterArea.x; + PIXI.offset.y = -filterArea.y; + + // update projection + gl.uniform2f(PIXI.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2); + gl.uniform2f(PIXI.defaultShader.offsetVector, -filterArea.x, -filterArea.y); + //PIXI.primitiveProgram + + gl.colorMask(true, true, true, true); + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + + filterBlock._glFilterTexture = texture; +}; PIXI.WebGLFilterManager.prototype.popFilter = function() { - - var gl = PIXI.gl; - - var filterBlock = this.filterStack.pop(); + var gl = PIXI.gl; + var filterBlock = this.filterStack.pop(); + var filterArea = filterBlock.target.filterArea; + var texture = filterBlock._glFilterTexture; + + if(filterBlock.filterPasses.length > 1) + { + gl.viewport(0, 0, filterArea.width, filterArea.height); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + + this.vertexArray[0] = 0; + this.vertexArray[1] = filterArea.height; + + this.vertexArray[2] = filterArea.width; + this.vertexArray[3] = filterArea.height; + + this.vertexArray[4] = 0; + this.vertexArray[5] = 0; + + this.vertexArray[6] = filterArea.width; + this.vertexArray[7] = 0; + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + // nnow set the uvs.. + this.uvArray[2] = filterArea.width/this.width; + this.uvArray[5] = filterArea.height/this.height; + this.uvArray[6] = filterArea.width/this.width; + this.uvArray[7] = filterArea.height/this.height; + + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); + + var inputTexture = texture; + var outputTexture = this.texturePool.pop(); + if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.width, this.height); + + // need to clear this FBO as it may have some left over elements from a prvious filter. + gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); + gl.clear(gl.COLOR_BUFFER_BIT); + + gl.disable(gl.BLEND); + + for (var i = 0; i < filterBlock.filterPasses.length-1; i++) + { + var filterPass = filterBlock.filterPasses[i]; + + gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); + + // set texture + gl.activeTexture(gl.TEXTURE0); + gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); + + // draw texture.. + //filterPass.applyFilterPass(filterArea.width, filterArea.height); + this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); + + // swap the textures.. + var temp = inputTexture; + inputTexture = outputTexture; + outputTexture = temp; + } + + gl.enable(gl.BLEND); + + texture = inputTexture; + this.texturePool.push(outputTexture); + } + + var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; + + this.offsetX -= filterArea.x; + this.offsetY -= filterArea.y; + + + var sizeX = this.width; + var sizeY = this.height; + + var offsetX = 0; + var offsetY = 0; + + var buffer = this.buffer; + + // time to render the filters texture to the previous scene + if(this.filterStack.length === 0) + { + gl.colorMask(true, true, true, this.transparent); + } + else + { + var currentFilter = this.filterStack[this.filterStack.length-1]; + filterArea = currentFilter.target.filterArea; + + sizeX = filterArea.width; + sizeY = filterArea.height; + + offsetX = filterArea.x; + offsetY = filterArea.y; + + buffer = currentFilter._glFilterTexture.frameBuffer; + } - var filterArea = filterBlock.target.filterArea; + // TODO need toremove thease global elements.. + PIXI.projection.x = sizeX/2; + PIXI.projection.y = -sizeY/2; - var texture = filterBlock._glFilterTexture; + PIXI.offset.x = offsetX; + PIXI.offset.y = offsetY; - if(filterBlock.filterPasses.length > 1) - { - gl.viewport(0, 0, filterArea.width, filterArea.height); + filterArea = filterBlock.target.filterArea; - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = 0; - this.vertexArray[1] = filterArea.height; - - this.vertexArray[2] = filterArea.width; - this.vertexArray[3] = filterArea.height; - - this.vertexArray[4] = 0; - this.vertexArray[5] = 0; - - this.vertexArray[6] = filterArea.width; - this.vertexArray[7] = 0; + var x = filterArea.x-offsetX; + var y = filterArea.y-offsetY; + // update the buffers.. + // make sure to flip the y! + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); + this.vertexArray[0] = x; + this.vertexArray[1] = y + filterArea.height; - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - // nnow set the uvs.. - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); + this.vertexArray[2] = x + filterArea.width; + this.vertexArray[3] = y + filterArea.height; - var inputTexture = texture; - var outputTexture = this.texturePool.pop(); - if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.width, this.height); - - // need to clear this FBO as it may have some left over elements from a prvious filter. - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - gl.clear(gl.COLOR_BUFFER_BIT); - - gl.disable(gl.BLEND); - - for (var i = 0; i < filterBlock.filterPasses.length-1; i++) - { - var filterPass = filterBlock.filterPasses[i]; - - gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer ); - - // set texture - gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture); - - // draw texture.. - //filterPass.applyFilterPass(filterArea.width, filterArea.height); - this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height); + this.vertexArray[4] = x; + this.vertexArray[5] = y; - // swap the textures.. - var temp = inputTexture; - inputTexture = outputTexture; - outputTexture = temp; - - }; + this.vertexArray[6] = x + filterArea.width; + this.vertexArray[7] = y; - gl.enable(gl.BLEND); + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - texture = inputTexture; - this.texturePool.push(outputTexture); - } + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1]; - - this.offsetX -= filterArea.x; - this.offsetY -= filterArea.y; + this.uvArray[2] = filterArea.width/this.width; + this.uvArray[5] = filterArea.height/this.height; + this.uvArray[6] = filterArea.width/this.width; + this.uvArray[7] = filterArea.height/this.height; - - var sizeX = this.width; - var sizeY = this.height; - - var offsetX = 0; - var offsetY = 0; - - var buffer = this.buffer; - - // time to render the filters texture to the previous scene - if(this.filterStack.length === 0) - { - gl.colorMask(true, true, true, this.transparent); - } - else - { - var currentFilter = this.filterStack[this.filterStack.length-1]; - var filterArea = currentFilter.target.filterArea; - - sizeX = filterArea.width; - sizeY = filterArea.height; - - offsetX = filterArea.x; - offsetY = filterArea.y; - - buffer = currentFilter._glFilterTexture.frameBuffer; - } - - + gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - // TODO need toremove thease global elements.. - PIXI.projection.x = sizeX/2; - PIXI.projection.y = -sizeY/2; + gl.viewport(0, 0, sizeX, sizeY); + // bind the buffer + gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - PIXI.offset.x = offsetX; - PIXI.offset.y = offsetY; - - - var filterArea = filterBlock.target.filterArea; - var x = filterArea.x-offsetX; - var y = filterArea.y-offsetY; - - // update the buffers.. - // make sure to flip the y! - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - - this.vertexArray[0] = x; - this.vertexArray[1] = y + filterArea.height; - - this.vertexArray[2] = x + filterArea.width; - this.vertexArray[3] = y + filterArea.height; - - this.vertexArray[4] = x; - this.vertexArray[5] = y; - - this.vertexArray[6] = x + filterArea.width; - this.vertexArray[7] = y; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - - this.uvArray[2] = filterArea.width/this.width; - this.uvArray[5] = filterArea.height/this.height; - this.uvArray[6] = filterArea.width/this.width; - this.uvArray[7] = filterArea.height/this.height; - - gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray); - - gl.viewport(0, 0, sizeX, sizeY); - // bind the buffer - gl.bindFramebuffer(gl.FRAMEBUFFER, buffer ); - - // set texture + // set texture gl.activeTexture(gl.TEXTURE0); - gl.bindTexture(gl.TEXTURE_2D, texture.texture); - - // apply! - //filter.applyFilterPass(sizeX, sizeY); - this.applyFilterPass(filter, filterArea, sizeX, sizeY); + gl.bindTexture(gl.TEXTURE_2D, texture.texture); - // now restore the regular shader.. + // apply! + //filter.applyFilterPass(sizeX, sizeY); + this.applyFilterPass(filter, filterArea, sizeX, sizeY); + + // now restore the regular shader.. gl.useProgram(PIXI.defaultShader.program); - gl.uniform2f(PIXI.defaultShader.projectionVector, sizeX/2, -sizeY/2); - gl.uniform2f(PIXI.defaultShader.offsetVector, -offsetX, -offsetY); + gl.uniform2f(PIXI.defaultShader.projectionVector, sizeX/2, -sizeY/2); + gl.uniform2f(PIXI.defaultShader.offsetVector, -offsetX, -offsetY); - // return the texture to the pool - this.texturePool.push(texture); - filterBlock._glFilterTexture = null; -} + // return the texture to the pool + this.texturePool.push(texture); + filterBlock._glFilterTexture = null; +}; PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea, width, height) { - // use program - var gl = PIXI.gl; + // use program + var gl = PIXI.gl; + var shader = filter.shader; - if(!filter.shader) - { - var shader = new PIXI.PixiShader(); - - shader.fragmentSrc = filter.fragmentSrc; - shader.uniforms = filter.uniforms; - shader.init(); - - filter.shader = shader; - } + if(!shader) + { + shader = new PIXI.PixiShader(); - var shader = filter.shader; - - // set the shader - gl.useProgram(shader.program); + shader.fragmentSrc = filter.fragmentSrc; + shader.uniforms = filter.uniforms; + shader.init(); - gl.uniform2f(shader.projectionVector, width/2, -height/2); - gl.uniform2f(shader.offsetVector, 0,0) + filter.shader = shader; + } - if(filter.uniforms.dimensions) - { - //console.log(filter.uniforms.dimensions) - filter.uniforms.dimensions.value[0] = this.width;//width; - filter.uniforms.dimensions.value[1] = this.height;//height; - filter.uniforms.dimensions.value[2] = this.vertexArray[0]; - filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; - // console.log(this.vertexArray[5]) - } + // set the shader + gl.useProgram(shader.program); - shader.syncUniforms(); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.uniform2f(shader.projectionVector, width/2, -height/2); + gl.uniform2f(shader.offsetVector, 0,0); + + if(filter.uniforms.dimensions) + { + filter.uniforms.dimensions.value[0] = this.width;//width; + filter.uniforms.dimensions.value[1] = this.height;//height; + filter.uniforms.dimensions.value[2] = this.vertexArray[0]; + filter.uniforms.dimensions.value[3] = this.vertexArray[5];//filterArea.height; + } + + shader.syncUniforms(); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0); - + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - - // draw the filter... + + // draw the filter... gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 ); -} +}; PIXI.WebGLFilterManager.prototype.initShaderBuffers = function() { - var gl = PIXI.gl; - - // create some buffers - this.vertexBuffer = gl.createBuffer(); - this.uvBuffer = gl.createBuffer(); - this.indexBuffer = gl.createBuffer(); - - // bind and upload the vertexs.. - // keep a refferance to the vertexFloatData.. - this.vertexArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); - gl.bufferData( - gl.ARRAY_BUFFER, - this.vertexArray, + var gl = PIXI.gl; + + // create some buffers + this.vertexBuffer = gl.createBuffer(); + this.uvBuffer = gl.createBuffer(); + this.indexBuffer = gl.createBuffer(); + + // bind and upload the vertexs.. + // keep a refferance to the vertexFloatData.. + this.vertexArray = new Float32Array([0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + 1.0, 1.0]); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer); + gl.bufferData( + gl.ARRAY_BUFFER, + this.vertexArray, gl.STATIC_DRAW); - - + + // bind and upload the uv buffer - this.uvArray = new Float32Array([0.0, 0.0, - 1.0, 0.0, - 0.0, 1.0, - 1.0, 1.0]); - - gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); - gl.bufferData( - gl.ARRAY_BUFFER, - this.uvArray, + this.uvArray = new Float32Array([0.0, 0.0, + 1.0, 0.0, + 0.0, 1.0, + 1.0, 1.0]); + + gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer); + gl.bufferData( + gl.ARRAY_BUFFER, + this.uvArray, gl.STATIC_DRAW); - - // bind and upload the index - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); - gl.bufferData( - gl.ELEMENT_ARRAY_BUFFER, - new Uint16Array([0, 1, 2, 1, 3, 2]), + + // bind and upload the index + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer); + gl.bufferData( + gl.ELEMENT_ARRAY_BUFFER, + new Uint16Array([0, 1, 2, 1, 3, 2]), gl.STATIC_DRAW); -} +}; PIXI.WebGLFilterManager.prototype.getBounds = function(displayObject) { - // time to get the width and height of the object! - var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, doTest; - var a, b, c, d, tx, ty, x1, x2, x3, x4, y1, y2, y3, y4; + // time to get the width and height of the object! + var worldTransform, width, height, aX, aY, w0, w1, h0, h1, doTest; + var a, b, c, d, tx, ty, x1, x2, x3, x4, y1, y2, y3, y4; - var tempObject = displayObject.first; - var testObject = displayObject.last._iNext; - - var maxX = -Infinity; - var maxY = -Infinity; - - var minX = Infinity; - var minY = Infinity; - - do - { - // TODO can be optimized! - what if there is no scale / rotation? - - if(tempObject.visible) - { - if(tempObject instanceof PIXI.Sprite) - { - width = tempObject.texture.frame.width; - height = tempObject.texture.frame.height; + var tempObject = displayObject.first; + var testObject = displayObject.last._iNext; - // TODO trim?? - aX = tempObject.anchor.x; - aY = tempObject.anchor.y; - w0 = width * (1-aX); - w1 = width * -aX; + var maxX = -Infinity; + var maxY = -Infinity; - h0 = height * (1-aY); - h1 = height * -aY; + var minX = Infinity; + var minY = Infinity; - doTest = true; - } - else if(tempObject instanceof PIXI.Graphics) - { - tempObject.updateFilterBounds(); + do + { + // TODO can be optimized! - what if there is no scale / rotation? - var bounds = tempObject.bounds; + if(tempObject.visible) + { + if(tempObject instanceof PIXI.Sprite) + { + width = tempObject.texture.frame.width; + height = tempObject.texture.frame.height; - width = bounds.width; - height = bounds.height; + // TODO trim?? + aX = tempObject.anchor.x; + aY = tempObject.anchor.y; + w0 = width * (1-aX); + w1 = width * -aX; - w0 = bounds.x - w1 = bounds.x + bounds.width; + h0 = height * (1-aY); + h1 = height * -aY; - h0 = bounds.y - h1 = bounds.y + bounds.height; + doTest = true; + } + else if(tempObject instanceof PIXI.Graphics) + { + tempObject.updateFilterBounds(); - doTest = true; - } - } - - if(doTest) - { - worldTransform = tempObject.worldTransform; + var bounds = tempObject.bounds; - a = worldTransform[0]; - b = worldTransform[3]; - c = worldTransform[1]; - d = worldTransform[4]; - tx = worldTransform[2]; - ty = worldTransform[5]; + width = bounds.width; + height = bounds.height; - x1 = a * w1 + c * h1 + tx; - y1 = d * h1 + b * w1 + ty; + w0 = bounds.x; + w1 = bounds.x + bounds.width; - x2 = a * w0 + c * h1 + tx; - y2 = d * h1 + b * w0 + ty; + h0 = bounds.y; + h1 = bounds.y + bounds.height; - x3 = a * w0 + c * h0 + tx; - y3 = d * h0 + b * w0 + ty; + doTest = true; + } + } - x4 = a * w1 + c * h0 + tx; - y4 = d * h0 + b * w1 + ty; + if(doTest) + { + worldTransform = tempObject.worldTransform; - minX = x1 < minX ? x1 : minX; - minX = x2 < minX ? x2 : minX; - minX = x3 < minX ? x3 : minX; - minX = x4 < minX ? x4 : minX; - - minY = y1 < minY ? y1 : minY; - minY = y2 < minY ? y2 : minY; - minY = y3 < minY ? y3 : minY; - minY = y4 < minY ? y4 : minY; - - maxX = x1 > maxX ? x1 : maxX; - maxX = x2 > maxX ? x2 : maxX; - maxX = x3 > maxX ? x3 : maxX; - maxX = x4 > maxX ? x4 : maxX; - - maxY = y1 > maxY ? y1 : maxY; - maxY = y2 > maxY ? y2 : maxY; - maxY = y3 > maxY ? y3 : maxY; - maxY = y4 > maxY ? y4 : maxY; - } + a = worldTransform[0]; + b = worldTransform[3]; + c = worldTransform[1]; + d = worldTransform[4]; + tx = worldTransform[2]; + ty = worldTransform[5]; - doTest = false; - tempObject = tempObject._iNext; + x1 = a * w1 + c * h1 + tx; + y1 = d * h1 + b * w1 + ty; - } - while(tempObject != testObject) - - // maximum bounds is the size of the screen.. - //minX = minX > 0 ? minX : 0; - //minY = minY > 0 ? minY : 0; + x2 = a * w0 + c * h1 + tx; + y2 = d * h1 + b * w0 + ty; - displayObject.filterArea.x = minX; - displayObject.filterArea.y = minY; + x3 = a * w0 + c * h0 + tx; + y3 = d * h0 + b * w0 + ty; -// console.log(maxX+ " : " + minX) - displayObject.filterArea.width = maxX - minX; - displayObject.filterArea.height = maxY - minY; -} + x4 = a * w1 + c * h0 + tx; + y4 = d * h0 + b * w1 + ty; + + minX = x1 < minX ? x1 : minX; + minX = x2 < minX ? x2 : minX; + minX = x3 < minX ? x3 : minX; + minX = x4 < minX ? x4 : minX; + + minY = y1 < minY ? y1 : minY; + minY = y2 < minY ? y2 : minY; + minY = y3 < minY ? y3 : minY; + minY = y4 < minY ? y4 : minY; + + maxX = x1 > maxX ? x1 : maxX; + maxX = x2 > maxX ? x2 : maxX; + maxX = x3 > maxX ? x3 : maxX; + maxX = x4 > maxX ? x4 : maxX; + + maxY = y1 > maxY ? y1 : maxY; + maxY = y2 > maxY ? y2 : maxY; + maxY = y3 > maxY ? y3 : maxY; + maxY = y4 > maxY ? y4 : maxY; + } + + doTest = false; + tempObject = tempObject._iNext; + + } + while(tempObject !== testObject); + + displayObject.filterArea.x = minX; + displayObject.filterArea.y = minY; + + displayObject.filterArea.width = maxX - minX; + displayObject.filterArea.height = maxY - minY; +}; PIXI.FilterTexture = function(width, height) { - var gl = PIXI.gl; - + var gl = PIXI.gl; + // next time to create a frame buffer and texture - this.frameBuffer = gl.createFramebuffer(); + this.frameBuffer = gl.createFramebuffer(); this.texture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, this.texture); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer ); - - gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer ); - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0); - - this.resize(width, height); -} + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.framebuffer ); + + gl.bindFramebuffer(gl.FRAMEBUFFER, this.frameBuffer ); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.texture, 0); + + this.resize(width, height); +}; PIXI.FilterTexture.prototype.resize = function(width, height) { - this.width = width; - this.height = height; + if(this.width === width && this.height === height) return; - var gl = PIXI.gl; + this.width = width; + this.height = height; + + var gl = PIXI.gl; + + gl.bindTexture(gl.TEXTURE_2D, this.texture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + +}; - gl.bindTexture(gl.TEXTURE_2D, this.texture); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, width, height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - -} /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -5057,8 +4983,8 @@ PIXI.FilterTexture.prototype.resize = function(width, height) */ PIXI.WebGLGraphics = function() { - -} + +}; /** * Renders the graphics object @@ -5071,62 +4997,61 @@ PIXI.WebGLGraphics = function() */ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection) { - var gl = PIXI.gl; - - if(!graphics._webGL)graphics._webGL = {points:[], indices:[], lastIndex:0, - buffer:gl.createBuffer(), - indexBuffer:gl.createBuffer()}; - - if(graphics.dirty) - { - graphics.dirty = false; - - if(graphics.clearDirty) - { - graphics.clearDirty = false; - - graphics._webGL.lastIndex = 0; - graphics._webGL.points = []; - graphics._webGL.indices = []; - - } - - PIXI.WebGLGraphics.updateGraphics(graphics); - } - - PIXI.activatePrimitiveShader(); - - // This could be speeded up fo sure! - var m = PIXI.mat3.clone(graphics.worldTransform); - - PIXI.mat3.transpose(m); - - // set the matrix transform for the - gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + var gl = PIXI.gl; - gl.uniformMatrix3fv(PIXI.primitiveShader.translationMatrix, false, m); - - gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); - gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); - - gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); - gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); - - gl.vertexAttribPointer(PIXI.primitiveShader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0); - gl.vertexAttribPointer(PIXI.primitiveShader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4); - - // set the index buffer! - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); - + if(!graphics._webGL)graphics._webGL = {points:[], indices:[], lastIndex:0, + buffer:gl.createBuffer(), + indexBuffer:gl.createBuffer()}; - gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); - - PIXI.deactivatePrimitiveShader(); - - - // return to default shader... -// PIXI.activateShader(PIXI.defaultShader); -} + if(graphics.dirty) + { + graphics.dirty = false; + + if(graphics.clearDirty) + { + graphics.clearDirty = false; + + graphics._webGL.lastIndex = 0; + graphics._webGL.points = []; + graphics._webGL.indices = []; + + } + + PIXI.WebGLGraphics.updateGraphics(graphics); + } + + PIXI.activatePrimitiveShader(); + + // This could be speeded up fo sure! + var m = PIXI.mat3.clone(graphics.worldTransform); + + PIXI.mat3.transpose(m); + + // set the matrix transform for the + gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA); + + gl.uniformMatrix3fv(PIXI.primitiveShader.translationMatrix, false, m); + + gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y); + gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y); + + gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha); + gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); + + gl.vertexAttribPointer(PIXI.primitiveShader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0); + gl.vertexAttribPointer(PIXI.primitiveShader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4); + + // set the index buffer! + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); + + + gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 ); + + PIXI.deactivatePrimitiveShader(); + + // return to default shader... +// PIXI.activateShader(PIXI.defaultShader); +}; /** * Updates the graphics object @@ -5138,47 +5063,47 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection) */ PIXI.WebGLGraphics.updateGraphics = function(graphics) { - for (var i=graphics._webGL.lastIndex; i < graphics.graphicsData.length; i++) - { - var data = graphics.graphicsData[i]; - - if(data.type == PIXI.Graphics.POLY) - { - if(data.fill) - { - if(data.points.length>3) - PIXI.WebGLGraphics.buildPoly(data, graphics._webGL); - } - - if(data.lineWidth > 0) - { - PIXI.WebGLGraphics.buildLine(data, graphics._webGL); - } - } - else if(data.type == PIXI.Graphics.RECT) - { - PIXI.WebGLGraphics.buildRectangle(data, graphics._webGL); - } - else if(data.type == PIXI.Graphics.CIRC || data.type == PIXI.Graphics.ELIP) - { - PIXI.WebGLGraphics.buildCircle(data, graphics._webGL); - } - }; - - graphics._webGL.lastIndex = graphics.graphicsData.length; - - var gl = PIXI.gl; + for (var i = graphics._webGL.lastIndex; i < graphics.graphicsData.length; i++) + { + var data = graphics.graphicsData[i]; - graphics._webGL.glPoints = new Float32Array(graphics._webGL.points); - - gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); - gl.bufferData(gl.ARRAY_BUFFER, graphics._webGL.glPoints, gl.STATIC_DRAW); - - graphics._webGL.glIndicies = new Uint16Array(graphics._webGL.indices); - - gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); + if(data.type === PIXI.Graphics.POLY) + { + if(data.fill) + { + if(data.points.length>3) + PIXI.WebGLGraphics.buildPoly(data, graphics._webGL); + } + + if(data.lineWidth > 0) + { + PIXI.WebGLGraphics.buildLine(data, graphics._webGL); + } + } + else if(data.type === PIXI.Graphics.RECT) + { + PIXI.WebGLGraphics.buildRectangle(data, graphics._webGL); + } + else if(data.type === PIXI.Graphics.CIRC || data.type === PIXI.Graphics.ELIP) + { + PIXI.WebGLGraphics.buildCircle(data, graphics._webGL); + } + } + + graphics._webGL.lastIndex = graphics.graphicsData.length; + + var gl = PIXI.gl; + + graphics._webGL.glPoints = new Float32Array(graphics._webGL.points); + + gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer); + gl.bufferData(gl.ARRAY_BUFFER, graphics._webGL.glPoints, gl.STATIC_DRAW); + + graphics._webGL.glIndicies = new Uint16Array(graphics._webGL.indices); + + gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.glIndicies, gl.STATIC_DRAW); -} +}; /** * Builds a rectangle to draw @@ -5191,59 +5116,58 @@ PIXI.WebGLGraphics.updateGraphics = function(graphics) */ PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData) { - // --- // - // need to convert points to a nice regular data - // - var rectData = graphicsData.points; - var x = rectData[0]; - var y = rectData[1]; - var width = rectData[2]; - var height = rectData[3]; - - - if(graphicsData.fill) - { - var color = HEXtoRGB(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; - - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var verts = webGLData.points; - var indices = webGLData.indices; - - var vertPos = verts.length/6; - - // start - verts.push(x, y); - verts.push(r, g, b, alpha); - - verts.push(x + width, y); - verts.push(r, g, b, alpha); - - verts.push(x , y + height); - verts.push(r, g, b, alpha); - - verts.push(x + width, y + height); - verts.push(r, g, b, alpha); - - // insert 2 dead triangles.. - indices.push(vertPos, vertPos, vertPos+1, vertPos+2, vertPos+3, vertPos+3) - } - - if(graphicsData.lineWidth) - { - graphicsData.points = [x, y, - x + width, y, - x + width, y + height, - x, y + height, - x, y]; - - PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); - } - -} + // --- // + // need to convert points to a nice regular data + // + var rectData = graphicsData.points; + var x = rectData[0]; + var y = rectData[1]; + var width = rectData[2]; + var height = rectData[3]; + + + if(graphicsData.fill) + { + var color = PIXI.hex2rgb(graphicsData.fillColor); + var alpha = graphicsData.fillAlpha; + + var r = color[0] * alpha; + var g = color[1] * alpha; + var b = color[2] * alpha; + + var verts = webGLData.points; + var indices = webGLData.indices; + + var vertPos = verts.length/6; + + // start + verts.push(x, y); + verts.push(r, g, b, alpha); + + verts.push(x + width, y); + verts.push(r, g, b, alpha); + + verts.push(x , y + height); + verts.push(r, g, b, alpha); + + verts.push(x + width, y + height); + verts.push(r, g, b, alpha); + + // insert 2 dead triangles.. + indices.push(vertPos, vertPos, vertPos+1, vertPos+2, vertPos+3, vertPos+3); + } + + if(graphicsData.lineWidth) + { + graphicsData.points = [x, y, + x + width, y, + x + width, y + height, + x, y + height, + x, y]; + + PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); + } +}; /** * Builds a circle to draw @@ -5256,62 +5180,63 @@ PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData) */ PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData) { - // --- // - // need to convert points to a nice regular data - // - var rectData = graphicsData.points; - var x = rectData[0]; - var y = rectData[1]; - var width = rectData[2]; - var height = rectData[3]; - - var totalSegs = 40; - var seg = (Math.PI * 2) / totalSegs ; - - if(graphicsData.fill) - { - var color = HEXtoRGB(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; + // --- // + // need to convert points to a nice regular data + // + var rectData = graphicsData.points; + var x = rectData[0]; + var y = rectData[1]; + var width = rectData[2]; + var height = rectData[3]; - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var verts = webGLData.points; - var indices = webGLData.indices; - - var vecPos = verts.length/6; - - indices.push(vecPos); - - for (var i=0; i < totalSegs + 1 ; i++) - { - verts.push(x,y, r, g, b, alpha); - - verts.push(x + Math.sin(seg * i) * width, - y + Math.cos(seg * i) * height, - r, g, b, alpha); - - indices.push(vecPos++, vecPos++); - }; - - indices.push(vecPos-1); - } - - if(graphicsData.lineWidth) - { - graphicsData.points = []; - - for (var i=0; i < totalSegs + 1; i++) - { - graphicsData.points.push(x + Math.sin(seg * i) * width, - y + Math.cos(seg * i) * height) - }; - - PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); - } - -} + var totalSegs = 40; + var seg = (Math.PI * 2) / totalSegs ; + + var i = 0; + + if(graphicsData.fill) + { + var color = PIXI.hex2rgb(graphicsData.fillColor); + var alpha = graphicsData.fillAlpha; + + var r = color[0] * alpha; + var g = color[1] * alpha; + var b = color[2] * alpha; + + var verts = webGLData.points; + var indices = webGLData.indices; + + var vecPos = verts.length/6; + + indices.push(vecPos); + + for (i = 0; i < totalSegs + 1 ; i++) + { + verts.push(x,y, r, g, b, alpha); + + verts.push(x + Math.sin(seg * i) * width, + y + Math.cos(seg * i) * height, + r, g, b, alpha); + + indices.push(vecPos++, vecPos++); + } + + indices.push(vecPos-1); + } + + if(graphicsData.lineWidth) + { + graphicsData.points = []; + + for (i = 0; i < totalSegs + 1; i++) + { + graphicsData.points.push(x + Math.sin(seg * i) * width, + y + Math.cos(seg * i) * height); + } + + PIXI.WebGLGraphics.buildLine(graphicsData, webGLData); + } +}; /** * Builds a line to draw @@ -5324,205 +5249,204 @@ PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData) */ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData) { - // TODO OPTIMISE! - - var wrap = true; - var points = graphicsData.points; - if(points.length === 0)return; - - // if the line width is an odd number add 0.5 to align to a whole pixel - if(graphicsData.lineWidth%2) - { - for (var i = 0; i < points.length; i++) { - points[i] += 0.5; - }; - } + // TODO OPTIMISE! + var i = 0; - // get first and last point.. figure out the middle! - var firstPoint = new PIXI.Point( points[0], points[1] ); - var lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] ); - - // if the first point is the last point - goona have issues :) - if(firstPoint.x == lastPoint.x && firstPoint.y == lastPoint.y) - { - points.pop(); - points.pop(); - - lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] ); - - var midPointX = lastPoint.x + (firstPoint.x - lastPoint.x) *0.5; - var midPointY = lastPoint.y + (firstPoint.y - lastPoint.y) *0.5; - - points.unshift(midPointX, midPointY); - points.push(midPointX, midPointY) - } - - var verts = webGLData.points; - var indices = webGLData.indices; - var length = points.length / 2; - var indexCount = points.length; - var indexStart = verts.length/6; - - // DRAW the Line - var width = graphicsData.lineWidth / 2; - - // sort color - var color = HEXtoRGB(graphicsData.lineColor); - var alpha = graphicsData.lineAlpha; - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var p1x, p1y, p2x, p2y, p3x, p3y; - var perpx, perpy, perp2x, perp2y, perp3x, perp3y; - var ipx, ipy; - var a1, b1, c1, a2, b2, c2; - var denom, pdist, dist; - - p1x = points[0]; - p1y = points[1]; - - p2x = points[2]; - p2y = points[3]; - - perpx = -(p1y - p2y); - perpy = p1x - p2x; - - dist = Math.sqrt(perpx*perpx + perpy*perpy); - - perpx /= dist; - perpy /= dist; - perpx *= width; - perpy *= width; - - // start - verts.push(p1x - perpx , p1y - perpy, - r, g, b, alpha); - - verts.push(p1x + perpx , p1y + perpy, - r, g, b, alpha); - - for (var i = 1; i < length-1; i++) - { - p1x = points[(i-1)*2]; - p1y = points[(i-1)*2 + 1]; - - p2x = points[(i)*2] - p2y = points[(i)*2 + 1] - - p3x = points[(i+1)*2]; - p3y = points[(i+1)*2 + 1]; - - perpx = -(p1y - p2y); - perpy = p1x - p2x; - - dist = Math.sqrt(perpx*perpx + perpy*perpy); - perpx /= dist; - perpy /= dist; - perpx *= width; - perpy *= width; + var points = graphicsData.points; + if(points.length === 0)return; - perp2x = -(p2y - p3y); - perp2y = p2x - p3x; - - dist = Math.sqrt(perp2x*perp2x + perp2y*perp2y); - perp2x /= dist; - perp2y /= dist; - perp2x *= width; - perp2y *= width; - - a1 = (-perpy + p1y) - (-perpy + p2y); - b1 = (-perpx + p2x) - (-perpx + p1x); - c1 = (-perpx + p1x) * (-perpy + p2y) - (-perpx + p2x) * (-perpy + p1y); - a2 = (-perp2y + p3y) - (-perp2y + p2y); - b2 = (-perp2x + p2x) - (-perp2x + p3x); - c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y); - - denom = a1*b2 - a2*b1; + // if the line width is an odd number add 0.5 to align to a whole pixel + if(graphicsData.lineWidth%2) + { + for (i = 0; i < points.length; i++) { + points[i] += 0.5; + } + } - if(Math.abs(denom) < 0.1 ) - { - - denom+=10.1; - verts.push(p2x - perpx , p2y - perpy, - r, g, b, alpha); - - verts.push(p2x + perpx , p2y + perpy, - r, g, b, alpha); - - continue; - } - - px = (b1*c2 - b2*c1)/denom; - py = (a2*c1 - a1*c2)/denom; - - - pdist = (px -p2x) * (px -p2x) + (py -p2y) + (py -p2y); - + // get first and last point.. figure out the middle! + var firstPoint = new PIXI.Point( points[0], points[1] ); + var lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] ); - if(pdist > 140 * 140) - { - perp3x = perpx - perp2x; - perp3y = perpy - perp2y; - - dist = Math.sqrt(perp3x*perp3x + perp3y*perp3y); - perp3x /= dist; - perp3y /= dist; - perp3x *= width; - perp3y *= width; - - verts.push(p2x - perp3x, p2y -perp3y); - verts.push(r, g, b, alpha); - - verts.push(p2x + perp3x, p2y +perp3y); - verts.push(r, g, b, alpha); - - verts.push(p2x - perp3x, p2y -perp3y); - verts.push(r, g, b, alpha); - - indexCount++; - } - else - { + // if the first point is the last point - goona have issues :) + if(firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y) + { + points.pop(); + points.pop(); - verts.push(px , py); - verts.push(r, g, b, alpha); - - verts.push(p2x - (px-p2x), p2y - (py - p2y)); - verts.push(r, g, b, alpha); - } - } - - p1x = points[(length-2)*2] - p1y = points[(length-2)*2 + 1] - - p2x = points[(length-1)*2] - p2y = points[(length-1)*2 + 1] - - perpx = -(p1y - p2y) - perpy = p1x - p2x; - - dist = Math.sqrt(perpx*perpx + perpy*perpy); - perpx /= dist; - perpy /= dist; - perpx *= width; - perpy *= width; - - verts.push(p2x - perpx , p2y - perpy) - verts.push(r, g, b, alpha); - - verts.push(p2x + perpx , p2y + perpy) - verts.push(r, g, b, alpha); - - indices.push(indexStart); - - for (var i=0; i < indexCount; i++) - { - indices.push(indexStart++); - }; - - indices.push(indexStart-1); -} + lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] ); + + var midPointX = lastPoint.x + (firstPoint.x - lastPoint.x) *0.5; + var midPointY = lastPoint.y + (firstPoint.y - lastPoint.y) *0.5; + + points.unshift(midPointX, midPointY); + points.push(midPointX, midPointY); + } + + var verts = webGLData.points; + var indices = webGLData.indices; + var length = points.length / 2; + var indexCount = points.length; + var indexStart = verts.length/6; + + // DRAW the Line + var width = graphicsData.lineWidth / 2; + + // sort color + var color = PIXI.hex2rgb(graphicsData.lineColor); + var alpha = graphicsData.lineAlpha; + var r = color[0] * alpha; + var g = color[1] * alpha; + var b = color[2] * alpha; + + var px, py, p1x, p1y, p2x, p2y, p3x, p3y; + var perpx, perpy, perp2x, perp2y, perp3x, perp3y; + var a1, b1, c1, a2, b2, c2; + var denom, pdist, dist; + + p1x = points[0]; + p1y = points[1]; + + p2x = points[2]; + p2y = points[3]; + + perpx = -(p1y - p2y); + perpy = p1x - p2x; + + dist = Math.sqrt(perpx*perpx + perpy*perpy); + + perpx /= dist; + perpy /= dist; + perpx *= width; + perpy *= width; + + // start + verts.push(p1x - perpx , p1y - perpy, + r, g, b, alpha); + + verts.push(p1x + perpx , p1y + perpy, + r, g, b, alpha); + + for (i = 1; i < length-1; i++) + { + p1x = points[(i-1)*2]; + p1y = points[(i-1)*2 + 1]; + + p2x = points[(i)*2]; + p2y = points[(i)*2 + 1]; + + p3x = points[(i+1)*2]; + p3y = points[(i+1)*2 + 1]; + + perpx = -(p1y - p2y); + perpy = p1x - p2x; + + dist = Math.sqrt(perpx*perpx + perpy*perpy); + perpx /= dist; + perpy /= dist; + perpx *= width; + perpy *= width; + + perp2x = -(p2y - p3y); + perp2y = p2x - p3x; + + dist = Math.sqrt(perp2x*perp2x + perp2y*perp2y); + perp2x /= dist; + perp2y /= dist; + perp2x *= width; + perp2y *= width; + + a1 = (-perpy + p1y) - (-perpy + p2y); + b1 = (-perpx + p2x) - (-perpx + p1x); + c1 = (-perpx + p1x) * (-perpy + p2y) - (-perpx + p2x) * (-perpy + p1y); + a2 = (-perp2y + p3y) - (-perp2y + p2y); + b2 = (-perp2x + p2x) - (-perp2x + p3x); + c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y); + + denom = a1*b2 - a2*b1; + + if(Math.abs(denom) < 0.1 ) + { + + denom+=10.1; + verts.push(p2x - perpx , p2y - perpy, + r, g, b, alpha); + + verts.push(p2x + perpx , p2y + perpy, + r, g, b, alpha); + + continue; + } + + px = (b1*c2 - b2*c1)/denom; + py = (a2*c1 - a1*c2)/denom; + + + pdist = (px -p2x) * (px -p2x) + (py -p2y) + (py -p2y); + + + if(pdist > 140 * 140) + { + perp3x = perpx - perp2x; + perp3y = perpy - perp2y; + + dist = Math.sqrt(perp3x*perp3x + perp3y*perp3y); + perp3x /= dist; + perp3y /= dist; + perp3x *= width; + perp3y *= width; + + verts.push(p2x - perp3x, p2y -perp3y); + verts.push(r, g, b, alpha); + + verts.push(p2x + perp3x, p2y +perp3y); + verts.push(r, g, b, alpha); + + verts.push(p2x - perp3x, p2y -perp3y); + verts.push(r, g, b, alpha); + + indexCount++; + } + else + { + + verts.push(px , py); + verts.push(r, g, b, alpha); + + verts.push(p2x - (px-p2x), p2y - (py - p2y)); + verts.push(r, g, b, alpha); + } + } + + p1x = points[(length-2)*2]; + p1y = points[(length-2)*2 + 1]; + + p2x = points[(length-1)*2]; + p2y = points[(length-1)*2 + 1]; + + perpx = -(p1y - p2y); + perpy = p1x - p2x; + + dist = Math.sqrt(perpx*perpx + perpy*perpy); + perpx /= dist; + perpy /= dist; + perpx *= width; + perpy *= width; + + verts.push(p2x - perpx , p2y - perpy); + verts.push(r, g, b, alpha); + + verts.push(p2x + perpx , p2y + perpy); + verts.push(r, g, b, alpha); + + indices.push(indexStart); + + for (i = 0; i < indexCount; i++) + { + indices.push(indexStart++); + } + + indices.push(indexStart-1); +}; /** * Builds a polygon to draw @@ -5535,49 +5459,43 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData) */ PIXI.WebGLGraphics.buildPoly = function(graphicsData, webGLData) { - var points = graphicsData.points; - if(points.length < 6)return; - - // get first and last point.. figure out the middle! - var verts = webGLData.points; - var indices = webGLData.indices; - - var length = points.length / 2; - - // sort color - var color = HEXtoRGB(graphicsData.fillColor); - var alpha = graphicsData.fillAlpha; - var r = color[0] * alpha; - var g = color[1] * alpha; - var b = color[2] * alpha; - - var triangles = PIXI.PolyK.Triangulate(points); - - var vertPos = verts.length / 6; - - for (var i=0; i < triangles.length; i+=3) - { - indices.push(triangles[i] + vertPos); - indices.push(triangles[i] + vertPos); - indices.push(triangles[i+1] + vertPos); - indices.push(triangles[i+2] +vertPos); - indices.push(triangles[i+2] + vertPos); - }; - - for (var i = 0; i < length; i++) - { - verts.push(points[i * 2], points[i * 2 + 1], - r, g, b, alpha); - }; -} + var points = graphicsData.points; + if(points.length < 6)return; -function HEXtoRGB(hex) { - return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; -} + // get first and last point.. figure out the middle! + var verts = webGLData.points; + var indices = webGLData.indices; + var length = points.length / 2; + // sort color + var color = PIXI.hex2rgb(graphicsData.fillColor); + var alpha = graphicsData.fillAlpha; + var r = color[0] * alpha; + var g = color[1] * alpha; + var b = color[2] * alpha; + var triangles = PIXI.PolyK.Triangulate(points); + var vertPos = verts.length / 6; + + var i = 0; + + for (i = 0; i < triangles.length; i+=3) + { + indices.push(triangles[i] + vertPos); + indices.push(triangles[i] + vertPos); + indices.push(triangles[i+1] + vertPos); + indices.push(triangles[i+2] +vertPos); + indices.push(triangles[i+2] + vertPos); + } + + for (i = 0; i < length; i++) + { + verts.push(points[i * 2], points[i * 2 + 1], + r, g, b, alpha); + } +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 @@ -5587,7 +5505,7 @@ PIXI._defaultFrame = new PIXI.Rectangle(0,0,1,1); // an instance of the gl context.. // only one at the moment :/ -PIXI.gl; +PIXI.gl = null; /** * the WebGLRenderer is draws the stage and all its content onto a webGL enabled canvas. This renderer @@ -5602,68 +5520,68 @@ PIXI.gl; * @param view {Canvas} the canvas to use as a view, optional * @param transparent=false {Boolean} the transparency of the render view, default false * @param antialias=false {Boolean} sets antialias (only applicable in chrome at the moment) - * + * */ PIXI.WebGLRenderer = function(width, height, view, transparent, antialias) { - // do a catch.. only 1 webGL renderer.. + // do a catch.. only 1 webGL renderer.. - this.transparent = !!transparent; + this.transparent = !!transparent; - this.width = width || 800; - this.height = height || 600; + this.width = width || 800; + this.height = height || 600; - this.view = view || document.createElement( 'canvas' ); + this.view = view || document.createElement( 'canvas' ); this.view.width = this.width; - this.view.height = this.height; + this.view.height = this.height; - // deal with losing context.. + // deal with losing context.. var scope = this; - this.view.addEventListener('webglcontextlost', function(event) { scope.handleContextLost(event); }, false) - this.view.addEventListener('webglcontextrestored', function(event) { scope.handleContextRestored(event); }, false) + this.view.addEventListener('webglcontextlost', function(event) { scope.handleContextLost(event); }, false); + this.view.addEventListener('webglcontextrestored', function(event) { scope.handleContextRestored(event); }, false); - this.batchs = []; + this.batchs = []; - var options = { - alpha: this.transparent, - antialias:!!antialias, // SPEED UP?? - premultipliedAlpha:false, - stencil:true - } + var options = { + alpha: this.transparent, + antialias:!!antialias, // SPEED UP?? + premultipliedAlpha:false, + stencil:true + }; - //try 'experimental-webgl' - try { - PIXI.gl = this.gl = this.view.getContext("experimental-webgl", options); - } catch (e) { - //try 'webgl' - try { - PIXI.gl = this.gl = this.view.getContext("webgl", options); - } catch (e) { - // fail, not able to get a context - throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this); - } - } + //try 'experimental-webgl' + try { + PIXI.gl = this.gl = this.view.getContext('experimental-webgl', options); + } catch (e) { + //try 'webgl' + try { + PIXI.gl = this.gl = this.view.getContext('webgl', options); + } catch (e2) { + // fail, not able to get a context + throw new Error(' This browser does not support webGL. Try using the canvas renderer' + this); + } + } PIXI.initDefaultShaders(); - - + + // PIXI.activateDefaultShader(); var gl = this.gl; - + gl.useProgram(PIXI.defaultShader.program); PIXI.WebGLRenderer.gl = gl; this.batch = new PIXI.WebGLBatch(gl); - gl.disable(gl.DEPTH_TEST); - gl.disable(gl.CULL_FACE); + gl.disable(gl.DEPTH_TEST); + gl.disable(gl.CULL_FACE); gl.enable(gl.BLEND); - gl.colorMask(true, true, true, this.transparent); + gl.colorMask(true, true, true, this.transparent); PIXI.projection = new PIXI.Point(400, 300); PIXI.offset = new PIXI.Point(0, 0); @@ -5673,11 +5591,11 @@ PIXI.WebGLRenderer = function(width, height, view, transparent, antialias) this.resize(this.width, this.height); this.contextLost = false; - //PIXI.pushShader(PIXI.defaultShader); + //PIXI.pushShader(PIXI.defaultShader); this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl, this.transparent); // this.stageRenderGroup. = this.transparent -} +}; // constructor PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer; @@ -5688,19 +5606,19 @@ PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer; * @static * @method getBatch * @return {WebGLBatch} - * @private + * @private */ PIXI.WebGLRenderer.getBatch = function() { - if(PIXI._batchs.length === 0) - { - return new PIXI.WebGLBatch(PIXI.WebGLRenderer.gl); - } - else - { - return PIXI._batchs.pop(); - } -} + if(PIXI._batchs.length === 0) + { + return new PIXI.WebGLBatch(PIXI.WebGLRenderer.gl); + } + else + { + return PIXI._batchs.pop(); + } +}; /** * Puts a batch back into the pool @@ -5712,9 +5630,9 @@ PIXI.WebGLRenderer.getBatch = function() */ PIXI.WebGLRenderer.returnBatch = function(batch) { - batch.clean(); - PIXI._batchs.push(batch); -} + batch.clean(); + PIXI._batchs.push(batch); +}; /** * Renders the stage to its webGL view @@ -5724,68 +5642,68 @@ PIXI.WebGLRenderer.returnBatch = function(batch) */ PIXI.WebGLRenderer.prototype.render = function(stage) { - if(this.contextLost)return; - - - // if rendering a new stage clear the batchs.. - if(this.__stage !== stage) - { - // TODO make this work - // dont think this is needed any more? - this.__stage = stage; - this.stageRenderGroup.setRenderable(stage); - } + if(this.contextLost)return; - // update any textures - PIXI.WebGLRenderer.updateTextures(); - - // update the scene graph - PIXI.visibleCount++; - stage.updateTransform(); - - var gl = this.gl; - - // -- Does this need to be set every frame? -- // - gl.colorMask(true, true, true, this.transparent); - gl.viewport(0, 0, this.width, this.height); - - gl.bindFramebuffer(gl.FRAMEBUFFER, null); - - gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); - gl.clear(gl.COLOR_BUFFER_BIT); - // HACK TO TEST - - this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit; - - PIXI.projection.x = this.width/2; - PIXI.projection.y = -this.height/2; - - this.stageRenderGroup.render(PIXI.projection); - - // interaction - // run interaction! - if(stage.interactive) - { - //need to add some events! - if(!stage._interactiveEventsAdded) - { - stage._interactiveEventsAdded = true; - stage.interactionManager.setTarget(this); - } - } - - // after rendering lets confirm all frames that have been uodated.. - if(PIXI.Texture.frameUpdates.length > 0) - { - for (var i=0; i < PIXI.Texture.frameUpdates.length; i++) - { - PIXI.Texture.frameUpdates[i].updateFrame = false; - }; - - PIXI.Texture.frameUpdates = []; - } -} + // if rendering a new stage clear the batchs.. + if(this.__stage !== stage) + { + // TODO make this work + // dont think this is needed any more? + this.__stage = stage; + this.stageRenderGroup.setRenderable(stage); + } + + // update any textures + PIXI.WebGLRenderer.updateTextures(); + + // update the scene graph + PIXI.visibleCount++; + stage.updateTransform(); + + var gl = this.gl; + + // -- Does this need to be set every frame? -- // + gl.colorMask(true, true, true, this.transparent); + gl.viewport(0, 0, this.width, this.height); + + gl.bindFramebuffer(gl.FRAMEBUFFER, null); + + gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent); + gl.clear(gl.COLOR_BUFFER_BIT); + + // HACK TO TEST + + this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit; + + PIXI.projection.x = this.width/2; + PIXI.projection.y = -this.height/2; + + this.stageRenderGroup.render(PIXI.projection); + + // interaction + // run interaction! + if(stage.interactive) + { + //need to add some events! + if(!stage._interactiveEventsAdded) + { + stage._interactiveEventsAdded = true; + stage.interactionManager.setTarget(this); + } + } + + // after rendering lets confirm all frames that have been uodated.. + if(PIXI.Texture.frameUpdates.length > 0) + { + for (var i=0; i < PIXI.Texture.frameUpdates.length; i++) + { + PIXI.Texture.frameUpdates[i].updateFrame = false; + } + + PIXI.Texture.frameUpdates = []; + } +}; /** * Updates the textures loaded into this webgl renderer @@ -5796,12 +5714,18 @@ PIXI.WebGLRenderer.prototype.render = function(stage) */ PIXI.WebGLRenderer.updateTextures = function() { - //TODO break this out into a texture manager... - for (var i=0; i < PIXI.texturesToUpdate.length; i++) PIXI.WebGLRenderer.updateTexture(PIXI.texturesToUpdate[i]); - for (var i=0; i < PIXI.texturesToDestroy.length; i++) PIXI.WebGLRenderer.destroyTexture(PIXI.texturesToDestroy[i]); - PIXI.texturesToUpdate = []; - PIXI.texturesToDestroy = []; -} + var i = 0; + + //TODO break this out into a texture manager... + for (i = 0; i < PIXI.texturesToUpdate.length; i++) + PIXI.WebGLRenderer.updateTexture(PIXI.texturesToUpdate[i]); + + for (i = 0; i < PIXI.texturesToDestroy.length; i++) + PIXI.WebGLRenderer.destroyTexture(PIXI.texturesToDestroy[i]); + + PIXI.texturesToUpdate = []; + PIXI.texturesToDestroy = []; +}; /** * Updates a loaded webgl texture @@ -5813,39 +5737,39 @@ PIXI.WebGLRenderer.updateTextures = function() */ PIXI.WebGLRenderer.updateTexture = function(texture) { - //TODO break this out into a texture manager... - var gl = PIXI.gl; - - if(!texture._glTexture) - { - texture._glTexture = gl.createTexture(); - } + //TODO break this out into a texture manager... + var gl = PIXI.gl; - if(texture.hasLoaded) - { - gl.bindTexture(gl.TEXTURE_2D, texture._glTexture); - gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); + if(!texture._glTexture) + { + texture._glTexture = gl.createTexture(); + } - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + if(texture.hasLoaded) + { + gl.bindTexture(gl.TEXTURE_2D, texture._glTexture); + gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true); - // reguler... + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, gl.RGBA, gl.UNSIGNED_BYTE, texture.source); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, texture.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR ? gl.LINEAR : gl.NEAREST); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR ? gl.LINEAR : gl.NEAREST); - if(!texture._powerOf2) - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - } - else - { - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); - } + // reguler... - gl.bindTexture(gl.TEXTURE_2D, null); - } -} + if(!texture._powerOf2) + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + } + else + { + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT); + } + + gl.bindTexture(gl.TEXTURE_2D, null); + } +}; /** * Destroys a loaded webgl texture @@ -5856,15 +5780,15 @@ PIXI.WebGLRenderer.updateTexture = function(texture) */ PIXI.WebGLRenderer.destroyTexture = function(texture) { - //TODO break this out into a texture manager... - var gl = PIXI.gl; + //TODO break this out into a texture manager... + var gl = PIXI.gl; - if(texture._glTexture) - { - texture._glTexture = gl.createTexture(); - gl.deleteTexture(gl.TEXTURE_2D, texture._glTexture); - } -} + if(texture._glTexture) + { + texture._glTexture = gl.createTexture(); + gl.deleteTexture(gl.TEXTURE_2D, texture._glTexture); + } +}; /** * resizes the webGL view to the specified width and height @@ -5875,27 +5799,27 @@ PIXI.WebGLRenderer.destroyTexture = function(texture) */ PIXI.WebGLRenderer.prototype.resize = function(width, height) { - this.width = width; - this.height = height; + this.width = width; + this.height = height; - this.view.width = width; - this.view.height = height; + this.view.width = width; + this.view.height = height; - this.gl.viewport(0, 0, this.width, this.height); + this.gl.viewport(0, 0, this.width, this.height); - //var projectionMatrix = this.projectionMatrix; + //var projectionMatrix = this.projectionMatrix; - PIXI.projection.x = this.width/2; - PIXI.projection.y = -this.height/2; - - //PIXI.size.x = this.width/2; - //PIXI.size.y = -this.height/2; + PIXI.projection.x = this.width/2; + PIXI.projection.y = -this.height/2; -// projectionMatrix[0] = 2/this.width; -// projectionMatrix[5] = -2/this.height; -// projectionMatrix[12] = -1; -// projectionMatrix[13] = 1; -} + //PIXI.size.x = this.width/2; + //PIXI.size.y = -this.height/2; + +// projectionMatrix[0] = 2/this.width; +// projectionMatrix[5] = -2/this.height; +// projectionMatrix[12] = -1; +// projectionMatrix[13] = 1; +}; /** * Handles a lost webgl context @@ -5906,9 +5830,9 @@ PIXI.WebGLRenderer.prototype.resize = function(width, height) */ PIXI.WebGLRenderer.prototype.handleContextLost = function(event) { - event.preventDefault(); - this.contextLost = true; -} + event.preventDefault(); + this.contextLost = true; +}; /** * Handles a restored webgl context @@ -5917,31 +5841,31 @@ PIXI.WebGLRenderer.prototype.handleContextLost = function(event) * @param event {Event} * @private */ -PIXI.WebGLRenderer.prototype.handleContextRestored = function(event) +PIXI.WebGLRenderer.prototype.handleContextRestored = function() { - this.gl = this.view.getContext("experimental-webgl", { - alpha: true + this.gl = this.view.getContext('experimental-webgl', { + alpha: true }); - this.initShaders(); + this.initShaders(); - for(var key in PIXI.TextureCache) - { - var texture = PIXI.TextureCache[key].baseTexture; - texture._glTexture = null; - PIXI.WebGLRenderer.updateTexture(texture); - }; + for(var key in PIXI.TextureCache) + { + var texture = PIXI.TextureCache[key].baseTexture; + texture._glTexture = null; + PIXI.WebGLRenderer.updateTexture(texture); + } - for (var i=0; i < this.batchs.length; i++) - { - this.batchs[i].restoreLostContext(this.gl)// - this.batchs[i].dirty = true; - }; + for (var i=0; i < this.batchs.length; i++) + { + this.batchs[i].restoreLostContext(this.gl); + this.batchs[i].dirty = true; + } - PIXI._restoreBatchs(this.gl); + PIXI._restoreBatchs(this.gl); - this.contextLost = false; -} + this.contextLost = false; +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 @@ -6139,9 +6063,6 @@ PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, project endBatch = lastRenderable; } - //console.log(endBatch); - // TODO - need to fold this up a bit! - if(startBatch == endBatch) { if(startBatch instanceof PIXI.WebGLBatch) @@ -6720,7 +6641,7 @@ PIXI.WebGLRenderGroup.prototype.removeObject = function(displayObject) // ok so.. check to see if you adjacent batchs should be joined. // TODO may optimise? - if(index === 0 || index == this.batchs.length-1) + if(index == 0 || index == this.batchs.length-1) { // wha - eva! just get of the empty batch! this.batchs.splice(index, 1); @@ -6793,7 +6714,7 @@ PIXI.WebGLRenderGroup.prototype.initTilingSprite = function(sprite) gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, sprite._indexBuffer); gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, sprite.indices, gl.STATIC_DRAW); -// return ( (x > 0) && ((x & (x - 1)) === 0) ); +// return ( (x > 0) && ((x & (x - 1)) == 0) ); if(sprite.texture.baseTexture._glTexture) { @@ -6979,73 +6900,70 @@ PIXI.WebGLRenderGroup.prototype.initStrip = function(strip) * @author Mat Groves http://matgroves.com/ @Doormat23 */ - -PIXI.initDefaultShaders = function() +PIXI.initDefaultShaders = function() { - PIXI.primitiveShader = new PIXI.PrimitiveShader(); - PIXI.primitiveShader.init(); + PIXI.primitiveShader = new PIXI.PrimitiveShader(); + PIXI.primitiveShader.init(); - PIXI.stripShader = new PIXI.StripShader(); - PIXI.stripShader.init(); + PIXI.stripShader = new PIXI.StripShader(); + PIXI.stripShader.init(); - PIXI.defaultShader = new PIXI.PixiShader(); - PIXI.defaultShader.init(); + PIXI.defaultShader = new PIXI.PixiShader(); + PIXI.defaultShader.init(); - var gl = PIXI.gl; - var shaderProgram = PIXI.defaultShader.program; - + var gl = PIXI.gl; + var shaderProgram = PIXI.defaultShader.program; - gl.useProgram(shaderProgram); - - gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition); - gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute); - gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); -} + gl.useProgram(shaderProgram); + + gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition); + gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute); + gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); +}; PIXI.activatePrimitiveShader = function() { - var gl = PIXI.gl; - - gl.useProgram(PIXI.primitiveShader.program); - - gl.disableVertexAttribArray(PIXI.defaultShader.aVertexPosition); - gl.disableVertexAttribArray(PIXI.defaultShader.colorAttribute); - gl.disableVertexAttribArray(PIXI.defaultShader.aTextureCoord); + var gl = PIXI.gl; - gl.enableVertexAttribArray(PIXI.primitiveShader.aVertexPosition); - gl.enableVertexAttribArray(PIXI.primitiveShader.colorAttribute); -} + gl.useProgram(PIXI.primitiveShader.program); + + gl.disableVertexAttribArray(PIXI.defaultShader.aVertexPosition); + gl.disableVertexAttribArray(PIXI.defaultShader.colorAttribute); + gl.disableVertexAttribArray(PIXI.defaultShader.aTextureCoord); + + gl.enableVertexAttribArray(PIXI.primitiveShader.aVertexPosition); + gl.enableVertexAttribArray(PIXI.primitiveShader.colorAttribute); +}; PIXI.deactivatePrimitiveShader = function() { - var gl = PIXI.gl; + var gl = PIXI.gl; - gl.useProgram(PIXI.defaultShader.program); - - gl.disableVertexAttribArray(PIXI.primitiveShader.aVertexPosition); - gl.disableVertexAttribArray(PIXI.primitiveShader.colorAttribute); + gl.useProgram(PIXI.defaultShader.program); - gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition); - gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute); - gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); + gl.disableVertexAttribArray(PIXI.primitiveShader.aVertexPosition); + gl.disableVertexAttribArray(PIXI.primitiveShader.colorAttribute); -} + gl.enableVertexAttribArray(PIXI.defaultShader.aVertexPosition); + gl.enableVertexAttribArray(PIXI.defaultShader.colorAttribute); + gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); +}; PIXI.activateStripShader = function() { - var gl = PIXI.gl; - - gl.useProgram(PIXI.stripShader.program); + var gl = PIXI.gl; + + gl.useProgram(PIXI.stripShader.program); // gl.disableVertexAttribArray(PIXI.defaultShader.aTextureCoord); -} +}; PIXI.deactivateStripShader = function() { - var gl = PIXI.gl; + var gl = PIXI.gl; - gl.useProgram(PIXI.defaultShader.program); - //gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); -} + gl.useProgram(PIXI.defaultShader.program); + //gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord); +}; /* @@ -7054,55 +6972,54 @@ SHADER COMPILER HELPERS PIXI.CompileVertexShader = function(gl, shaderSrc) { - return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER); -} + return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER); +}; PIXI.CompileFragmentShader = function(gl, shaderSrc) { - return PIXI._CompileShader(gl, shaderSrc, gl.FRAGMENT_SHADER); -} + return PIXI._CompileShader(gl, shaderSrc, gl.FRAGMENT_SHADER); +}; PIXI._CompileShader = function(gl, shaderSrc, shaderType) { - var src = shaderSrc.join("\n"); - var shader = gl.createShader(shaderType); - gl.shaderSource(shader, src); - gl.compileShader(shader); + var src = shaderSrc.join("\n"); + var shader = gl.createShader(shaderType); + gl.shaderSource(shader, src); + gl.compileShader(shader); - if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { - console.log(gl.getShaderInfoLog(shader)); - return null; - } - - return shader; -} + if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) { + window.console.log(gl.getShaderInfoLog(shader)); + return null; + } + return shader; +}; PIXI.compileProgram = function(vertexSrc, fragmentSrc) { - var gl = PIXI.gl; - var fragmentShader = PIXI.CompileFragmentShader(gl, fragmentSrc); - var vertexShader = PIXI.CompileVertexShader(gl, vertexSrc); - - var shaderProgram = gl.createProgram(); - + var gl = PIXI.gl; + var fragmentShader = PIXI.CompileFragmentShader(gl, fragmentSrc); + var vertexShader = PIXI.CompileVertexShader(gl, vertexSrc); + + var shaderProgram = gl.createProgram(); + gl.attachShader(shaderProgram, vertexShader); gl.attachShader(shaderProgram, fragmentShader); gl.linkProgram(shaderProgram); if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) { - console.log("Could not initialise shaders"); + window.console.log("Could not initialise shaders"); } - return shaderProgram; -} + return shaderProgram; +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ /** - * A Text Object will create a line(s) of text using bitmap font. To split a line you can use "\n", "\r" or "\r\n" + * A Text Object will create a line(s) of text using bitmap font. To split a line you can use '\n', '\r' or '\r\n' * You can generate the fnt files using * http://www.angelcode.com/products/bmfont/ for windows or * http://www.bmglyph.com/ for mac. @@ -7112,8 +7029,8 @@ PIXI.compileProgram = function(vertexSrc, fragmentSrc) * @constructor * @param text {String} The copy that you would like the text to display * @param style {Object} The style parameters - * @param style.font {String} The size (optional) and bitmap font id (required) eq "Arial" or "20px Arial" (must have loaded previously) - * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right") + * @param style.font {String} The size (optional) and bitmap font id (required) eq 'Arial' or '20px Arial' (must have loaded previously) + * @param [style.align='left'] {String} An alignment of the multiline text ('left', 'center' or 'right') */ PIXI.BitmapText = function(text, style) { @@ -7122,8 +7039,7 @@ PIXI.BitmapText = function(text, style) this.setText(text); this.setStyle(style); this.updateText(); - this.dirty = false - + this.dirty = false; }; // constructor @@ -7138,7 +7054,7 @@ PIXI.BitmapText.prototype.constructor = PIXI.BitmapText; */ PIXI.BitmapText.prototype.setText = function(text) { - this.text = text || " "; + this.text = text || ' '; this.dirty = true; }; @@ -7147,16 +7063,16 @@ PIXI.BitmapText.prototype.setText = function(text) * * @method setStyle * @param style {Object} The style parameters - * @param style.font {String} The size (optional) and bitmap font id (required) eq "Arial" or "20px Arial" (must have loaded previously) - * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right") + * @param style.font {String} The size (optional) and bitmap font id (required) eq 'Arial' or '20px Arial' (must have loaded previously) + * @param [style.align='left'] {String} An alignment of the multiline text ('left', 'center' or 'right') */ PIXI.BitmapText.prototype.setStyle = function(style) { style = style || {}; - style.align = style.align || "left"; + style.align = style.align || 'left'; this.style = style; - var font = style.font.split(" "); + var font = style.font.split(' '); this.fontName = font[font.length - 1]; this.fontSize = font.length >= 2 ? parseInt(font[font.length - 2], 10) : PIXI.BitmapText.fonts[this.fontName].size; @@ -7199,7 +7115,7 @@ PIXI.BitmapText.prototype.updateText = function() if(prevCharCode && charData[prevCharCode]) { - pos.x += charData.kerning[prevCharCode]; + pos.x += charData.kerning[prevCharCode]; } chars.push({texture:charData.texture, line: line, charCode: charCode, position: new PIXI.Point(pos.x + charData.xOffset, pos.y + charData.yOffset)}); pos.x += charData.xAdvance; @@ -7214,11 +7130,11 @@ PIXI.BitmapText.prototype.updateText = function() for(i = 0; i <= line; i++) { var alignOffset = 0; - if(this.style.align == "right") + if(this.style.align === 'right') { alignOffset = maxLineWidth - lineWidths[i]; } - else if(this.style.align == "center") + else if(this.style.align === 'center') { alignOffset = (maxLineWidth - lineWidths[i]) / 2; } @@ -7227,14 +7143,14 @@ PIXI.BitmapText.prototype.updateText = function() for(i = 0; i < chars.length; i++) { - var c = new PIXI.Sprite(chars[i].texture)//PIXI.Sprite.fromFrame(chars[i].charCode); + var c = new PIXI.Sprite(chars[i].texture); //PIXI.Sprite.fromFrame(chars[i].charCode); c.position.x = (chars[i].position.x + lineAlignOffsets[chars[i].line]) * scale; c.position.y = chars[i].position.y * scale; c.scale.x = c.scale.y = scale; this.addChild(c); } - this.width = pos.x * scale; + this.width = maxLineWidth * scale; this.height = (pos.y + data.lineHeight) * scale; }; @@ -7246,8 +7162,8 @@ PIXI.BitmapText.prototype.updateText = function() */ PIXI.BitmapText.prototype.updateTransform = function() { - if(this.dirty) - { + if(this.dirty) + { while(this.children.length > 0) { this.removeChild(this.getChildAt(0)); @@ -7255,9 +7171,9 @@ PIXI.BitmapText.prototype.updateTransform = function() this.updateText(); this.dirty = false; - } + } - PIXI.DisplayObjectContainer.prototype.updateTransform.call(this); + PIXI.DisplayObjectContainer.prototype.updateTransform.call(this); }; PIXI.BitmapText.fonts = {}; @@ -7267,25 +7183,25 @@ PIXI.BitmapText.fonts = {}; */ /** - * A Text Object will create a line(s) of text to split a line you can use "\n" + * A Text Object will create a line(s) of text to split a line you can use '\n' * * @class Text * @extends Sprite * @constructor * @param text {String} The copy that you would like the text to display * @param [style] {Object} The style parameters - * @param [style.font] {String} default "bold 20pt Arial" The style and size of the font - * @param [style.fill="black"] {Object} A canvas fillstyle that will be used on the text eg "red", "#00FF00" - * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right") - * @param [style.stroke] {String} A canvas fillstyle that will be used on the text stroke eg "blue", "#FCFF00" + * @param [style.font] {String} default 'bold 20pt Arial' The style and size of the font + * @param [style.fill='black'] {Object} A canvas fillstyle that will be used on the text eg 'red', '#00FF00' + * @param [style.align='left'] {String} An alignment of the multiline text ('left', 'center' or 'right') + * @param [style.stroke] {String} A canvas fillstyle that will be used on the text stroke eg 'blue', '#FCFF00' * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke) * @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap */ PIXI.Text = function(text, style) { - this.canvas = document.createElement("canvas"); - this.context = this.canvas.getContext("2d"); + this.canvas = document.createElement('canvas'); + this.context = this.canvas.getContext('2d'); PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas)); this.setText(text); @@ -7304,10 +7220,10 @@ PIXI.Text.prototype.constructor = PIXI.Text; * * @method setStyle * @param [style] {Object} The style parameters - * @param [style.font="bold 20pt Arial"] {String} The style and size of the font - * @param [style.fill="black"] {Object} A canvas fillstyle that will be used on the text eg "red", "#00FF00" - * @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right") - * @param [style.stroke="black"] {String} A canvas fillstyle that will be used on the text stroke eg "blue", "#FCFF00" + * @param [style.font='bold 20pt Arial'] {String} The style and size of the font + * @param [style.fill='black'] {Object} A canvas fillstyle that will be used on the text eg 'red', '#00FF00' + * @param [style.align='left'] {String} An alignment of the multiline text ('left', 'center' or 'right') + * @param [style.stroke='black'] {String} A canvas fillstyle that will be used on the text stroke eg 'blue', '#FCFF00' * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke) * @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap @@ -7315,10 +7231,10 @@ PIXI.Text.prototype.constructor = PIXI.Text; PIXI.Text.prototype.setStyle = function(style) { style = style || {}; - style.font = style.font || "bold 20pt Arial"; - style.fill = style.fill || "black"; - style.align = style.align || "left"; - style.stroke = style.stroke || "black"; //provide a default, see: https://github.com/GoodBoyDigital/pixi.js/issues/136 + style.font = style.font || 'bold 20pt Arial'; + style.fill = style.fill || 'black'; + style.align = style.align || 'left'; + style.stroke = style.stroke || 'black'; //provide a default, see: https://github.com/GoodBoyDigital/pixi.js/issues/136 style.strokeThickness = style.strokeThickness || 0; style.wordWrap = style.wordWrap || false; style.wordWrapWidth = style.wordWrapWidth || 100; @@ -7327,14 +7243,14 @@ PIXI.Text.prototype.setStyle = function(style) }; /** - * Set the copy for the text object. To split a line you can use "\n" + * Set the copy for the text object. To split a line you can use '\n' * - * @methos setText + * @method setText * @param {String} text The copy that you would like the text to display */ PIXI.Text.prototype.setText = function(text) { - this.text = text.toString() || " "; + this.text = text.toString() || ' '; this.dirty = true; }; @@ -7346,65 +7262,65 @@ PIXI.Text.prototype.setText = function(text) */ PIXI.Text.prototype.updateText = function() { - this.context.font = this.style.font; + this.context.font = this.style.font; - var outputText = this.text; + var outputText = this.text; - // word wrap - // preserve original text - if(this.style.wordWrap)outputText = this.wordWrap(this.text); + // word wrap + // preserve original text + if(this.style.wordWrap)outputText = this.wordWrap(this.text); - //split text into lines - var lines = outputText.split(/(?:\r\n|\r|\n)/); + //split text into lines + var lines = outputText.split(/(?:\r\n|\r|\n)/); - //calculate text width - var lineWidths = []; - var maxLineWidth = 0; - for (var i = 0; i < lines.length; i++) - { - var lineWidth = this.context.measureText(lines[i]).width; - lineWidths[i] = lineWidth; - maxLineWidth = Math.max(maxLineWidth, lineWidth); - } - this.canvas.width = maxLineWidth + this.style.strokeThickness; + //calculate text width + var lineWidths = []; + var maxLineWidth = 0; + for (var i = 0; i < lines.length; i++) + { + var lineWidth = this.context.measureText(lines[i]).width; + lineWidths[i] = lineWidth; + maxLineWidth = Math.max(maxLineWidth, lineWidth); + } + this.canvas.width = maxLineWidth + this.style.strokeThickness; - //calculate text height - var lineHeight = this.determineFontHeight("font: " + this.style.font + ";") + this.style.strokeThickness; - this.canvas.height = lineHeight * lines.length; + //calculate text height + var lineHeight = this.determineFontHeight('font: ' + this.style.font + ';') + this.style.strokeThickness; + this.canvas.height = lineHeight * lines.length; - //set canvas text styles - this.context.fillStyle = this.style.fill; - this.context.font = this.style.font; + //set canvas text styles + this.context.fillStyle = this.style.fill; + this.context.font = this.style.font; - this.context.strokeStyle = this.style.stroke; - this.context.lineWidth = this.style.strokeThickness; + this.context.strokeStyle = this.style.stroke; + this.context.lineWidth = this.style.strokeThickness; - this.context.textBaseline = "top"; + this.context.textBaseline = 'top'; - //draw lines line by line - for (i = 0; i < lines.length; i++) - { - var linePosition = new PIXI.Point(this.style.strokeThickness / 2, this.style.strokeThickness / 2 + i * lineHeight); + //draw lines line by line + for (i = 0; i < lines.length; i++) + { + var linePosition = new PIXI.Point(this.style.strokeThickness / 2, this.style.strokeThickness / 2 + i * lineHeight); - if(this.style.align == "right") - { - linePosition.x += maxLineWidth - lineWidths[i]; - } - else if(this.style.align == "center") - { - linePosition.x += (maxLineWidth - lineWidths[i]) / 2; - } + if(this.style.align === 'right') + { + linePosition.x += maxLineWidth - lineWidths[i]; + } + else if(this.style.align === 'center') + { + linePosition.x += (maxLineWidth - lineWidths[i]) / 2; + } - if(this.style.stroke && this.style.strokeThickness) - { - this.context.strokeText(lines[i], linePosition.x, linePosition.y); - } + if(this.style.stroke && this.style.strokeThickness) + { + this.context.strokeText(lines[i], linePosition.x, linePosition.y); + } - if(this.style.fill) - { - this.context.fillText(lines[i], linePosition.x, linePosition.y); - } - } + if(this.style.fill) + { + this.context.fillText(lines[i], linePosition.x, linePosition.y); + } + } this.updateTexture(); }; @@ -7422,7 +7338,7 @@ PIXI.Text.prototype.updateTexture = function() this.texture.frame.width = this.canvas.width; this.texture.frame.height = this.canvas.height; - this._width = this.canvas.width; + this._width = this.canvas.width; this._height = this.canvas.height; PIXI.texturesToUpdate.push(this.texture.baseTexture); @@ -7436,13 +7352,13 @@ PIXI.Text.prototype.updateTexture = function() */ PIXI.Text.prototype.updateTransform = function() { - if(this.dirty) - { - this.updateText(); - this.dirty = false; - } + if(this.dirty) + { + this.updateText(); + this.dirty = false; + } - PIXI.Sprite.prototype.updateTransform.call(this); + PIXI.Sprite.prototype.updateTransform.call(this); }; /* @@ -7455,26 +7371,26 @@ PIXI.Text.prototype.updateTransform = function() */ PIXI.Text.prototype.determineFontHeight = function(fontStyle) { - // build a little reference dictionary so if the font style has been used return a - // cached version... - var result = PIXI.Text.heightCache[fontStyle]; + // build a little reference dictionary so if the font style has been used return a + // cached version... + var result = PIXI.Text.heightCache[fontStyle]; - if(!result) - { - var body = document.getElementsByTagName("body")[0]; - var dummy = document.createElement("div"); - var dummyText = document.createTextNode("M"); - dummy.appendChild(dummyText); - dummy.setAttribute("style", fontStyle + ';position:absolute;top:0;left:0'); - body.appendChild(dummy); + if(!result) + { + var body = document.getElementsByTagName('body')[0]; + var dummy = document.createElement('div'); + var dummyText = document.createTextNode('M'); + dummy.appendChild(dummyText); + dummy.setAttribute('style', fontStyle + ';position:absolute;top:0;left:0'); + body.appendChild(dummy); - result = dummy.offsetHeight; - PIXI.Text.heightCache[fontStyle] = result; + result = dummy.offsetHeight; + PIXI.Text.heightCache[fontStyle] = result; - body.removeChild(dummy); - } + body.removeChild(dummy); + } - return result; + return result; }; /** @@ -7487,38 +7403,38 @@ PIXI.Text.prototype.determineFontHeight = function(fontStyle) */ PIXI.Text.prototype.wordWrap = function(text) { - // Greedy wrapping algorithm that will wrap words as the line grows longer - // than its horizontal bounds. - var result = ""; - var lines = text.split("\n"); - for (var i = 0; i < lines.length; i++) - { - var spaceLeft = this.style.wordWrapWidth; - var words = lines[i].split(" "); - for (var j = 0; j < words.length; j++) - { - var wordWidth = this.context.measureText(words[j]).width; - var wordWidthWithSpace = wordWidth + this.context.measureText(" ").width; - if(wordWidthWithSpace > spaceLeft) - { - // Skip printing the newline if it's the first word of the line that is - // greater than the word wrap width. - if(j > 0) - { - result += "\n"; - } - result += words[j] + " "; - spaceLeft = this.style.wordWrapWidth - wordWidth; - } - else - { - spaceLeft -= wordWidthWithSpace; - result += words[j] + " "; - } - } - result += "\n"; - } - return result; + // Greedy wrapping algorithm that will wrap words as the line grows longer + // than its horizontal bounds. + var result = ''; + var lines = text.split('\n'); + for (var i = 0; i < lines.length; i++) + { + var spaceLeft = this.style.wordWrapWidth; + var words = lines[i].split(' '); + for (var j = 0; j < words.length; j++) + { + var wordWidth = this.context.measureText(words[j]).width; + var wordWidthWithSpace = wordWidth + this.context.measureText(' ').width; + if(wordWidthWithSpace > spaceLeft) + { + // Skip printing the newline if it's the first word of the line that is + // greater than the word wrap width. + if(j > 0) + { + result += '\n'; + } + result += words[j] + ' '; + spaceLeft = this.style.wordWrapWidth - wordWidth; + } + else + { + spaceLeft -= wordWidthWithSpace; + result += words[j] + ' '; + } + } + result += '\n'; + } + return result; }; /** @@ -7529,10 +7445,10 @@ PIXI.Text.prototype.wordWrap = function(text) */ PIXI.Text.prototype.destroy = function(destroyTexture) { - if(destroyTexture) - { - this.texture.destroy(); - } + if(destroyTexture) + { + this.texture.destroy(); + } }; @@ -7554,85 +7470,94 @@ PIXI.texturesToDestroy = []; * @constructor * @param source {String} the source object (image or canvas) */ -PIXI.BaseTexture = function(source) +PIXI.BaseTexture = function(source, scaleMode) { - PIXI.EventTarget.call( this ); + PIXI.EventTarget.call( this ); - /** - * [read-only] The width of the base texture set when the image has loaded - * - * @property width - * @type Number - * @readOnly - */ - this.width = 100; + /** + * [read-only] The width of the base texture set when the image has loaded + * + * @property width + * @type Number + * @readOnly + */ + this.width = 100; - /** - * [read-only] The height of the base texture set when the image has loaded - * - * @property height - * @type Number - * @readOnly - */ - this.height = 100; + /** + * [read-only] The height of the base texture set when the image has loaded + * + * @property height + * @type Number + * @readOnly + */ + this.height = 100; - /** - * [read-only] Describes if the base texture has loaded or not - * - * @property hasLoaded - * @type Boolean - * @readOnly - */ - this.hasLoaded = false; + /** + * The scale mode to apply when scaling this texture + * @property scaleMode + * @type PIXI.BaseTexture.SCALE_MODE + * @default PIXI.BaseTexture.SCALE_MODE.LINEAR + */ + this.scaleMode = scaleMode || PIXI.BaseTexture.SCALE_MODE.DEFAULT; - /** - * The source that is loaded to create the texture - * - * @property source - * @type Image - */ - this.source = source; + /** + * [read-only] Describes if the base texture has loaded or not + * + * @property hasLoaded + * @type Boolean + * @readOnly + */ + this.hasLoaded = false; - if(!source)return; + /** + * The source that is loaded to create the texture + * + * @property source + * @type Image + */ + this.source = source; - if(this.source instanceof Image || this.source instanceof HTMLImageElement) - { - if(this.source.complete) - { - this.hasLoaded = true; - this.width = this.source.width; - this.height = this.source.height; + if(!source)return; - PIXI.texturesToUpdate.push(this); - } - else - { + if(this.source instanceof Image || this.source instanceof HTMLImageElement) + { + if(this.source.complete) + { + this.hasLoaded = true; + this.width = this.source.width; + this.height = this.source.height; - var scope = this; - this.source.onload = function(){ + PIXI.texturesToUpdate.push(this); + } + else + { - scope.hasLoaded = true; - scope.width = scope.source.width; - scope.height = scope.source.height; + var scope = this; + this.source.onload = function() { - // add it to somewhere... - PIXI.texturesToUpdate.push(scope); - scope.dispatchEvent( { type: 'loaded', content: scope } ); - } - // this.image.src = imageUrl; - } - } - else - { - this.hasLoaded = true; - this.width = this.source.width; - this.height = this.source.height; + scope.hasLoaded = true; + scope.width = scope.source.width; + scope.height = scope.source.height; - PIXI.texturesToUpdate.push(this); - } + // add it to somewhere... + PIXI.texturesToUpdate.push(scope); + scope.dispatchEvent( { type: 'loaded', content: scope } ); + }; + //this.image.src = imageUrl; + } + } + else + { + this.hasLoaded = true; + this.width = this.source.width; + this.height = this.source.height; - this._powerOf2 = false; -} + PIXI.texturesToUpdate.push(this); + } + + this.imageUrl = null; + this._powerOf2 = false; +}; PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture; @@ -7643,13 +7568,29 @@ PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture; */ PIXI.BaseTexture.prototype.destroy = function() { - if(this.source instanceof Image) - { - this.source.src = null; - } - this.source = null; - PIXI.texturesToDestroy.push(this); -} + if(this.source instanceof Image) + { + if (this.imageUrl in PIXI.BaseTextureCache) + delete PIXI.BaseTextureCache[this.imageUrl]; + this.imageUrl = null; + this.source.src = null; + } + this.source = null; + PIXI.texturesToDestroy.push(this); +}; + +/** + * + * + * @method destroy + */ + +PIXI.BaseTexture.prototype.updateSourceImage = function(newSrc) +{ + this.hasLoaded = false; + this.source.src = null; + this.source.src = newSrc; +}; /** * Helper function that returns a base texture based on an image url @@ -7660,26 +7601,32 @@ PIXI.BaseTexture.prototype.destroy = function() * @param imageUrl {String} The image url of the texture * @return BaseTexture */ -PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin) +PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin, scaleMode) { - var baseTexture = PIXI.BaseTextureCache[imageUrl]; - if(!baseTexture) - { - // new Image() breaks tex loading in some versions of Chrome. - // See https://code.google.com/p/chromium/issues/detail?id=238071 - var image = new Image();//document.createElement('img'); - if (crossorigin) - { - image.crossOrigin = ''; - } - image.src = imageUrl; - baseTexture = new PIXI.BaseTexture(image); - PIXI.BaseTextureCache[imageUrl] = baseTexture; - } + var baseTexture = PIXI.BaseTextureCache[imageUrl]; + if(!baseTexture) + { + // new Image() breaks tex loading in some versions of Chrome. + // See https://code.google.com/p/chromium/issues/detail?id=238071 + var image = new Image();//document.createElement('img'); + if (crossorigin) + { + image.crossOrigin = ''; + } + image.src = imageUrl; + baseTexture = new PIXI.BaseTexture(image, scaleMode); + baseTexture.imageUrl = imageUrl; + PIXI.BaseTextureCache[imageUrl] = baseTexture; + } - return baseTexture; -} + return baseTexture; +}; +PIXI.BaseTexture.SCALE_MODE = { + DEFAULT: 0, //default to LINEAR + LINEAR: 0, + NEAREST: 1 +}; /** * @author Mat Groves http://matgroves.com/ @Doormat23 */ @@ -7699,56 +7646,56 @@ PIXI.FrameCache = {}; */ PIXI.Texture = function(baseTexture, frame) { - PIXI.EventTarget.call( this ); + PIXI.EventTarget.call( this ); - if(!frame) - { - this.noFrame = true; - frame = new PIXI.Rectangle(0,0,1,1); - } + if(!frame) + { + this.noFrame = true; + frame = new PIXI.Rectangle(0,0,1,1); + } - if(baseTexture instanceof PIXI.Texture) - baseTexture = baseTexture.baseTexture; + if(baseTexture instanceof PIXI.Texture) + baseTexture = baseTexture.baseTexture; - /** - * The base texture of this texture - * - * @property baseTexture - * @type BaseTexture - */ - this.baseTexture = baseTexture; + /** + * The base texture of this texture + * + * @property baseTexture + * @type BaseTexture + */ + this.baseTexture = baseTexture; - /** - * The frame specifies the region of the base texture that this texture uses - * - * @property frame - * @type Rectangle - */ - this.frame = frame; + /** + * The frame specifies the region of the base texture that this texture uses + * + * @property frame + * @type Rectangle + */ + this.frame = frame; - /** - * The trim point - * - * @property trim - * @type Point - */ - this.trim = new PIXI.Point(); + /** + * The trim point + * + * @property trim + * @type Point + */ + this.trim = new PIXI.Point(); - this.scope = this; + this.scope = this; - if(baseTexture.hasLoaded) - { - if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height); - //console.log(frame) + if(baseTexture.hasLoaded) + { + if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height); + //console.log(frame) - this.setFrame(frame); - } - else - { - var scope = this; - baseTexture.addEventListener( 'loaded', function(){ scope.onBaseTextureLoaded()} ); - } -} + this.setFrame(frame); + } + else + { + var scope = this; + baseTexture.addEventListener('loaded', function(){ scope.onBaseTextureLoaded(); }); + } +}; PIXI.Texture.prototype.constructor = PIXI.Texture; @@ -7759,18 +7706,18 @@ PIXI.Texture.prototype.constructor = PIXI.Texture; * @param event * @private */ -PIXI.Texture.prototype.onBaseTextureLoaded = function(event) +PIXI.Texture.prototype.onBaseTextureLoaded = function() { - var baseTexture = this.baseTexture; - baseTexture.removeEventListener( 'loaded', this.onLoaded ); + var baseTexture = this.baseTexture; + baseTexture.removeEventListener( 'loaded', this.onLoaded ); - if(this.noFrame)this.frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height); - this.noFrame = false; - this.width = this.frame.width; - this.height = this.frame.height; + if(this.noFrame)this.frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height); + this.noFrame = false; + this.width = this.frame.width; + this.height = this.frame.height; - this.scope.dispatchEvent( { type: 'update', content: this } ); -} + this.scope.dispatchEvent( { type: 'update', content: this } ); +}; /** * Destroys this texture @@ -7780,8 +7727,8 @@ PIXI.Texture.prototype.onBaseTextureLoaded = function(event) */ PIXI.Texture.prototype.destroy = function(destroyBase) { - if(destroyBase)this.baseTexture.destroy(); -} + if(destroyBase) this.baseTexture.destroy(); +}; /** * Specifies the rectangle region of the baseTexture @@ -7791,20 +7738,20 @@ PIXI.Texture.prototype.destroy = function(destroyBase) */ PIXI.Texture.prototype.setFrame = function(frame) { - this.frame = frame; - this.width = frame.width; - this.height = frame.height; + this.frame = frame; + this.width = frame.width; + this.height = frame.height; - if(frame.x + frame.width > this.baseTexture.width || frame.y + frame.height > this.baseTexture.height) - { - throw new Error("Texture Error: frame does not fit inside the base Texture dimensions " + this); - } + if(frame.x + frame.width > this.baseTexture.width || frame.y + frame.height > this.baseTexture.height) + { + throw new Error('Texture Error: frame does not fit inside the base Texture dimensions ' + this); + } - this.updateFrame = true; + this.updateFrame = true; - PIXI.Texture.frameUpdates.push(this); - //this.dispatchEvent( { type: 'update', content: this } ); -} + PIXI.Texture.frameUpdates.push(this); + //this.dispatchEvent( { type: 'update', content: this } ); +}; /** * Helper function that returns a texture based on an image url @@ -7816,18 +7763,18 @@ PIXI.Texture.prototype.setFrame = function(frame) * @param crossorigin {Boolean} Whether requests should be treated as crossorigin * @return Texture */ -PIXI.Texture.fromImage = function(imageUrl, crossorigin) +PIXI.Texture.fromImage = function(imageUrl, crossorigin, scaleMode) { - var texture = PIXI.TextureCache[imageUrl]; + var texture = PIXI.TextureCache[imageUrl]; - if(!texture) - { - texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin)); - PIXI.TextureCache[imageUrl] = texture; - } + if(!texture) + { + texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin, scaleMode)); + PIXI.TextureCache[imageUrl] = texture; + } - return texture; -} + return texture; +}; /** * Helper function that returns a texture based on a frame id @@ -7840,10 +7787,10 @@ PIXI.Texture.fromImage = function(imageUrl, crossorigin) */ PIXI.Texture.fromFrame = function(frameId) { - var texture = PIXI.TextureCache[frameId]; - if(!texture)throw new Error("The frameId '"+ frameId +"' does not exist in the texture cache " + this); - return texture; -} + var texture = PIXI.TextureCache[frameId]; + if(!texture) throw new Error('The frameId "' + frameId + '" does not exist in the texture cache ' + this); + return texture; +}; /** * Helper function that returns a texture based on a canvas element @@ -7854,11 +7801,11 @@ PIXI.Texture.fromFrame = function(frameId) * @param canvas {Canvas} The canvas element source of the texture * @return Texture */ -PIXI.Texture.fromCanvas = function(canvas) +PIXI.Texture.fromCanvas = function(canvas, scaleMode) { - var baseTexture = new PIXI.BaseTexture(canvas); - return new PIXI.Texture(baseTexture); -} + var baseTexture = new PIXI.BaseTexture(canvas, scaleMode); + return new PIXI.Texture(baseTexture); +}; /** @@ -7871,8 +7818,8 @@ PIXI.Texture.fromCanvas = function(canvas) */ PIXI.Texture.addTextureToCache = function(texture, id) { - PIXI.TextureCache[id] = texture; -} + PIXI.TextureCache[id] = texture; +}; /** * Remove a texture from the textureCache. @@ -7884,14 +7831,15 @@ PIXI.Texture.addTextureToCache = function(texture, id) */ PIXI.Texture.removeTextureFromCache = function(id) { - var texture = PIXI.TextureCache[id] - PIXI.TextureCache[id] = null; - return texture; -} + var texture = PIXI.TextureCache[id]; + PIXI.TextureCache[id] = null; + return texture; +}; // this is more for webGL.. it contains updated frames.. PIXI.Texture.frameUpdates = []; +PIXI.Texture.SCALE_MODE = PIXI.BaseTexture.SCALE_MODE; /** * @author Mat Groves http://matgroves.com/ @Doormat23 @@ -7900,24 +7848,24 @@ PIXI.Texture.frameUpdates = []; /** A RenderTexture is a special texture that allows any pixi displayObject to be rendered to it. - __Hint__: All DisplayObjects (exmpl. Sprites) that renders on RenderTexture should be preloaded. - Otherwise black rectangles will be drawn instead. - + __Hint__: All DisplayObjects (exmpl. Sprites) that renders on RenderTexture should be preloaded. + Otherwise black rectangles will be drawn instead. + RenderTexture takes snapshot of DisplayObject passed to render method. If DisplayObject is passed to render method, position and rotation of it will be ignored. For example: - - var renderTexture = new PIXI.RenderTexture(800, 600); - var sprite = PIXI.Sprite.fromImage("spinObj_01.png"); - sprite.position.x = 800/2; - sprite.position.y = 600/2; - sprite.anchor.x = 0.5; - sprite.anchor.y = 0.5; - renderTexture.render(sprite); + + var renderTexture = new PIXI.RenderTexture(800, 600); + var sprite = PIXI.Sprite.fromImage("spinObj_01.png"); + sprite.position.x = 800/2; + sprite.position.y = 600/2; + sprite.anchor.x = 0.5; + sprite.anchor.y = 0.5; + renderTexture.render(sprite); Sprite in this case will be rendered to 0,0 position. To render this sprite at center DisplayObjectContainer should be used: - var doc = new PIXI.DisplayObjectContainer(); - doc.addChild(sprite); - renderTexture.render(doc); // Renders to center of renderTexture + var doc = new PIXI.DisplayObjectContainer(); + doc.addChild(sprite); + renderTexture.render(doc); // Renders to center of renderTexture @class RenderTexture @extends Texture @@ -7927,24 +7875,24 @@ PIXI.Texture.frameUpdates = []; */ PIXI.RenderTexture = function(width, height) { - PIXI.EventTarget.call( this ); + PIXI.EventTarget.call( this ); - this.width = width || 100; - this.height = height || 100; + this.width = width || 100; + this.height = height || 100; - this.indetityMatrix = PIXI.mat3.create(); + this.indetityMatrix = PIXI.mat3.create(); - this.frame = new PIXI.Rectangle(0, 0, this.width, this.height); + this.frame = new PIXI.Rectangle(0, 0, this.width, this.height); - if(PIXI.gl) - { - this.initWebGL(); - } - else - { - this.initCanvas(); - } -} + if(PIXI.gl) + { + this.initWebGL(); + } + else + { + this.initCanvas(); + } +}; PIXI.RenderTexture.prototype = Object.create( PIXI.Texture.prototype ); PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture; @@ -7957,65 +7905,65 @@ PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture; */ PIXI.RenderTexture.prototype.initWebGL = function() { - var gl = PIXI.gl; - this.glFramebuffer = gl.createFramebuffer(); + var gl = PIXI.gl; + this.glFramebuffer = gl.createFramebuffer(); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer ); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer ); this.glFramebuffer.width = this.width; - this.glFramebuffer.height = this.height; + this.glFramebuffer.height = this.height; - this.baseTexture = new PIXI.BaseTexture(); + this.baseTexture = new PIXI.BaseTexture(); - this.baseTexture.width = this.width; - this.baseTexture.height = this.height; + this.baseTexture.width = this.width; + this.baseTexture.height = this.height; this.baseTexture._glTexture = gl.createTexture(); gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); - gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, gl.LINEAR); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.CLAMP_TO_EDGE); + gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.CLAMP_TO_EDGE); - this.baseTexture.isRender = true; + this.baseTexture.isRender = true; - gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer ); - gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.baseTexture._glTexture, 0); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer ); + gl.framebufferTexture2D(gl.FRAMEBUFFER, gl.COLOR_ATTACHMENT0, gl.TEXTURE_2D, this.baseTexture._glTexture, 0); - // create a projection matrix.. - this.projection = new PIXI.Point(this.width/2 , -this.height/2); + // create a projection matrix.. + this.projection = new PIXI.Point(this.width/2 , -this.height/2); - // set the correct render function.. - this.render = this.renderWebGL; -} + // set the correct render function.. + this.render = this.renderWebGL; +}; PIXI.RenderTexture.prototype.resize = function(width, height) { - this.width = width; - this.height = height; - - if(PIXI.gl) - { - this.projection.x = this.width/2 - this.projection.y = -this.height/2; - - var gl = PIXI.gl; - gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture); - gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); - } - else - { - - this.frame.width = this.width - this.frame.height = this.height; - this.renderer.resize(this.width, this.height); - } -} + this.width = width; + this.height = height; + + if(PIXI.gl) + { + this.projection.x = this.width / 2; + this.projection.y = -this.height / 2; + + var gl = PIXI.gl; + gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture); + gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, this.width, this.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null); + } + else + { + + this.frame.width = this.width; + this.frame.height = this.height; + this.renderer.resize(this.width, this.height); + } +}; /** * Initializes the canvas data for this texture @@ -8025,13 +7973,13 @@ PIXI.RenderTexture.prototype.resize = function(width, height) */ PIXI.RenderTexture.prototype.initCanvas = function() { - this.renderer = new PIXI.CanvasRenderer(this.width, this.height, null, 0); + this.renderer = new PIXI.CanvasRenderer(this.width, this.height, null, 0); - this.baseTexture = new PIXI.BaseTexture(this.renderer.view); - this.frame = new PIXI.Rectangle(0, 0, this.width, this.height); + this.baseTexture = new PIXI.BaseTexture(this.renderer.view); + this.frame = new PIXI.Rectangle(0, 0, this.width, this.height); - this.render = this.renderCanvas; -} + this.render = this.renderCanvas; +}; /** * This function will draw the display object to the texture. @@ -8043,67 +7991,67 @@ PIXI.RenderTexture.prototype.initCanvas = function() */ PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear) { - var gl = PIXI.gl; + var gl = PIXI.gl; - // enable the alpha color mask.. - gl.colorMask(true, true, true, true); + // enable the alpha color mask.. + gl.colorMask(true, true, true, true); - gl.viewport(0, 0, this.width, this.height); + gl.viewport(0, 0, this.width, this.height); - gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer ); + gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer ); - if(clear) - { - gl.clearColor(0,0,0, 0); - gl.clear(gl.COLOR_BUFFER_BIT); - } + if(clear) + { + gl.clearColor(0,0,0, 0); + gl.clear(gl.COLOR_BUFFER_BIT); + } - // THIS WILL MESS WITH HIT TESTING! - var children = displayObject.children; + // THIS WILL MESS WITH HIT TESTING! + var children = displayObject.children; - //TODO -? create a new one??? dont think so! - var originalWorldTransform = displayObject.worldTransform; - displayObject.worldTransform = PIXI.mat3.create();//sthis.indetityMatrix; - // modify to flip... - displayObject.worldTransform[4] = -1; - displayObject.worldTransform[5] = this.projection.y * -2; + //TODO -? create a new one??? dont think so! + var originalWorldTransform = displayObject.worldTransform; + displayObject.worldTransform = PIXI.mat3.create();//sthis.indetityMatrix; + // modify to flip... + displayObject.worldTransform[4] = -1; + displayObject.worldTransform[5] = this.projection.y * -2; - if(position) - { - displayObject.worldTransform[2] = position.x; - displayObject.worldTransform[5] -= position.y; - } - - PIXI.visibleCount++; - displayObject.vcount = PIXI.visibleCount; - - for(var i=0,j=children.length; i>1; - if(n<3) return []; - var tgs = []; - var avl = []; - for(var i=0; i> 1; + if(n < 3) return []; - var i = 0; - var al = n; - while(al > 3) - { - var i0 = avl[(i+0)%al]; - var i1 = avl[(i+1)%al]; - var i2 = avl[(i+2)%al]; + var tgs = []; + var avl = []; + for(var i = 0; i < n; i++) avl.push(i); - var ax = p[2*i0], ay = p[2*i0+1]; - var bx = p[2*i1], by = p[2*i1+1]; - var cx = p[2*i2], cy = p[2*i2+1]; + i = 0; + var al = n; + while(al > 3) + { + var i0 = avl[(i+0)%al]; + var i1 = avl[(i+1)%al]; + var i2 = avl[(i+2)%al]; - var earFound = false; - if(PIXI.PolyK._convex(ax, ay, bx, by, cx, cy, sign)) - { - earFound = true; - for(var j=0; j 3*al) - { - // need to flip flip reverse it! - // reset! - if(sign) - { - var tgs = []; - avl = []; - for(var i=0; i 3*al) + { + // need to flip flip reverse it! + // reset! + if(sign) + { + tgs = []; + avl = []; + for(i = 0; i < n; i++) avl.push(i); + + i = 0; + al = n; + + sign = false; + } + else + { + window.console.log("PIXI Warning: shape too complex to fill"); + return []; + } + } + } + + tgs.push(avl[0], avl[1], avl[2]); + return tgs; +}; /** * Checks if a point is within a triangle @@ -8326,26 +8285,26 @@ PIXI.PolyK.Triangulate = function(p) */ PIXI.PolyK._PointInTriangle = function(px, py, ax, ay, bx, by, cx, cy) { - var v0x = cx-ax; - var v0y = cy-ay; - var v1x = bx-ax; - var v1y = by-ay; - var v2x = px-ax; - var v2y = py-ay; + var v0x = cx-ax; + var v0y = cy-ay; + var v1x = bx-ax; + var v1y = by-ay; + var v2x = px-ax; + var v2y = py-ay; - var dot00 = v0x*v0x+v0y*v0y; - var dot01 = v0x*v1x+v0y*v1y; - var dot02 = v0x*v2x+v0y*v2y; - var dot11 = v1x*v1x+v1y*v1y; - var dot12 = v1x*v2x+v1y*v2y; + var dot00 = v0x*v0x+v0y*v0y; + var dot01 = v0x*v1x+v0y*v1y; + var dot02 = v0x*v2x+v0y*v2y; + var dot11 = v1x*v1x+v1y*v1y; + var dot12 = v1x*v2x+v1y*v2y; - var invDenom = 1 / (dot00 * dot11 - dot01 * dot01); - var u = (dot11 * dot02 - dot01 * dot12) * invDenom; - var v = (dot00 * dot12 - dot01 * dot02) * invDenom; + var invDenom = 1 / (dot00 * dot11 - dot01 * dot01); + var u = (dot11 * dot02 - dot01 * dot12) * invDenom; + var v = (dot00 * dot12 - dot01 * dot02) * invDenom; - // Check if point is in triangle - return (u >= 0) && (v >= 0) && (u + v < 1); -} + // Check if point is in triangle + return (u >= 0) && (v >= 0) && (u + v < 1); +}; /** * Checks if a shape is convex @@ -8356,12 +8315,12 @@ PIXI.PolyK._PointInTriangle = function(px, py, ax, ay, bx, by, cx, cy) */ PIXI.PolyK._convex = function(ax, ay, bx, by, cx, cy, sign) { - return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) == sign; -} + return ((ay-by)*(cx-bx) + (bx-ax)*(cy-by) >= 0) === sign; +}; /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -8400,7 +8359,7 @@ Phaser.Camera = function (game, id, x, y, width, height) { * Camera view. * The view into the world we wish to render (by default the game dimensions). * The x/y values are in world coordinates, not screen coordinates, the width/height is how many pixels to render. - * Objects outside of this view are not rendered (unless set to ignore the Camera, i.e. UI?). + * Objects outside of this view are not rendered if set to camera cull. * @property {Phaser.Rectangle} view */ this.view = new Phaser.Rectangle(x, y, width, height); @@ -8447,6 +8406,9 @@ Phaser.Camera = function (game, id, x, y, width, height) { */ this._edge = 0; + /** + * @property {PIXI.DisplayObject} displayObject - The display object to which all game objects are added. Set by World.boot + */ this.displayObject = null; }; @@ -8564,6 +8526,11 @@ Phaser.Camera.prototype = { }, + /** + * Internal method + * @method Phaser.Camera#updateTarget + * @private + */ updateTarget: function () { if (this.deadzone) @@ -8603,9 +8570,13 @@ Phaser.Camera.prototype = { }, + /** + * Update the Camera bounds to match the game world. + * @method Phaser.Camera#setBoundsToWorld + */ setBoundsToWorld: function () { - this.bounds.setTo(this.game.world.x, this.game.world.y, this.game.world.width, this.game.world.height); + this.bounds.setTo(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height); }, @@ -8625,10 +8596,10 @@ Phaser.Camera.prototype = { this.view.x = this.bounds.x; } - if (this.view.x > this.bounds.right - this.width) + if (this.view.right > this.bounds.right) { this.atLimit.x = true; - this.view.x = (this.bounds.right - this.width) + 1; + this.view.x = this.bounds.right - this.width; } if (this.view.y < this.bounds.top) @@ -8637,10 +8608,10 @@ Phaser.Camera.prototype = { this.view.y = this.bounds.top; } - if (this.view.y > this.bounds.bottom - this.height) + if (this.view.bottom > this.bounds.bottom) { this.atLimit.y = true; - this.view.y = (this.bounds.bottom - this.height) + 1; + this.view.y = this.bounds.bottom - this.height; } this.view.floor(); @@ -8683,6 +8654,8 @@ Phaser.Camera.prototype = { }; +Phaser.Camera.prototype.constructor = Phaser.Camera; + /** * The Cameras x coordinate. This value is automatically clamped if it falls outside of the World bounds. * @name Phaser.Camera#x @@ -8765,7 +8738,7 @@ Object.defineProperty(Phaser.Camera.prototype, "height", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -8933,11 +8906,13 @@ Phaser.State.prototype = { }; +Phaser.State.prototype.constructor = Phaser.State; + /* jshint newcap: false */ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -8967,7 +8942,7 @@ Phaser.StateManager = function (game, pendingState) { */ this._pendingState = null; - if (pendingState !== null) + if (typeof pendingState !== 'undefined' && pendingState !== null) { this._pendingState = pendingState; } @@ -9215,7 +9190,8 @@ Phaser.StateManager.prototype = { }, /** - * Description. + * Checks i a given phaser state is valid. + * State must exist and have at least one callback function registered.. * @method Phaser.StateManager#checkState * @param {string} key - The key of the state you want to check. * @return {boolean} Description. @@ -9282,7 +9258,7 @@ Phaser.StateManager.prototype = { * Sets the current State. Should not be called directly (use StateManager.start) * @method Phaser.StateManager#setCurrentState * @param {string} key - State key. - * @protected + * @private */ setCurrentState: function (key) { @@ -9312,6 +9288,17 @@ Phaser.StateManager.prototype = { }, + /** + * Gets the current State. + * + * @method Phaser.StateManager#getCurrentState + * @return Phaser.State + * @public + */ + getCurrentState: function() { + return this.states[this.current]; + }, + /** * @method Phaser.StateManager#loadComplete * @protected @@ -9448,9 +9435,11 @@ Phaser.StateManager.prototype = { }; +Phaser.StateManager.prototype.constructor = Phaser.StateManager; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -9602,9 +9591,12 @@ Phaser.LinkedList.prototype = { } }; + +Phaser.LinkedList.prototype.constructor = Phaser.LinkedList; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -9905,9 +9897,11 @@ Phaser.Signal.prototype = { }; +Phaser.Signal.prototype.constructor = Phaser.Signal; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -10068,9 +10062,11 @@ Phaser.SignalBinding.prototype = { }; +Phaser.SignalBinding.prototype.constructor = Phaser.SignalBinding; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -10194,6 +10190,8 @@ Phaser.Filter.prototype = { }; +Phaser.Filter.prototype.constructor = Phaser.Filter; + /** * @name Phaser.Filter#width * @property {number} width - The width (resolution uniform) @@ -10228,7 +10226,7 @@ Object.defineProperty(Phaser.Filter.prototype, 'height', { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -10348,11 +10346,13 @@ Phaser.Plugin.prototype = { }; +Phaser.Plugin.prototype.constructor = Phaser.Plugin; + /* jshint newcap: false */ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -10646,9 +10646,11 @@ Phaser.PluginManager.prototype = { }; +Phaser.PluginManager.prototype.constructor = Phaser.PluginManager; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -10672,7 +10674,6 @@ Phaser.Stage = function (game, width, height) { /** * @property {string} game - Background color of the stage (defaults to black). Set via the public backgroundColor property. * @private - * @default 'rgb(0,0,0)' */ this._backgroundColor = 'rgb(0,0,0)'; @@ -10682,10 +10683,9 @@ Phaser.Stage = function (game, width, height) { this.offset = new Phaser.Point(); /** - * @property {HTMLCanvasElement} canvas - Reference to the newly created <canvas> element. + * @property {HTMLCanvasElement} canvas - Reference to the newly created `canvas` element. */ - this.canvas = Phaser.Canvas.create(width, height); - this.canvas.style['-webkit-full-screen'] = 'width: 100%; height: 100%'; + this.canvas = null; /** * @property {PIXI.Stage} _stage - The Pixi Stage which is hooked to the renderer. @@ -10695,11 +10695,21 @@ Phaser.Stage = function (game, width, height) { this._stage.name = '_stage_root'; this._stage.interactive = false; + /** + * @property {PIXI.Stage} display - The Pixi Stage which is hooked to the renderer. + */ + this.display = this._stage; + /** * @property {number} scaleMode - The current scaleMode. */ this.scaleMode = Phaser.StageScaleMode.NO_SCALE; + /* + * @property {number} fullScreenScaleMode - Scale mode to be used in fullScreen + */ + this.fullScreenScaleMode = Phaser.StageScaleMode.NO_SCALE; + /** * @property {Phaser.StageScaleMode} scale - The scale of the current running game. */ @@ -10710,6 +10720,12 @@ Phaser.Stage = function (game, width, height) { */ this.aspectRatio = width / height; + /** + * @property {boolean} disableVisibilityChange - By default if the browser tab loses focus the game will pause. You can stop that behaviour by setting this property to true. + * @default + */ + this.disableVisibilityChange = false; + /** * @property {number} _nextOffsetCheck - The time to run the next offset check. * @private @@ -10722,10 +10738,73 @@ Phaser.Stage = function (game, width, height) { */ this.checkOffsetInterval = 2500; + if (game.config) + { + this.parseConfig(game.config); + } + else + { + this.canvas = Phaser.Canvas.create(width, height); + this.canvas.style['-webkit-full-screen'] = 'width: 100%; height: 100%'; + } + }; Phaser.Stage.prototype = { + /** + * Parses a Game configuration object. + * + * @method Phaser.Stage#parseConfig + * @protected + */ + parseConfig: function (config) { + + if (config['canvasID']) + { + this.canvas = Phaser.Canvas.create(this.game.width, this.game.height, config['canvasID']); + } + else + { + this.canvas = Phaser.Canvas.create(this.game.width, this.game.height); + } + + if (config['canvasStyle']) + { + this.canvas.stlye = config['canvasStyle']; + } + else + { + this.canvas.style['-webkit-full-screen'] = 'width: 100%; height: 100%'; + } + + if (config['checkOffsetInterval']) + { + this.checkOffsetInterval = config['checkOffsetInterval']; + } + + if (config['disableVisibilityChange']) + { + this.disableVisibilityChange = config['disableVisibilityChange']; + } + + if (config['fullScreenScaleMode']) + { + this.fullScreenScaleMode = config['fullScreenScaleMode']; + } + + if (config['scaleMode']) + { + this.scaleMode = config['scaleMode']; + } + + if (config['backgroundColor']) + { + this.backgroundColor = config['backgroundColor']; + } + + }, + /** * Initialises the stage and adds the event listeners. * @method Phaser.Stage#boot @@ -10788,7 +10867,7 @@ Phaser.Stage.prototype = { return; } - if (event.type == 'pagehide' || event.type == 'blur' || document['hidden'] === true || document['webkitHidden'] === true) + if (this.game.paused === false && (event.type == 'pagehide' || event.type == 'blur' || document['hidden'] === true || document['webkitHidden'] === true)) { this.game.paused = true; } @@ -10801,6 +10880,8 @@ Phaser.Stage.prototype = { }; +Phaser.Stage.prototype.constructor = Phaser.Stage; + /** * @name Phaser.Stage#backgroundColor * @property {number|string} backgroundColor - Gets and sets the background color of the stage. The color can be given as a number: 0xff0000 or a hex string: '#ff0000' @@ -10840,7 +10921,7 @@ Object.defineProperty(Phaser.Stage.prototype, "backgroundColor", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -10850,32 +10931,32 @@ Object.defineProperty(Phaser.Stage.prototype, "backgroundColor", { * @classdesc A Group is a container for display objects that allows for fast pooling, recycling and collision checks. * @constructor * @param {Phaser.Game} game - A reference to the currently running game. -* @param {*} parent - The parent Group or DisplayObjectContainer that will hold this group, if any. +* @param {*} parent - The parent Group or DisplayObjectContainer that will hold this group, if any. If undefined it will use game.world. * @param {string} [name=group] - A name for this Group. Not used internally but useful for debugging. * @param {boolean} [useStage=false] - Should the DisplayObjectContainer this Group creates be added to the World (default, false) or direct to the Stage (true). */ Phaser.Group = function (game, parent, name, useStage) { - if (typeof parent === 'undefined' || typeof parent === null) + /** + * @property {Phaser.Game} game - A reference to the currently running Game. + */ + this.game = game; + + if (typeof parent === 'undefined') { parent = game.world; } + /** + * @property {string} name - A name for this Group. Not used internally but useful for debugging. + */ + this.name = name || 'group'; + if (typeof useStage === 'undefined') { useStage = false; } - /** - * @property {Phaser.Game} game - A reference to the currently running Game. - */ - this.game = game; - - /** - * @property {string} name - A name for this Group. Not used internally but useful for debugging. - */ - this.name = name || 'group'; - if (useStage) { this._container = this.game.stage._stage; @@ -10890,7 +10971,6 @@ Phaser.Group = function (game, parent, name, useStage) { if (parent instanceof Phaser.Group) { parent._container.addChild(this._container); - parent._container.updateTransform(); } else { @@ -10911,6 +10991,12 @@ Phaser.Group = function (game, parent, name, useStage) { */ this.type = Phaser.GROUP; + /** + * @property {boolean} alive - The alive property is useful for Groups that are children of other Groups and need to be included/excluded in checks like forEachAlive. + * @default + */ + this.alive = true; + /** * @property {boolean} exists - If exists is true the the Group is updated, otherwise it is skipped. * @default @@ -10918,9 +11004,22 @@ Phaser.Group = function (game, parent, name, useStage) { this.exists = true; /** - * @property {Phaser.Point} scale - Replaces the PIXI.Point with a slightly more flexible one. + * @property {Phaser.Group} group - The parent Group of this Group, if a child of another. */ - this.scale = new Phaser.Point(1, 1); + this.group = null; + + // Replaces the PIXI.Point with a slightly more flexible one. + this._container.scale = new Phaser.Point(1, 1); + + /** + * @property {Phaser.Point} scale - The scane of the Group container. + */ + this.scale = this._container.scale; + + /** + * @property {Phaser.Point} pivot - The pivot point of the Group container. + */ + this.pivot = this._container.pivot; /** * The cursor is a simple way to iterate through the objects in a Group using the Group.next and Group.previous functions. @@ -10978,16 +11077,27 @@ Phaser.Group.prototype = { if (child.group !== this) { - child.group = this; - - if (child.events) + if (child.type && child.type === Phaser.GROUP) { - child.events.onAddedToGroup.dispatch(child, this); + child.group = this; + + this._container.addChild(child._container); + + child._container.updateTransform(); } + else + { + child.group = this; - this._container.addChild(child); + this._container.addChild(child); - child.updateTransform(); + child.updateTransform(); + + if (child.events) + { + child.events.onAddedToGroup.dispatch(child, this); + } + } if (this.cursor === null) { @@ -11012,16 +11122,27 @@ Phaser.Group.prototype = { if (child.group !== this) { - child.group = this; - - if (child.events) + if (child.type && child.type === Phaser.GROUP) { - child.events.onAddedToGroup.dispatch(child, this); + child.group = this; + + this._container.addChildAt(child._container, index); + + child._container.updateTransform(); } + else + { + child.group = this; - this._container.addChildAt(child, index); + this._container.addChildAt(child, index); - child.updateTransform(); + child.updateTransform(); + + if (child.events) + { + child.events.onAddedToGroup.dispatch(child, this); + } + } if (this.cursor === null) { @@ -11060,7 +11181,7 @@ Phaser.Group.prototype = { */ create: function (x, y, key, frame, exists) { - if (typeof exists == 'undefined') { exists = true; } + if (typeof exists === 'undefined') { exists = true; } var child = new Phaser.Sprite(this.game, x, y, key, frame); @@ -11069,15 +11190,15 @@ Phaser.Group.prototype = { child.visible = exists; child.alive = exists; + this._container.addChild(child); + + child.updateTransform(); + if (child.events) { child.events.onAddedToGroup.dispatch(child, this); } - this._container.addChild(child); - - child.updateTransform(); - if (this.cursor === null) { this.cursor = child; @@ -11100,7 +11221,7 @@ Phaser.Group.prototype = { */ createMultiple: function (quantity, key, frame, exists) { - if (typeof exists == 'undefined') { exists = false; } + if (typeof exists === 'undefined') { exists = false; } for (var i = 0; i < quantity; i++) { @@ -11111,14 +11232,15 @@ Phaser.Group.prototype = { child.visible = exists; child.alive = exists; + this._container.addChild(child); + + child.updateTransform(); + if (child.events) { child.events.onAddedToGroup.dispatch(child, this); } - this._container.addChild(child); - child.updateTransform(); - if (this.cursor === null) { this.cursor = child; @@ -11172,6 +11294,11 @@ Phaser.Group.prototype = { }, + /** + * Internal test. + * + * @method Phaser.Group#childTest + */ childTest: function (prefix, child) { var s = prefix + ' next: '; @@ -11200,13 +11327,16 @@ Phaser.Group.prototype = { }, + /** + * Internal test. + * + * @method Phaser.Group#swapIndex + */ swapIndex: function (index1, index2) { var child1 = this.getAt(index1); var child2 = this.getAt(index2); - console.log('swapIndex ', index1, ' with ', index2); - this.swap(child1, child2); }, @@ -11471,6 +11601,32 @@ Phaser.Group.prototype = { }, + /** + * This function allows you to quickly set a property on a single child of this Group to a new value. + * The operation parameter controls how the new value is assigned to the property, from simple replacement to addition and multiplication. + * + * @method Phaser.Group#set + * @param {Phaser.Sprite} child - The child to set the property on. + * @param {string} key - The property, as a string, to be set. For example: 'body.velocity.x' + * @param {*} value - The value that will be set. + * @param {boolean} [checkAlive=false] - If set then the child will only be updated if alive=true. + * @param {boolean} [checkVisible=false] - If set then the child will only be updated if visible=true. + * @param {number} [operation=0] - Controls how the value is assigned. A value of 0 replaces the value with the new one. A value of 1 adds it, 2 subtracts it, 3 multiplies it and 4 divides it. + */ + set: function (child, key, value, checkAlive, checkVisible, operation) { + + key = key.split('.'); + + if (typeof checkAlive === 'undefined') { checkAlive = false; } + if (typeof checkVisible === 'undefined') { checkVisible = false; } + + if ((checkAlive === false || (checkAlive && child.alive)) && (checkVisible === false || (checkVisible && child.visible))) + { + this.setProperty(child, key, value, operation); + } + + }, + /** * This function allows you to quickly set the same property across all children of this Group to a new value. * The operation parameter controls how the new value is assigned to the property, from simple replacement to addition and multiplication. @@ -11606,7 +11762,7 @@ Phaser.Group.prototype = { }, /** - * Calls a function on all of the children that have exists=true in this Group. + * Returns a reference to a function that exists on a child of the Group based on the given callback array. * * @method Phaser.Group#callbackFromArray * @param {object} child - The object to inspect. @@ -11664,7 +11820,7 @@ Phaser.Group.prototype = { * * @method Phaser.Group#callAll * @param {string} method - A string containing the name of the function that will be called. The function must exist on the child. - * @param {string} [context=''] - A string containing the context under which the method will be executed. Leave to '' to default to the child. + * @param {string} [context=null] - A string containing the context under which the method will be executed. Set to null to default to the child. * @param {...*} parameter - Additional parameters that will be passed to the method. */ callAll: function (method, context) { @@ -11731,6 +11887,7 @@ Phaser.Group.prototype = { * Allows you to call your own function on each member of this Group. You must pass the callback and context in which it will run. * After the checkExists parameter you can add as many parameters as you like, which will all be passed to the callback along with the child. * For example: Group.forEach(awardBonusGold, this, true, 100, 500) + * Note: Currently this will skip any children which are Groups themselves. * * @method Phaser.Group#forEach * @param {function} callback - The function that will be called. Each child of the Group will be passed to it as its first parameter. @@ -11881,12 +12038,13 @@ Phaser.Group.prototype = { * @param {number} returnType - How to return the data from this method. Either Phaser.Group.RETURN_NONE, Phaser.Group.RETURN_TOTAL or Phaser.Group.RETURN_CHILD. * @param {function} [callback=null] - Optional function that will be called on each matching child. Each child of the Group will be passed to it as its first parameter. * @param {Object} [callbackContext] - The context in which the function should be called (usually 'this'). + * @return {any} Returns either a numeric total (if RETURN_TOTAL was specified) or the child object. */ iterate: function (key, value, returnType, callback, callbackContext, args) { - if (returnType == Phaser.Group.RETURN_TOTAL && this._container.children.length === 0) + if (returnType === Phaser.Group.RETURN_TOTAL && this._container.children.length === 0) { - return -1; + return 0; } if (typeof callback === 'undefined') @@ -11912,7 +12070,7 @@ Phaser.Group.prototype = { callback.apply(callbackContext, args); } - if (returnType == Phaser.Group.RETURN_CHILD) + if (returnType === Phaser.Group.RETURN_CHILD) { return currentNode; } @@ -11923,11 +12081,11 @@ Phaser.Group.prototype = { while (currentNode != this._container.last._iNext); } - if (returnType == Phaser.Group.RETURN_TOTAL) + if (returnType === Phaser.Group.RETURN_TOTAL) { return total; } - else if (returnType == Phaser.Group.RETURN_CHILD) + else if (returnType === Phaser.Group.RETURN_CHILD) { return null; } @@ -11982,7 +12140,7 @@ Phaser.Group.prototype = { * Call this function to find out how many members of the group are alive. * * @method Phaser.Group#countLiving - * @return {number} The number of children flagged as alive. Returns -1 if Group is empty. + * @return {number} The number of children flagged as alive. */ countLiving: function () { @@ -11994,7 +12152,7 @@ Phaser.Group.prototype = { * Call this function to find out how many members of the group are dead. * * @method Phaser.Group#countDead - * @return {number} The number of children flagged as dead. Returns -1 if Group is empty. + * @return {number} The number of children flagged as dead. */ countDead: function () { @@ -12138,11 +12296,31 @@ Phaser.Group.prototype = { * Destroys this Group. Removes all children, then removes the container from the display list and nulls references. * * @method Phaser.Group#destroy + * @param {boolean} [destroyChildren=false] - Should every child of this Group have its destroy method called? */ - destroy: function () { + destroy: function (destroyChildren) { - this.removeAll(); + if (typeof destroyChildren === 'undefined') { destroyChildren = false; } + if (destroyChildren) + { + if (this._container.children.length > 0) + { + do + { + if (this._container.children[0].group) + { + this._container.children[0].destroy(); + } + } + while (this._container.children.length > 0); + } + } + else + { + this.removeAll(); + } + this._container.parent.removeChild(this._container); this._container = null; @@ -12195,130 +12373,52 @@ Phaser.Group.prototype = { return true; - }, - - /** - * Dumps out a list of Group children and their index positions to the browser console. Useful for group debugging. - * - * @method Phaser.Group#dump - * @param {boolean} [full=false] - If full the dump will include the entire display list, start from the Stage. Otherwise it will only include this container. - */ - dump: function (full) { - - if (typeof full == 'undefined') - { - full = false; - } - - var spacing = 20; - var output = "\n" + Phaser.Utils.pad('Node', spacing) + "|" + Phaser.Utils.pad('Next', spacing) + "|" + Phaser.Utils.pad('Previous', spacing) + "|" + Phaser.Utils.pad('First', spacing) + "|" + Phaser.Utils.pad('Last', spacing); - - console.log(output); - - var output = Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing); - console.log(output); - - if (full) - { - var testObject = this.game.stage._stage.last._iNext; - var displayObject = this.game.stage._stage; - } - else - { - var testObject = this._container.last._iNext; - var displayObject = this._container; - } - - do - { - var name = displayObject.name || '*'; - - if (this.cursor == displayObject) - { - var name = '> ' + name; - } - - var nameNext = '-'; - var namePrev = '-'; - var nameFirst = '-'; - var nameLast = '-'; - - if (displayObject._iNext) - { - nameNext = displayObject._iNext.name; - } - - if (displayObject._iPrev) - { - namePrev = displayObject._iPrev.name; - } - - if (displayObject.first) - { - nameFirst = displayObject.first.name; - } - - if (displayObject.last) - { - nameLast = displayObject.last.name; - } - - if (typeof nameNext === 'undefined') - { - nameNext = '-'; - } - - if (typeof namePrev === 'undefined') - { - namePrev = '-'; - } - - if (typeof nameFirst === 'undefined') - { - nameFirst = '-'; - } - - if (typeof nameLast === 'undefined') - { - nameLast = '-'; - } - - var output = Phaser.Utils.pad(name, spacing) + "|" + Phaser.Utils.pad(nameNext, spacing) + "|" + Phaser.Utils.pad(namePrev, spacing) + "|" + Phaser.Utils.pad(nameFirst, spacing) + "|" + Phaser.Utils.pad(nameLast, spacing); - console.log(output); - - displayObject = displayObject._iNext; - - } - while(displayObject != testObject) - } }; +Phaser.Group.prototype.constructor = Phaser.Group; + /** * @name Phaser.Group#total -* @property {number} total - The total number of children in this Group, regardless of their alive state. +* @property {number} total - The total number of children in this Group who have a state of exists = true. * @readonly */ Object.defineProperty(Phaser.Group.prototype, "total", { get: function () { - return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL); - // return this._container.children.length; + + if (this._container) + { + return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL); + } + else + { + return 0; + } + } }); /** * @name Phaser.Group#length -* @property {number} length - The number of children in this Group. +* @property {number} length - The total number of children in this Group, regardless of their exists/alive status. * @readonly */ Object.defineProperty(Phaser.Group.prototype, "length", { get: function () { - return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL); - // return this._container.children.length; + + if (this._container) + { + return this._container.children.length; + } + else + { + return 0; + } + } }); @@ -12429,7 +12529,7 @@ Object.defineProperty(Phaser.Group.prototype, "alpha", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -12441,6 +12541,7 @@ Object.defineProperty(Phaser.Group.prototype, "alpha", { * the world at world-based coordinates. By default a world is created the same size as your Stage. * * @class Phaser.World +* @extends Phaser.Group * @constructor * @param {Phaser.Game} game - Reference to the current game instance. */ @@ -12448,11 +12549,6 @@ Phaser.World = function (game) { Phaser.Group.call(this, game, null, '__world', false); - /** - * @property {Phaser.Point} scale - Replaces the PIXI.Point with a slightly more flexible one. - */ - this.scale = new Phaser.Point(1, 1); - /** * The World has no fixed size, but it does have a bounds outside of which objects are no longer considered as being "in world" and you should use this to clean-up the display list and purge dead objects. * By default we set the Bounds to be from 0,0 to Game.width,Game.height. I.e. it will match the size given to the game constructor with 0,0 representing the top-left of the display. @@ -12494,34 +12590,21 @@ Phaser.World.prototype.boot = function () { } /** -* This is called automatically every frame, and is where main logic happens. +* This is called automatically after the plugins preUpdate and before the State.update. +* Most objects have preUpdate methods and it's where initial movement, drawing and calculations are done. * * @method Phaser.World#update */ -Phaser.World.prototype.update = function () { - - this.currentRenderOrderID = 0; +Phaser.World.prototype.preUpdate = function () { if (this.game.stage._stage.first._iNext) { var currentNode = this.game.stage._stage.first._iNext; - var skipChildren; do { - skipChildren = false; - - if (currentNode['preUpdate']) - { - skipChildren = (currentNode.preUpdate() === false); - } - - if (currentNode['update']) - { - skipChildren = (currentNode.update() === false) || skipChildren; - } - - if (skipChildren) + // If preUpdate exists, and it returns false, skip PIXI child objects + if (currentNode['preUpdate'] && !currentNode.preUpdate()) { currentNode = currentNode.last._iNext; } @@ -12537,48 +12620,123 @@ Phaser.World.prototype.update = function () { } /** -* This is called automatically every frame, and is where main logic happens. -* @method Phaser.World#postUpdate +* This is called automatically after the State.update, but before particles or plugins update. +* Most objects won't have an update method set unless explicitly given one. +* +* @method Phaser.World#update */ -Phaser.World.prototype.postUpdate = function () { +Phaser.World.prototype.update = function () { + this.currentRenderOrderID = 0; + if (this.game.stage._stage.first._iNext) { var currentNode = this.game.stage._stage.first._iNext; do { - if (currentNode['postUpdate']) + // If update exists, and it returns false, skip PIXI child objects + if (currentNode['update'] && !currentNode.update()) { - currentNode.postUpdate(); + currentNode = currentNode.last._iNext; + } + else + { + currentNode = currentNode._iNext; } - currentNode = currentNode._iNext; } while (currentNode != this.game.stage._stage.last._iNext) } - this.camera.update(); +} + +/** +* This is called automatically before the renderer runs and after the plugins have updated. +* In postUpdate this is where all the final physics calculatations and object positioning happens. +* The objects are processed in the order of the display list. +* The only exception to this is if the camera is following an object, in which case that is updated first. +* +* @method Phaser.World#postUpdate +*/ +Phaser.World.prototype.postUpdate = function () { + + if (this.camera.target && this.camera.target['postUpdate']) + { + this.camera.target.postUpdate(); + + this.camera.update(); + + if (this.game.stage._stage.first._iNext) + { + var currentNode = this.game.stage._stage.first._iNext; + + do + { + if (currentNode['postUpdate'] && currentNode !== this.camera.target) + { + currentNode.postUpdate(); + } + + currentNode = currentNode._iNext; + } + while (currentNode != this.game.stage._stage.last._iNext) + } + } + else + { + this.camera.update(); + + if (this.game.stage._stage.first._iNext) + { + var currentNode = this.game.stage._stage.first._iNext; + + do + { + if (currentNode['postUpdate']) + { + currentNode.postUpdate(); + } + + currentNode = currentNode._iNext; + } + while (currentNode != this.game.stage._stage.last._iNext) + } + } + } /** * Updates the size of this world. Note that this doesn't modify the world x/y coordinates, just the width and height. -* If you need to adjust the bounds of the world +* * @method Phaser.World#setBounds * @param {number} x - Top left most corner of the world. * @param {number} y - Top left most corner of the world. -* @param {number} width - New width of the world. -* @param {number} height - New height of the world. +* @param {number} width - New width of the world. Can never be smaller than the Game.width. +* @param {number} height - New height of the world. Can never be smaller than the Game.height. */ Phaser.World.prototype.setBounds = function (x, y, width, height) { + if (width < this.game.width) + { + width = this.game.width; + } + + if (height < this.game.height) + { + height = this.game.height; + } + this.bounds.setTo(x, y, width, height); if (this.camera.bounds) { + // The Camera can never be smaller than the game size this.camera.bounds.setTo(x, y, width, height); } + this.game.physics.setBoundsToWorld(); + } /** @@ -12716,7 +12874,7 @@ Object.defineProperty(Phaser.World.prototype, "visible", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -12733,64 +12891,68 @@ Object.defineProperty(Phaser.World.prototype, "visible", { * @param {number} [width=800] - The width of your game in game pixels. * @param {number} [height=600] - The height of your game in game pixels. * @param {number} [renderer=Phaser.AUTO] - Which renderer to use: Phaser.AUTO will auto-detect, Phaser.WEBGL, Phaser.CANVAS or Phaser.HEADLESS (no rendering at all). -* @param {HTMLElement} [parent=''] - The Games DOM parent. -* @param {any} [state=null] - Description. +* @param {string|HTMLElement} [parent=''] - The DOM element into which this games canvas will be injected. Either a DOM ID (string) or the element itself. +* @param {object} [state=null] - The default state object. A object consisting of Phaser.State functions (preload, create, update, render) or null. * @param {boolean} [transparent=false] - Use a transparent canvas background or not. * @param {boolean} [antialias=true] - Anti-alias graphics. */ Phaser.Game = function (width, height, renderer, parent, state, transparent, antialias) { - width = width || 800; - height = height || 600; - renderer = renderer || Phaser.AUTO; - parent = parent || ''; - state = state || null; - - if (typeof transparent == 'undefined') { transparent = false; } - if (typeof antialias == 'undefined') { antialias = true; } - /** * @property {number} id - Phaser Game ID (for when Pixi supports multiple instances). */ this.id = Phaser.GAMES.push(this) - 1; /** - * @property {HTMLElement} parent - The Games DOM parent. + * @property {object} config - The Phaser.Game configuration object. */ - this.parent = parent; + this.config = null; - // Do some more intelligent size parsing here, so they can set "100%" for example, maybe pass the scale mode in here too? + /** + * @property {HTMLElement} parent - The Games DOM parent. + * @default + */ + this.parent = ''; /** * @property {number} width - The Game width (in pixels). + * @default */ - this.width = width; + this.width = 800; /** * @property {number} height - The Game height (in pixels). + * @default */ - this.height = height; + this.height = 600; /** * @property {boolean} transparent - Use a transparent canvas background or not. + * @default */ - this.transparent = transparent; + this.transparent = false; /** * @property {boolean} antialias - Anti-alias graphics (in WebGL this helps with edges, in Canvas2D it retains pixel-art quality). + * @default */ - this.antialias = antialias; + this.antialias = true; /** * @property {number} renderer - The Pixi Renderer * @default */ - this.renderer = null; + this.renderer = Phaser.AUTO; + + /** + * @property {number} renderType - The Renderer this Phaser.Game will use. Either Phaser.RENDERER_AUTO, Phaser.RENDERER_CANVAS or Phaser.RENDERER_WEBGL. + */ + this.renderType = Phaser.AUTO; /** * @property {number} state - The StateManager. */ - this.state = new Phaser.StateManager(this, state); + this.state = null; /** * @property {boolean} _paused - Is game paused? @@ -12799,11 +12961,6 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant */ this._paused = false; - /** - * @property {number} renderType - The Renderer this Phaser.Game will use. Either Phaser.RENDERER_AUTO, Phaser.RENDERER_CANVAS or Phaser.RENDERER_WEBGL. - */ - this.renderType = renderer; - /** * @property {boolean} _loadComplete - Whether load complete loading or not. * @private @@ -12943,6 +13100,68 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant */ this.particles = null; + /** + * @property {boolean} stepping - Enable core loop stepping with Game.enableStep(). + * @default + * @readonly + */ + this.stepping = false; + + /** + * @property {boolean} stepping - An internal property used by enableStep, but also useful to query from your own game objects. + * @default + * @readonly + */ + this.pendingStep = false; + + /** + * @property {number} stepCount - When stepping is enabled this contains the current step cycle. + * @default + * @readonly + */ + this.stepCount = 0; + + // Parse the configuration object (if any) + if (arguments.length === 1 && typeof arguments[0] === 'object') + { + this.parseConfig(arguments[0]); + } + else + { + if (typeof width !== 'undefined') + { + this.width = width; + } + + if (typeof height !== 'undefined') + { + this.height = height; + } + + if (typeof renderer !== 'undefined') + { + this.renderer = renderer; + this.renderType = renderer; + } + + if (typeof parent !== 'undefined') + { + this.parent = parent; + } + + if (typeof transparent !== 'undefined') + { + this.transparent = transparent; + } + + if (typeof antialias !== 'undefined') + { + this.antialias = antialias; + } + + this.state = new Phaser.StateManager(this, state); + } + var _this = this; this._onBoot = function () { @@ -12965,6 +13184,99 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant Phaser.Game.prototype = { + /** + * Parses a Game configuration object. + * + * @method Phaser.Game#parseConfig + * @protected + */ + parseConfig: function (config) { + + this.config = config; + + if (config['width']) + { + this.width = this.parseDimension(config['width'], 0); + } + + if (config['height']) + { + this.height = this.parseDimension(config['height'], 1); + } + + if (config['renderer']) + { + this.renderer = config['renderer']; + this.renderType = config['renderer']; + } + + if (config['parent']) + { + this.parent = config['parent']; + } + + if (config['transparent']) + { + this.transparent = config['transparent']; + } + + if (config['antialias']) + { + this.antialias = config['antialias']; + } + + var state = null; + + if (config['state']) + { + state = config['state']; + } + + this.state = new Phaser.StateManager(this, state); + + }, + + /** + * Get dimension. + * + * @method Phaser.Game#parseDimension + * @protected + */ + parseDimension: function (size, dimension) { + + var f = 0; + var px = 0; + + if (typeof size === 'string') + { + // %? + if (size.substr(-1) === '%') + { + f = parseInt(size, 10) / 100; + + if (dimension === 0) + { + px = window.innerWidth * f; + } + else + { + px = window.innerHeight * f; + } + } + else + { + px = parseInt(size, 10); + } + } + else + { + px = size; + } + + return px; + + }, + /** * Initialize engine sub modules and start the game. * @@ -13014,6 +13326,7 @@ Phaser.Game.prototype = { this.net = new Phaser.Net(this); this.debug = new Phaser.Utils.Debug(this); + this.time.boot(); this.stage.boot(); this.world.boot(); this.input.boot(); @@ -13088,6 +13401,14 @@ Phaser.Game.prototype = { */ setUpRenderer: function () { + /* + if (this.device.trident) + { + // Pixi WebGL renderer on IE11 doesn't work correctly with masks, if you need them you may want to comment this block out + this.renderType = Phaser.CANVAS; + } + */ + if (this.renderType === Phaser.HEADLESS || this.renderType === Phaser.CANVAS || (this.renderType === Phaser.AUTO && this.device.webGL === false)) { if (this.device.canvas) @@ -13154,20 +13475,28 @@ Phaser.Game.prototype = { } else { - this.plugins.preUpdate(); - this.physics.preUpdate(); + if (!this.pendingStep) + { + if (this.stepping) + { + this.pendingStep = true; + } - this.stage.update(); - this.input.update(); - this.tweens.update(); - this.sound.update(); - this.world.update(); - this.particles.update(); - this.state.update(); - this.plugins.update(); + this.plugins.preUpdate(); + this.world.preUpdate(); - this.world.postUpdate(); - this.plugins.postUpdate(); + this.stage.update(); + this.tweens.update(); + this.sound.update(); + this.input.update(); + this.state.update(); + this.world.update(); + this.particles.update(); + this.plugins.update(); + + this.world.postUpdate(); + this.plugins.postUpdate(); + } if (this.renderType !== Phaser.HEADLESS) { @@ -13177,11 +13506,49 @@ Phaser.Game.prototype = { this.plugins.postRender(); } - } }, + /** + * Enable core game loop stepping. When enabled you must call game.step() directly (perhaps via a DOM button?) + * Calling step will advance the game loop by one frame. This is extremely useful to hard to track down errors! + * + * @method Phaser.Game#enableStep + */ + enableStep: function () { + + this.stepping = true; + this.pendingStep = false; + this.stepCount = 0; + + }, + + /** + * Disables core game loop stepping. + * + * @method Phaser.Game#disableStep + */ + disableStep: function () { + + this.stepping = false; + this.pendingStep = false; + + }, + + /** + * When stepping is enabled you must call this function directly (perhaps via a DOM button?) to advance the game loop by one frame. + * This is extremely useful to hard to track down errors! Use the internal stepCount property to monitor progress. + * + * @method Phaser.Game#step + */ + step: function () { + + this.pendingStep = false; + this.stepCount++; + + }, + /** * Nuke the entire game from orbit * @@ -13209,6 +13576,8 @@ Phaser.Game.prototype = { }; +Phaser.Game.prototype.constructor = Phaser.Game; + /** * The paused state of the Game. A paused game doesn't update any of its subsystems. * When a game is paused the onPause event is dispatched. When it is resumed the onResume event is dispatched. @@ -13250,7 +13619,7 @@ Object.defineProperty(Phaser.Game.prototype, "paused", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -13280,6 +13649,16 @@ Phaser.Input = function (game) { * @default */ this.hitContext = null; + + /** + * @property {function} moveCallback - An optional callback that will be fired every time the activePointer receives a move event from the DOM. Set to null to disable. + */ + this.moveCallback = null; + + /** + * @property {object} moveCallbackContext - The context in which the moveCallback will be sent. Defaults to Phaser.Input but can be set to any valid JS object. + */ + this.moveCallbackContext = this; }; @@ -13556,6 +13935,13 @@ Phaser.Input.prototype = { */ mspointer: null, + /** + * The Gamepad Input manager. + * @property {Phaser.Gamepad} gamepad - The Gamepad Input manager. + * @default + */ + gamepad: null, + /** * A Signal that is dispatched each time a pointer is pressed down. * @property {Phaser.Signal} onDown @@ -13605,6 +13991,7 @@ Phaser.Input.prototype = { this.keyboard = new Phaser.Keyboard(this.game); this.touch = new Phaser.Touch(this.game); this.mspointer = new Phaser.MSPointer(this.game); + this.gamepad = new Phaser.Gamepad(this.game); this.onDown = new Phaser.Signal(); this.onUp = new Phaser.Signal(); @@ -13644,6 +14031,24 @@ Phaser.Input.prototype = { this.keyboard.stop(); this.touch.stop(); this.mspointer.stop(); + this.gamepad.stop(); + + this.moveCallback = null; + + }, + + /** + * Sets a callback that is fired every time the activePointer receives a DOM move event such as a mousemove or touchmove. + * It will be called every time the activePointer moves, which in a multi-touch game can be a lot of times, so this is best + * to only use if you've limited input to a single pointer (i.e. mouse or touch) + * @method Phaser.Input#setMoveCallback + * @param {function} callback - The callback that will be called each time the activePointer receives a DOM move event. + * @param {object} callbackContext - The context in which the callback will be called. + */ + setMoveCallback: function (callback, callbackContext) { + + this.moveCallback = callback; + this.moveCallbackContext = callbackContext; }, @@ -13697,6 +14102,8 @@ Phaser.Input.prototype = { this._oldPosition.copyFrom(this.position); this.mousePointer.update(); + if (this.gamepad.active) { this.gamepad.update(); } + this.pointer1.update(); this.pointer2.update(); @@ -13728,6 +14135,7 @@ Phaser.Input.prototype = { this.keyboard.reset(); this.mousePointer.reset(); + this.gamepad.reset(); for (var i = 1; i <= 10; i++) { @@ -13738,7 +14146,11 @@ Phaser.Input.prototype = { } this.currentPointers = 0; - this.game.stage.canvas.style.cursor = "default"; + + if (this.game.canvas.style.cursor !== 'none') + { + this.game.canvas.style.cursor = 'default'; + } if (hard === true) { @@ -13935,6 +14347,8 @@ Phaser.Input.prototype = { }; +Phaser.Input.prototype.constructor = Phaser.Input; + /** * The X coordinate of the most recently active pointer. This value takes game scaling into account automatically. See Pointer.screenX/clientX for source values. * @name Phaser.Input#x @@ -14050,7 +14464,7 @@ Object.defineProperty(Phaser.Input.prototype, "worldY", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -14220,9 +14634,11 @@ Phaser.Key.prototype = { }; +Phaser.Key.prototype.constructor = Phaser.Key; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -14322,7 +14738,7 @@ Phaser.Keyboard.prototype = { * The Key object can then be polled, have events attached to it, etc. * * @method Phaser.Keyboard#addKey - * @param {number} keycode - The keycode of the key, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR + * @param {number} keycode - The keycode of the key, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR * @return {Phaser.Key} The Key object which you can store locally and reference directly. */ addKey: function (keycode) { @@ -14339,7 +14755,7 @@ Phaser.Keyboard.prototype = { * Removes a Key object from the Keyboard manager. * * @method Phaser.Keyboard#removeKey - * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR + * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR */ removeKey: function (keycode) { @@ -14561,7 +14977,7 @@ Phaser.Keyboard.prototype = { /** * Returns the "just pressed" state of the key. Just pressed is considered true if the key was pressed down within the duration given (default 250ms) * @method Phaser.Keyboard#justPressed - * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR + * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR * @param {number} [duration=250] - The duration below which the key is considered as being just pressed. * @return {boolean} True if the key is just pressed otherwise false. */ @@ -14580,8 +14996,8 @@ Phaser.Keyboard.prototype = { /** * Returns the "just released" state of the Key. Just released is considered as being true if the key was released within the duration given (default 250ms) - * @method Phaser.Keyboard#justPressed - * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR + * @method Phaser.Keyboard#justReleased + * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR * @param {number} [duration=250] - The duration below which the key is considered as being just released. * @return {boolean} True if the key is just released otherwise false. */ @@ -14601,7 +15017,7 @@ Phaser.Keyboard.prototype = { /** * Returns true of the key is currently pressed down. Note that it can only detect key presses on the web browser. * @method Phaser.Keyboard#isDown - * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR + * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR * @return {boolean} True if the key is currently down. */ isDown: function (keycode) { @@ -14617,6 +15033,8 @@ Phaser.Keyboard.prototype = { }; +Phaser.Keyboard.prototype.constructor = Phaser.Keyboard; + Phaser.Keyboard.A = "A".charCodeAt(0); Phaser.Keyboard.B = "B".charCodeAt(0); Phaser.Keyboard.C = "C".charCodeAt(0); @@ -14718,7 +15136,7 @@ Phaser.Keyboard.NUM_LOCK = 144; /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -14786,7 +15204,8 @@ Phaser.Mouse = function (game) { this.pointerLock = new Phaser.Signal(); /** - * @property {MouseEvent} event - The browser mouse event. + * @property {MouseEvent} event - The browser mouse DOM event. Will be set to null if no mouse event has ever been received. + * @default */ this.event = null; @@ -15045,9 +15464,11 @@ Phaser.Mouse.prototype = { }; +Phaser.Mouse.prototype.constructor = Phaser.Mouse; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -15213,9 +15634,12 @@ Phaser.MSPointer.prototype = { } }; + +Phaser.MSPointer.prototype.constructor = Phaser.MSPointer; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -15422,7 +15846,7 @@ Phaser.Pointer.prototype = { } // Fix to stop rogue browser plugins from blocking the visibility state event - if (this.game.paused === true && this.game.stage.scale.incorrectOrientation === false) + if (this.game.stage.disableVisibilityChange === false && this.game.paused && this.game.stage.scale.incorrectOrientation === false) { this.game.paused = false; return this; @@ -15472,7 +15896,7 @@ Phaser.Pointer.prototype = { }, /** - * Called internall by the Input Manager. + * Called by the Input Manager. * @method Phaser.Pointer#update */ update: function () { @@ -15551,12 +15975,17 @@ Phaser.Pointer.prototype = { this.game.input.circle.y = this.game.input.y; } - // If the game is paused we don't process any target objects + // If the game is paused we don't process any target objects or callbacks if (this.game.paused) { return this; } + if (this.game.input.moveCallback) + { + this.game.input.moveCallback.call(this.game.input.moveCallbackContext, this, this.x, this.y); + } + // Easy out if we're dragging something and it still exists if (this.targetObject !== null && this.targetObject.isDragged === true) { @@ -15798,6 +16227,8 @@ Phaser.Pointer.prototype = { }; +Phaser.Pointer.prototype.constructor = Phaser.Pointer; + /** * How long the Pointer has been depressed on the touchscreen. If not currently down it returns -1. * @name Phaser.Pointer#duration @@ -15853,7 +16284,7 @@ Object.defineProperty(Phaser.Pointer.prototype, "worldY", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -15920,7 +16351,8 @@ Phaser.Touch = function (game) { this.preventDefault = true; /** - * @property {TouchEvent} event - The browser touch event. + * @property {TouchEvent} event - The browser touch DOM event. Will be set to null if no touch event has ever been received. + * @default */ this.event = null; @@ -16121,13 +16553,6 @@ Phaser.Touch.prototype = { event.preventDefault(); } - /* - for (var i = 0; i < event.changedTouches.length; i++) - { - //console.log('touch enter'); - } - */ - }, /** @@ -16150,13 +16575,6 @@ Phaser.Touch.prototype = { event.preventDefault(); } - /* - for (var i = 0; i < event.changedTouches.length; i++) - { - //console.log('touch leave'); - } - */ - }, /** @@ -16233,9 +16651,12 @@ Phaser.Touch.prototype = { } }; + +Phaser.Touch.prototype.constructor = Phaser.Touch; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -16263,36 +16684,6 @@ Phaser.InputHandler = function (sprite) { */ this.enabled = false; - /** - * @property {Description} parent - Description. - * @default - */ - // this.parent = null; - - /** - * @property {Description} next - Linked List - * @default - */ - // this.next = null; - - /** - * @property {Description} prev - Description. - * @default - */ - // this.prev = null; - - /** - * @property {Description} last - Description. - * @default - */ - // this.last = this; - - /** - * @property {Description} first - Description. - * @default - */ - // this.first = this; - /** * @property {number} priorityID - The PriorityID controls which Sprite receives an Input event first if they should overlap. * @default @@ -16359,6 +16750,18 @@ Phaser.InputHandler = function (sprite) { */ this.snapY = 0; + /** + * @property {number} snapOffsetX - This defines the top-left X coordinate of the snap grid. + * @default + */ + this.snapOffsetX = 0; + + /** + * @property {number} snapOffsetY - This defines the top-left Y coordinate of the snap grid.. + * @default + */ + this.snapOffsetY = 0; + /** * @property {number} pixelPerfect - Should we use pixel perfect hit detection? Warning: expensive. Only enable if you really need it! * @default @@ -16434,8 +16837,6 @@ Phaser.InputHandler.prototype = { */ start: function (priority, useHandCursor) { - console.log('InputHandler start'); - priority = priority || 0; if (typeof useHandCursor == 'undefined') { useHandCursor = false; } @@ -16851,7 +17252,7 @@ Phaser.InputHandler.prototype = { if (this.useHandCursor && this._pointerData[pointer.id].isDragged === false) { - this.game.stage.canvas.style.cursor = "pointer"; + this.game.canvas.style.cursor = "pointer"; } this.sprite.events.onInputOver.dispatch(this.sprite, pointer); @@ -16872,7 +17273,7 @@ Phaser.InputHandler.prototype = { if (this.useHandCursor && this._pointerData[pointer.id].isDragged === false) { - this.game.stage.canvas.style.cursor = "default"; + this.game.canvas.style.cursor = "default"; } if (this.sprite && this.sprite.events) @@ -16933,15 +17334,18 @@ Phaser.InputHandler.prototype = { // Only release the InputUp signal if the pointer is still over this sprite if (this.checkPointerOver(pointer)) { - //console.log('releasedHandler: ' + Date.now()); - this.sprite.events.onInputUp.dispatch(this.sprite, pointer); + // Release the inputUp signal and provide optional parameter if pointer is still over the sprite or not + this.sprite.events.onInputUp.dispatch(this.sprite, pointer, true); } else { + // Release the inputUp signal and provide optional parameter if pointer is still over the sprite or not + this.sprite.events.onInputUp.dispatch(this.sprite, pointer, false); + // Pointer outside the sprite? Reset the cursor if (this.useHandCursor) { - this.game.stage.canvas.style.cursor = "default"; + this.game.canvas.style.cursor = "default"; } } @@ -16968,30 +17372,61 @@ Phaser.InputHandler.prototype = { return false; } - if (this.allowHorizontalDrag) + if (this.sprite.fixedToCamera) { - this.sprite.x = pointer.x + this._dragPoint.x + this.dragOffset.x; - } + if (this.allowHorizontalDrag) + { + this.sprite.cameraOffset.x = pointer.x + this._dragPoint.x + this.dragOffset.x; + } - if (this.allowVerticalDrag) - { - this.sprite.y = pointer.y + this._dragPoint.y + this.dragOffset.y; - } + if (this.allowVerticalDrag) + { + this.sprite.cameraOffset.y = pointer.y + this._dragPoint.y + this.dragOffset.y; + } - if (this.boundsRect) - { - this.checkBoundsRect(); - } + if (this.boundsRect) + { + this.checkBoundsRect(); + } - if (this.boundsSprite) - { - this.checkBoundsSprite(); - } + if (this.boundsSprite) + { + this.checkBoundsSprite(); + } - if (this.snapOnDrag) + if (this.snapOnDrag) + { + this.sprite.cameraOffset.x = Math.round((this.sprite.cameraOffset.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX); + this.sprite.cameraOffset.y = Math.round((this.sprite.cameraOffset.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY); + } + } + else { - this.sprite.x = Math.round(this.sprite.x / this.snapX) * this.snapX; - this.sprite.y = Math.round(this.sprite.y / this.snapY) * this.snapY; + if (this.allowHorizontalDrag) + { + this.sprite.x = pointer.x + this._dragPoint.x + this.dragOffset.x; + } + + if (this.allowVerticalDrag) + { + this.sprite.y = pointer.y + this._dragPoint.y + this.dragOffset.y; + } + + if (this.boundsRect) + { + this.checkBoundsRect(); + } + + if (this.boundsSprite) + { + this.checkBoundsSprite(); + } + + if (this.snapOnDrag) + { + this.sprite.x = Math.round((this.sprite.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX); + this.sprite.y = Math.round((this.sprite.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY); + } } return true; @@ -17171,14 +17606,29 @@ Phaser.InputHandler.prototype = { this._draggedPointerID = pointer.id; this._pointerData[pointer.id].isDragged = true; - if (this.dragFromCenter) + if (this.sprite.fixedToCamera) { - this.sprite.centerOn(pointer.x, pointer.y); - this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y); + if (this.dragFromCenter) + { + this.sprite.centerOn(pointer.x, pointer.y); + this._dragPoint.setTo(this.sprite.cameraOffset.x - pointer.x, this.sprite.cameraOffset.y - pointer.y); + } + else + { + this._dragPoint.setTo(this.sprite.cameraOffset.x - pointer.x, this.sprite.cameraOffset.y - pointer.y); + } } else { - this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y); + if (this.dragFromCenter) + { + this.sprite.centerOn(pointer.x, pointer.y); + this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y); + } + else + { + this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y); + } } this.updateDrag(pointer); @@ -17205,8 +17655,16 @@ Phaser.InputHandler.prototype = { if (this.snapOnRelease) { - this.sprite.x = Math.round(this.sprite.x / this.snapX) * this.snapX; - this.sprite.y = Math.round(this.sprite.y / this.snapY) * this.snapY; + if (this.sprite.fixedToCamera) + { + this.sprite.cameraOffset.x = Math.round((this.sprite.cameraOffset.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX); + this.sprite.cameraOffset.y = Math.round((this.sprite.cameraOffset.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY); + } + else + { + this.sprite.x = Math.round((this.sprite.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX); + this.sprite.y = Math.round((this.sprite.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY); + } } this.sprite.events.onDragStop.dispatch(this.sprite, pointer); @@ -17243,14 +17701,20 @@ Phaser.InputHandler.prototype = { * @param {number} snapY - The height of the grid cell to snap to. * @param {boolean} [onDrag=true] - If true the sprite will snap to the grid while being dragged. * @param {boolean} [onRelease=false] - If true the sprite will snap to the grid when released. + * @param {number} [snapOffsetX=0] - Used to offset the top-left starting point of the snap grid. + * @param {number} [snapOffsetX=0] - Used to offset the top-left starting point of the snap grid. */ - enableSnap: function (snapX, snapY, onDrag, onRelease) { + enableSnap: function (snapX, snapY, onDrag, onRelease, snappOffsetX, snappOffsetY) { if (typeof onDrag == 'undefined') { onDrag = true; } if (typeof onRelease == 'undefined') { onRelease = false; } + if (typeof snapOffsetX == 'undefined') { snapOffsetX = 0; } + if (typeof snapOffsetY == 'undefined') { snapOffsetY = 0; } this.snapX = snapX; this.snapY = snapY; + this.snapOffsetX = snapOffsetX; + this.snapOffsetY = snapOffsetY; this.snapOnDrag = onDrag; this.snapOnRelease = onRelease; @@ -17273,22 +17737,45 @@ Phaser.InputHandler.prototype = { */ checkBoundsRect: function () { - if (this.sprite.x < this.boundsRect.left) + if (this.sprite.fixedToCamera) { - this.sprite.x = this.boundsRect.x; - } - else if ((this.sprite.x + this.sprite.width) > this.boundsRect.right) - { - this.sprite.x = this.boundsRect.right - this.sprite.width; - } + if (this.sprite.cameraOffset.x < this.boundsRect.left) + { + this.sprite.cameraOffset.x = this.boundsRect.cameraOffset.x; + } + else if ((this.sprite.cameraOffset.x + this.sprite.width) > this.boundsRect.right) + { + this.sprite.cameraOffset.x = this.boundsRect.right - this.sprite.width; + } - if (this.sprite.y < this.boundsRect.top) - { - this.sprite.y = this.boundsRect.top; + if (this.sprite.cameraOffset.y < this.boundsRect.top) + { + this.sprite.cameraOffset.y = this.boundsRect.top; + } + else if ((this.sprite.cameraOffset.y + this.sprite.height) > this.boundsRect.bottom) + { + this.sprite.cameraOffset.y = this.boundsRect.bottom - this.sprite.height; + } } - else if ((this.sprite.y + this.sprite.height) > this.boundsRect.bottom) + else { - this.sprite.y = this.boundsRect.bottom - this.sprite.height; + if (this.sprite.x < this.boundsRect.left) + { + this.sprite.x = this.boundsRect.x; + } + else if ((this.sprite.x + this.sprite.width) > this.boundsRect.right) + { + this.sprite.x = this.boundsRect.right - this.sprite.width; + } + + if (this.sprite.y < this.boundsRect.top) + { + this.sprite.y = this.boundsRect.top; + } + else if ((this.sprite.y + this.sprite.height) > this.boundsRect.bottom) + { + this.sprite.y = this.boundsRect.bottom - this.sprite.height; + } } }, @@ -17299,30 +17786,1381 @@ Phaser.InputHandler.prototype = { */ checkBoundsSprite: function () { - if (this.sprite.x < this.boundsSprite.x) + if (this.sprite.fixedToCamera && this.boundsSprite.fixedToCamera) { - this.sprite.x = this.boundsSprite.x; - } - else if ((this.sprite.x + this.sprite.width) > (this.boundsSprite.x + this.boundsSprite.width)) - { - this.sprite.x = (this.boundsSprite.x + this.boundsSprite.width) - this.sprite.width; - } + if (this.sprite.cameraOffset.x < this.boundsSprite.camerOffset.x) + { + this.sprite.cameraOffset.x = this.boundsSprite.camerOffset.x; + } + else if ((this.sprite.cameraOffset.x + this.sprite.width) > (this.boundsSprite.camerOffset.x + this.boundsSprite.width)) + { + this.sprite.cameraOffset.x = (this.boundsSprite.camerOffset.x + this.boundsSprite.width) - this.sprite.width; + } - if (this.sprite.y < this.boundsSprite.y) - { - this.sprite.y = this.boundsSprite.y; + if (this.sprite.cameraOffset.y < this.boundsSprite.camerOffset.y) + { + this.sprite.cameraOffset.y = this.boundsSprite.camerOffset.y; + } + else if ((this.sprite.cameraOffset.y + this.sprite.height) > (this.boundsSprite.camerOffset.y + this.boundsSprite.height)) + { + this.sprite.cameraOffset.y = (this.boundsSprite.camerOffset.y + this.boundsSprite.height) - this.sprite.height; + } } - else if ((this.sprite.y + this.sprite.height) > (this.boundsSprite.y + this.boundsSprite.height)) + else { - this.sprite.y = (this.boundsSprite.y + this.boundsSprite.height) - this.sprite.height; + if (this.sprite.x < this.boundsSprite.x) + { + this.sprite.x = this.boundsSprite.x; + } + else if ((this.sprite.x + this.sprite.width) > (this.boundsSprite.x + this.boundsSprite.width)) + { + this.sprite.x = (this.boundsSprite.x + this.boundsSprite.width) - this.sprite.width; + } + + if (this.sprite.y < this.boundsSprite.y) + { + this.sprite.y = this.boundsSprite.y; + } + else if ((this.sprite.y + this.sprite.height) > (this.boundsSprite.y + this.boundsSprite.height)) + { + this.sprite.y = (this.boundsSprite.y + this.boundsSprite.height) - this.sprite.height; + } } } }; + +Phaser.InputHandler.prototype.constructor = Phaser.InputHandler; + +/** +* @author @karlmacklin +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* The Gamepad class handles looking after gamepad input for your game. +* Remember to call gamepad.start(); expecting input! +* +* HTML5 GAMEPAD API SUPPORT IS AT AN EXPERIMENTAL STAGE! +* At moment of writing this (end of 2013) only Chrome supports parts of it out of the box. Firefox supports it +* via prefs flags (about:config, search gamepad). The browsers map the same controllers differently. +* This class has constans for Windows 7 Chrome mapping of +* XBOX 360 controller. +* +* @class Phaser.Gamepad +* @constructor +* @param {Phaser.Game} game - A reference to the currently running game. +*/ +Phaser.Gamepad = function (game) { + + /** + * @property {Phaser.Game} game - Local reference to game. + */ + this.game = game; + + /** + * @property {Array} _gamepads - The four Phaser Gamepads. + * @private + */ + this._gamepads = [ + new Phaser.SinglePad(game, this), + new Phaser.SinglePad(game, this), + new Phaser.SinglePad(game, this), + new Phaser.SinglePad(game, this) + ]; + + /** + * @property {Object} _gamepadIndexMap - Maps the browsers gamepad indices to our Phaser Gamepads + * @private + */ + this._gamepadIndexMap = {}; + + /** + * @property {Array} _rawPads - The raw state of the gamepads from the browser + * @private + */ + this._rawPads = []; + + /** + * @property {boolean} _active - Private flag for whether or not the API is polled + * @private + * @default + */ + this._active = false; + + /** + * You can disable all Gamepad Input by setting disabled to true. While true all new input related events will be ignored. + * @property {boolean} disabled - The disabled state of the Gamepad. + * @default + */ + this.disabled = false; + + /** + * Whether or not gamepads are supported in the current browser. Note that as of Dec. 2013 this check is actually not accurate at all due to poor implementation. + * @property {boolean} _gamepadSupportAvailable - Are gamepads supported in this browser or not? + * @private + */ + this._gamepadSupportAvailable = !!navigator.webkitGetGamepads || !!navigator.webkitGamepads || (navigator.userAgent.indexOf('Firefox/') != -1); + + /** + * Used to check for differences between earlier polls and current state of gamepads. + * @property {Array} _prevRawGamepadTypes + * @private + * @default + */ + this._prevRawGamepadTypes = []; + + /** + * Used to check for differences between earlier polls and current state of gamepads. + * @property {Array} _prevTimestamps + * @private + * @default + */ + this._prevTimestamps = []; + + /** + * @property {Object} callbackContext - The context under which the callbacks are run. + */ + this.callbackContext = this; + + /** + * @property {function} onConnectCallback - This callback is invoked every time any gamepad is connected + */ + this.onConnectCallback = null; + + /** + * @property {function} onDisconnectCallback - This callback is invoked every time any gamepad is disconnected + */ + this.onDisconnectCallback = null; + + /** + * @property {function} onDownCallback - This callback is invoked every time any gamepad button is pressed down. + */ + this.onDownCallback = null; + + /** + * @property {function} onUpCallback - This callback is invoked every time any gamepad button is released. + */ + this.onUpCallback = null; + + /** + * @property {function} onAxisCallback - This callback is invoked every time any gamepad axis is changed. + */ + this.onAxisCallback = null; + + /** + * @property {function} onFloatCallback - This callback is invoked every time any gamepad button is changed to a value where value > 0 and value < 1. + */ + this.onFloatCallback = null; + + /** + * @property {function} _ongamepadconnected - Private callback for Firefox gamepad connection handling + * @private + */ + this._ongamepadconnected = null; + + /** + * @property {function} _gamepaddisconnected - Private callback for Firefox gamepad connection handling + * @private + */ + this._gamepaddisconnected = null; +}; + +Phaser.Gamepad.prototype = { + + /** + * Add callbacks to the main Gamepad handler to handle connect/disconnect/button down/button up/axis change/float value buttons + * @method Phaser.Gamepad#addCallbacks + * @param {Object} context - The context under which the callbacks are run. + * @param {Object} callbacks - Object that takes six different callback methods: + * onConnectCallback, onDisconnectCallback, onDownCallback, onUpCallback, onAxisCallback, onFloatCallback + */ + addCallbacks: function (context, callbacks) { + + if (typeof callbacks !== 'undefined') + { + this.onConnectCallback = (typeof callbacks.onConnect === 'function') ? callbacks.onConnect : this.onConnectCallback; + this.onDisconnectCallback = (typeof callbacks.onDisconnect === 'function') ? callbacks.onDisconnect : this.onDisconnectCallback; + this.onDownCallback = (typeof callbacks.onDown === 'function') ? callbacks.onDown : this.onDownCallback; + this.onUpCallback = (typeof callbacks.onUp === 'function') ? callbacks.onUp : this.onUpCallback; + this.onAxisCallback = (typeof callbacks.onAxis === 'function') ? callbacks.onAxis : this.onAxisCallback; + this.onFloatCallback = (typeof callbacks.onFloat === 'function') ? callbacks.onFloat : this.onFloatCallback; + } + + }, + + /** + * Starts the Gamepad event handling. + * This MUST be called manually before Phaser will start polling the Gamepad API. + * + * @method Phaser.Gamepad#start + */ + start: function () { + + this._active = true; + var _this = this; + + this._ongamepadconnected = function(event) { + var newPad = event.gamepad; + _this._rawPads.push(newPad); + _this._gamepads[newPad.index].connect(newPad); + }; + + window.addEventListener('gamepadconnected', this._ongamepadconnected, false); + + this._ongamepaddisconnected = function(event) { + + var removedPad = event.gamepad; + + for (var i in _this._rawPads) + { + if (_this._rawPads[i].index === removedPad.index) + { + _this._rawPads.splice(i,1); + } + } + _this._gamepads[removedPad.index].disconnect(); + }; + + window.addEventListener('gamepaddisconnected', this._ongamepaddisconnected, false); + + }, + + /** + * Main gamepad update loop. Should not be called manually. + * @method Phaser.Gamepad#update + * @private + */ + update: function () { + + this._pollGamepads(); + + for (var i = 0; i < this._gamepads.length; i++) + { + if (this._gamepads[i]._connected) + { + this._gamepads[i].pollStatus(); + } + } + + }, + + /** + * Updating connected gamepads (for Google Chrome). + * Should not be called manually. + * @method Phaser.Gamepad#_pollGamepads + * @private + */ + _pollGamepads: function () { + + var rawGamepads = (navigator.webkitGetGamepads && navigator.webkitGetGamepads()) || navigator.webkitGamepads; + + if (rawGamepads) + { + this._rawPads = []; + + var gamepadsChanged = false; + + for (var i = 0; i < rawGamepads.length; i++) + { + if (typeof rawGamepads[i] !== this._prevRawGamepadTypes[i]) + { + gamepadsChanged = true; + this._prevRawGamepadTypes[i] = typeof rawGamepads[i]; + } + + if (rawGamepads[i]) + { + this._rawPads.push(rawGamepads[i]); + } + + // Support max 4 pads at the moment + if (i === 3) + { + break; + } + } + + if (gamepadsChanged) + { + var validConnections = { rawIndices: {}, padIndices: {} }; + var singlePad; + + for (var j = 0; j < this._gamepads.length; j++) + { + singlePad = this._gamepads[j]; + + if (singlePad.connected) + { + for (var k = 0; k < this._rawPads.length; k++) + { + if (this._rawPads[k].index === singlePad.index) + { + validConnections.rawIndices[singlePad.index] = true; + validConnections.padIndices[j] = true; + } + } + } + } + + for (var l = 0; l < this._gamepads.length; l++) + { + singlePad = this._gamepads[l]; + + if (validConnections.padIndices[l]) + { + continue; + } + + if (this._rawPads.length < 1) + { + singlePad.disconnect(); + } + + for (var m = 0; m < this._rawPads.length; m++) + { + if (validConnections.padIndices[l]) + { + break; + } + + var rawPad = this._rawPads[m]; + + if (rawPad) + { + if (validConnections.rawIndices[rawPad.index]) + { + singlePad.disconnect(); + continue; + } + else + { + singlePad.connect(rawPad); + validConnections.rawIndices[rawPad.index] = true; + validConnections.padIndices[l] = true; + } + } + else + { + singlePad.disconnect(); + } + } + } + } + } + }, + + /** + * Sets the deadZone variable for all four gamepads + * @method Phaser.Gamepad#setDeadZones + */ + setDeadZones: function (value) { + + for (var i = 0; i < this._gamepads.length; i++) + { + this._gamepads[i].deadZone = value; + } + + }, + + /** + * Stops the Gamepad event handling. + * + * @method Phaser.Gamepad#stop + */ + stop: function () { + + this._active = false; + + window.removeEventListener('gamepadconnected', this._ongamepadconnected); + window.removeEventListener('gamepaddisconnected', this._ongamepaddisconnected); + + }, + + /** + * Reset all buttons/axes of all gamepads + * @method Phaser.Gamepad#reset + */ + reset: function () { + + this.update(); + + for (var i = 0; i < this._gamepads.length; i++) + { + this._gamepads[i].reset(); + } + + }, + + /** + * Returns the "just pressed" state of a button from ANY gamepad connected. Just pressed is considered true if the button was pressed down within the duration given (default 250ms). + * @method Phaser.Gamepad#justPressed + * @param {number} buttonCode - The buttonCode of the button to check for. + * @param {number} [duration=250] - The duration below which the button is considered as being just pressed. + * @return {boolean} True if the button is just pressed otherwise false. + */ + justPressed: function (buttonCode, duration) { + + for (var i = 0; i < this._gamepads.length; i++) + { + if (this._gamepads[i].justPressed(buttonCode, duration) === true) + { + return true; + } + } + + return false; + + }, + + /** + * Returns the "just released" state of a button from ANY gamepad connected. Just released is considered as being true if the button was released within the duration given (default 250ms). + * @method Phaser.Gamepad#justPressed + * @param {number} buttonCode - The buttonCode of the button to check for. + * @param {number} [duration=250] - The duration below which the button is considered as being just released. + * @return {boolean} True if the button is just released otherwise false. + */ + justReleased: function (buttonCode, duration) { + + for (var i = 0; i < this._gamepads.length; i++) + { + if (this._gamepads[i].justReleased(buttonCode, duration) === true) + { + return true; + } + } + + return false; + + }, + + /** + * Returns true if the button is currently pressed down, on ANY gamepad. + * @method Phaser.Gamepad#isDown + * @param {number} buttonCode - The buttonCode of the button to check for. + * @return {boolean} True if a button is currently down. + */ + isDown: function (buttonCode) { + + for (var i = 0; i < this._gamepads.length; i++) + { + if (this._gamepads[i].isDown(buttonCode) === true) + { + return true; + } + } + + return false; + } + +}; + +Phaser.Gamepad.prototype.constructor = Phaser.Gamepad; + +/** +* If the gamepad input is active or not - if not active it should not be updated from Input.js +* @name Phaser.Gamepad#active +* @property {boolean} active - If the gamepad input is active or not. +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "active", { + + get: function () { + return this._active; + } + +}); + +/** +* Whether or not gamepads are supported in current browser. +* @name Phaser.Gamepad#supported +* @property {boolean} supported - Whether or not gamepads are supported in current browser. +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "supported", { + + get: function () { + return this._gamepadSupportAvailable; + } + +}); + +/** +* How many live gamepads are currently connected. +* @name Phaser.Gamepad#padsConnected +* @property {boolean} padsConnected - How many live gamepads are currently connected. +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "padsConnected", { + + get: function () { + return this._rawPads.length; + } + +}); + +/** +* Gamepad #1 +* @name Phaser.Gamepad#pad1 +* @property {boolean} pad1 - Gamepad #1; +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "pad1", { + + get: function () { + return this._gamepads[0]; + } + +}); + +/** +* Gamepad #2 +* @name Phaser.Gamepad#pad2 +* @property {boolean} pad2 - Gamepad #2 +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "pad2", { + + get: function () { + return this._gamepads[1]; + } + +}); + +/** +* Gamepad #3 +* @name Phaser.Gamepad#pad3 +* @property {boolean} pad3 - Gamepad #3 +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "pad3", { + + get: function () { + return this._gamepads[2]; + } + +}); + +/** +* Gamepad #4 +* @name Phaser.Gamepad#pad4 +* @property {boolean} pad4 - Gamepad #4 +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "pad4", { + + get: function () { + return this._gamepads[3]; + } + +}); + +Phaser.Gamepad.BUTTON_0 = 0; +Phaser.Gamepad.BUTTON_1 = 1; +Phaser.Gamepad.BUTTON_2 = 2; +Phaser.Gamepad.BUTTON_3 = 3; +Phaser.Gamepad.BUTTON_4 = 4; +Phaser.Gamepad.BUTTON_5 = 5; +Phaser.Gamepad.BUTTON_6 = 6; +Phaser.Gamepad.BUTTON_7 = 7; +Phaser.Gamepad.BUTTON_8 = 8; +Phaser.Gamepad.BUTTON_9 = 9; +Phaser.Gamepad.BUTTON_10 = 10; +Phaser.Gamepad.BUTTON_11 = 11; +Phaser.Gamepad.BUTTON_12 = 12; +Phaser.Gamepad.BUTTON_13 = 13; +Phaser.Gamepad.BUTTON_14 = 14; +Phaser.Gamepad.BUTTON_15 = 15; + +Phaser.Gamepad.AXIS_0 = 0; +Phaser.Gamepad.AXIS_1 = 1; +Phaser.Gamepad.AXIS_2 = 2; +Phaser.Gamepad.AXIS_3 = 3; +Phaser.Gamepad.AXIS_4 = 4; +Phaser.Gamepad.AXIS_5 = 5; +Phaser.Gamepad.AXIS_6 = 6; +Phaser.Gamepad.AXIS_7 = 7; +Phaser.Gamepad.AXIS_8 = 8; +Phaser.Gamepad.AXIS_9 = 9; + +// Below mapping applies to XBOX 360 Wired and Wireless controller on Google Chrome (tested on Windows 7). +// - Firefox uses different map! Separate amount of buttons and axes. DPAD = axis and not a button. +// In other words - discrepancies when using gamepads. + +Phaser.Gamepad.XBOX360_A = 0; +Phaser.Gamepad.XBOX360_B = 1; +Phaser.Gamepad.XBOX360_X = 2; +Phaser.Gamepad.XBOX360_Y = 3; +Phaser.Gamepad.XBOX360_LEFT_BUMPER = 4; +Phaser.Gamepad.XBOX360_RIGHT_BUMPER = 5; +Phaser.Gamepad.XBOX360_LEFT_TRIGGER = 6; +Phaser.Gamepad.XBOX360_RIGHT_TRIGGER = 7; +Phaser.Gamepad.XBOX360_BACK = 8; +Phaser.Gamepad.XBOX360_START = 9; +Phaser.Gamepad.XBOX360_STICK_LEFT_BUTTON = 10; +Phaser.Gamepad.XBOX360_STICK_RIGHT_BUTTON = 11; + +Phaser.Gamepad.XBOX360_DPAD_LEFT = 14; +Phaser.Gamepad.XBOX360_DPAD_RIGHT = 15; +Phaser.Gamepad.XBOX360_DPAD_UP = 12; +Phaser.Gamepad.XBOX360_DPAD_DOWN = 13; + +Phaser.Gamepad.XBOX360_STICK_LEFT_X = 0; +Phaser.Gamepad.XBOX360_STICK_LEFT_Y = 1; +Phaser.Gamepad.XBOX360_STICK_RIGHT_X = 2; +Phaser.Gamepad.XBOX360_STICK_RIGHT_Y = 3; + +/** +* @author @karlmacklin +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* @class Phaser.SinglePad +* @classdesc A single Phaser Gamepad +* @constructor +* @param {Phaser.Game} game - Current game instance. +* @param {Object} padParent - The parent Phaser.Gamepad object (all gamepads reside under this) +*/ +Phaser.SinglePad = function (game, padParent) { + + /** + * @property {Phaser.Game} game - Local reference to game. + */ + this.game = game; + + /** + * @property {Phaser.Gamepad} padParent - Main Phaser Gamepad object + */ + this._padParent = padParent; + + /** + * @property {number} index - The gamepad index as per browsers data + * @default + */ + this._index = null; + + /** + * @property {Object} _rawPad - The 'raw' gamepad data. + * @private + */ + this._rawPad = null; + + /** + * @property {boolean} _connected - Is this pad connected or not. + * @private + */ + this._connected = false; + + /** + * @property {number} _prevTimestamp - Used to check for differences between earlier polls and current state of gamepads. + * @private + */ + this._prevTimestamp = null; + + /** + * @property {Array} _rawButtons - The 'raw' button state. + * @private + */ + this._rawButtons = []; + + /** + * @property {Array} _buttons - Current Phaser state of the buttons. + * @private + */ + this._buttons = []; + + /** + * @property {Array} _axes - Current axes state. + * @private + */ + this._axes = []; + + /** + * @property {Array} _hotkeys - Hotkey buttons. + * @private + */ + this._hotkeys = []; + + /** + * @property {Object} callbackContext - The context under which the callbacks are run. + */ + this.callbackContext = this; + + /** + * @property {function} onConnectCallback - This callback is invoked every time this gamepad is connected + */ + this.onConnectCallback = null; + + /** + * @property {function} onDisconnectCallback - This callback is invoked every time this gamepad is disconnected + */ + this.onDisconnectCallback = null; + + /** + * @property {function} onDownCallback - This callback is invoked every time a button is pressed down. + */ + this.onDownCallback = null; + + /** + * @property {function} onUpCallback - This callback is invoked every time a gamepad button is released. + */ + this.onUpCallback = null; + + /** + * @property {function} onAxisCallback - This callback is invoked every time an axis is changed. + */ + this.onAxisCallback = null; + + /** + * @property {function} onFloatCallback - This callback is invoked every time a button is changed to a value where value > 0 and value < 1. + */ + this.onFloatCallback = null; + + /** + * @property {number} deadZone - Dead zone for axis feedback - within this value you won't trigger updates. + */ + this.deadZone = 0.26; + +}; + +Phaser.SinglePad.prototype = { + + /** + * Add callbacks to the this Gamepad to handle connect/disconnect/button down/button up/axis change/float value buttons + * @method Phaser.Gamepad#addCallbacks + * @param {Object} context - The context under which the callbacks are run. + * @param {Object} callbacks - Object that takes six different callbak methods: + * onConnectCallback, onDisconnectCallback, onDownCallback, onUpCallback, onAxisCallback, onFloatCallback + */ + addCallbacks: function (context, callbacks) { + + if (typeof callbacks !== 'undefined') + { + this.onConnectCallback = (typeof callbacks.onConnect === 'function') ? callbacks.onConnect : this.onConnectCallback; + this.onDisconnectCallback = (typeof callbacks.onDisconnect === 'function') ? callbacks.onDisconnect : this.onDisconnectCallback; + this.onDownCallback = (typeof callbacks.onDown === 'function') ? callbacks.onDown : this.onDownCallback; + this.onUpCallback = (typeof callbacks.onUp === 'function') ? callbacks.onUp : this.onUpCallback; + this.onAxisCallback = (typeof callbacks.onAxis === 'function') ? callbacks.onAxis : this.onAxisCallback; + this.onFloatCallback = (typeof callbacks.onFloat === 'function') ? callbacks.onFloat : this.onFloatCallback; + } + + }, + + /** + * If you need more fine-grained control over a Key you can create a new Phaser.Key object via this method. + * The Key object can then be polled, have events attached to it, etc. + * + * @method Phaser.SinglePad#addButton + * @param {number} buttonCode - The buttonCode of the button, i.e. Phaser.Gamepad.BUTTON_0 or Phaser.Gamepad.BUTTON_1 + * @return {Phaser.GamepadButton} The GamepadButton object which you can store locally and reference directly. + */ + addButton: function (buttonCode) { + + this._hotkeys[buttonCode] = new Phaser.GamepadButton(this.game, buttonCode); + return this._hotkeys[buttonCode]; + + }, + + /** + * Main update function, should be called by Phaser.Gamepad + * @method Phaser.SinglePad#pollStatus + */ + pollStatus: function () { + + if (this._rawPad.timestamp && (this._rawPad.timestamp == this._prevTimestamp)) + { + return; + } + + for (var i = 0; i < this._rawPad.buttons.length; i += 1) + { + var buttonValue = this._rawPad.buttons[i]; + + if (this._rawButtons[i] !== buttonValue) + { + if (buttonValue === 1) + { + this.processButtonDown(i, buttonValue); + } + else if (buttonValue === 0) + { + this.processButtonUp(i, buttonValue); + } + else + { + this.processButtonFloat(i, buttonValue); + } + + this._rawButtons[i] = buttonValue; + } + } + + var axes = this._rawPad.axes; + + for (var j = 0; j < axes.length; j += 1) + { + var axis = axes[j]; + + if (axis > 0 && axis > this.deadZone || axis < 0 && axis < -this.deadZone) + { + this.processAxisChange({axis: j, value: axis}); + } + else + { + this.processAxisChange({axis: j, value: 0}); + } + } + + this._prevTimestamp = this._rawPad.timestamp; + + }, + + /** + * Gamepad connect function, should be called by Phaser.Gamepad + * @param {Object} rawPad - The raw gamepad object + * @method Phaser.SinglePad#connect + */ + connect: function (rawPad) { + + var triggerCallback = !this._connected; + + this._index = rawPad.index; + this._connected = true; + this._rawPad = rawPad; + this._rawButtons = rawPad.buttons; + this._axes = rawPad.axes; + + if (triggerCallback && this._padParent.onConnectCallback) + { + this._padParent.onConnectCallback.call(this._padParent.callbackContext, this._index); + } + + if (triggerCallback && this.onConnectCallback) + { + this.onConnectCallback.call(this.callbackContext); + } + + }, + + /** + * Gamepad disconnect function, should be called by Phaser.Gamepad + * @method Phaser.SinglePad#disconnect + */ + disconnect: function () { + + var triggerCallback = this._connected; + this._connected = false; + this._rawPad = undefined; + this._rawButtons = []; + this._buttons = []; + var disconnectingIndex = this._index; + this._index = null; + + if (triggerCallback && this._padParent.onDisconnectCallback) + { + this._padParent.onDisconnectCallback.call(this._padParent.callbackContext, disconnectingIndex); + } + + if (triggerCallback && this.onDisconnectCallback) + { + this.onDisconnectCallback.call(this.callbackContext); + } + + }, + + /** + * Handles changes in axis + * @param {Object} axisState - State of the relevant axis + * @method Phaser.SinglePad#processAxisChange + */ + processAxisChange: function (axisState) { + + if (this.game.input.disabled || this.game.input.gamepad.disabled) + { + return; + } + + if (this._axes[axisState.axis] === axisState.value) + { + return; + } + + this._axes[axisState.axis] = axisState.value; + + if (this._padParent.onAxisCallback) + { + this._padParent.onAxisCallback.call(this._padParent.callbackContext, axisState, this._index); + } + + if (this.onAxisCallback) + { + this.onAxisCallback.call(this.callbackContext, axisState); + } + + }, + + /** + * Handles button down press + * @param {number} buttonCode - Which buttonCode of this button + * @param {Object} value - Button value + * @method Phaser.SinglePad#processButtonDown + */ + processButtonDown: function (buttonCode, value) { + + if (this.game.input.disabled || this.game.input.gamepad.disabled) + { + return; + } + + if (this._padParent.onDownCallback) + { + this._padParent.onDownCallback.call(this._padParent.callbackContext, buttonCode, value, this._index); + } + + if (this.onDownCallback) + { + this.onDownCallback.call(this.callbackContext, buttonCode, value); + } + + if (this._buttons[buttonCode] && this._buttons[buttonCode].isDown) + { + // Key already down and still down, so update + this._buttons[buttonCode].duration = this.game.time.now - this._buttons[buttonCode].timeDown; + } + else + { + if (!this._buttons[buttonCode]) + { + // Not used this button before, so register it + this._buttons[buttonCode] = { + isDown: true, + timeDown: this.game.time.now, + timeUp: 0, + duration: 0, + value: value + }; + } + else + { + // Button used before but freshly down + this._buttons[buttonCode].isDown = true; + this._buttons[buttonCode].timeDown = this.game.time.now; + this._buttons[buttonCode].duration = 0; + this._buttons[buttonCode].value = value; + } + } + + if (this._hotkeys[buttonCode]) + { + this._hotkeys[buttonCode].processButtonDown(value); + } + + }, + + /** + * Handles button release + * @param {number} buttonCode - Which buttonCode of this button + * @param {Object} value - Button value + * @method Phaser.SinglePad#processButtonUp + */ + processButtonUp: function (buttonCode, value) { + + if (this.game.input.disabled || this.game.input.gamepad.disabled) + { + return; + } + + if (this._padParent.onUpCallback) + { + this._padParent.onUpCallback.call(this._padParent.callbackContext, buttonCode, value, this._index); + } + + if (this.onUpCallback) + { + this.onUpCallback.call(this.callbackContext, buttonCode, value); + } + + if (this._hotkeys[buttonCode]) + { + this._hotkeys[buttonCode].processButtonUp(value); + } + + if (this._buttons[buttonCode]) + { + this._buttons[buttonCode].isDown = false; + this._buttons[buttonCode].timeUp = this.game.time.now; + this._buttons[buttonCode].value = value; + } + else + { + // Not used this button before, so register it + this._buttons[buttonCode] = { + isDown: false, + timeDown: this.game.time.now, + timeUp: this.game.time.now, + duration: 0, + value: value + }; + } + + }, + + /** + * Handles buttons with floating values (like analog buttons that acts almost like an axis but still registers like a button) + * @param {number} buttonCode - Which buttonCode of this button + * @param {Object} value - Button value (will range somewhere between 0 and 1, but not specifically 0 or 1. + * @method Phaser.SinglePad#processButtonFloat + */ + processButtonFloat: function (buttonCode, value) { + + if (this.game.input.disabled || this.game.input.gamepad.disabled) + { + return; + } + + if (this._padParent.onFloatCallback) + { + this._padParent.onFloatCallback.call(this._padParent.callbackContext, buttonCode, value, this._index); + } + + if (this.onFloatCallback) + { + this.onFloatCallback.call(this.callbackContext, buttonCode, value); + } + + if (!this._buttons[buttonCode]) + { + // Not used this button before, so register it + this._buttons[buttonCode] = { value: value }; + } + else + { + // Button used before but freshly down + this._buttons[buttonCode].value = value; + } + + if (this._hotkeys[buttonCode]) + { + this._hotkeys[buttonCode].processButtonFloat(value); + } + + }, + + /** + * Returns value of requested axis + * @method Phaser.SinglePad#isDown + * @param {number} axisCode - The index of the axis to check + * @return {number} Axis value if available otherwise false + */ + axis: function (axisCode) { + + if (this._axes[axisCode]) + { + return this._axes[axisCode]; + } + + return false; + + }, + + /** + * Returns true if the button is currently pressed down. + * @method Phaser.SinglePad#isDown + * @param {number} buttonCode - The buttonCode of the key to check. + * @return {boolean} True if the key is currently down. + */ + isDown: function (buttonCode) { + + if (this._buttons[buttonCode]) + { + return this._buttons[buttonCode].isDown; + } + + return false; + + }, + + /** + * Returns the "just released" state of a button from this gamepad. Just released is considered as being true if the button was released within the duration given (default 250ms). + * @method Phaser.SinglePad#justPressed + * @param {number} buttonCode - The buttonCode of the button to check for. + * @param {number} [duration=250] - The duration below which the button is considered as being just released. + * @return {boolean} True if the button is just released otherwise false. + */ + justReleased: function (buttonCode, duration) { + + if (typeof duration === "undefined") { duration = 250; } + + return (this._buttons[buttonCode] && this._buttons[buttonCode].isDown === false && (this.game.time.now - this._buttons[buttonCode].timeUp < duration)); + + }, + + /** + * Returns the "just pressed" state of a button from this gamepad. Just pressed is considered true if the button was pressed down within the duration given (default 250ms). + * @method Phaser.SinglePad#justPressed + * @param {number} buttonCode - The buttonCode of the button to check for. + * @param {number} [duration=250] - The duration below which the button is considered as being just pressed. + * @return {boolean} True if the button is just pressed otherwise false. + */ + justPressed: function (buttonCode, duration) { + + if (typeof duration === "undefined") { duration = 250; } + + return (this._buttons[buttonCode] && this._buttons[buttonCode].isDown && this._buttons[buttonCode].duration < duration); + + }, + + /** + * Returns the value of a gamepad button. Intended mainly for cases when you have floating button values, for example + * analog trigger buttons on the XBOX 360 controller + * @method Phaser.SinglePad#buttonValue + * @param {number} buttonCode - The buttonCode of the button to check. + * @return {boolean} Button value if available otherwise false. + */ + buttonValue: function (buttonCode) { + + if (this._buttons[buttonCode]) + { + return this._buttons[buttonCode].value; + } + + return false; + + }, + + /** + * Reset all buttons/axes of this gamepad + * @method Phaser.SinglePad#reset + */ + reset: function () { + + for (var i = 0; i < this._buttons.length; i++) + { + this._buttons[i] = 0; + } + + for (var j = 0; j < this._axes.length; j++) + { + this._axes[j] = 0; + } + + } + +}; + +Phaser.SinglePad.prototype.constructor = Phaser.SinglePad; + +/** + * Whether or not this particular gamepad is connected or not. + * @name Phaser.SinglePad#connected + * @property {boolean} connected - Whether or not this particular gamepad is connected or not. + * @readonly + */ +Object.defineProperty(Phaser.SinglePad.prototype, "connected", { + + get: function () { + return this._connected; + } + +}); + +/** + * Gamepad index as per browser data + * @name Phaser.SinglePad#index + * @property {number} index - The gamepad index, used to identify specific gamepads in the browser + * @readonly + */ +Object.defineProperty(Phaser.SinglePad.prototype, "index", { + + get: function () { + return this._index; + } + +}); + +/** +* @author @karlmacklin +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* @class Phaser.GamepadButton +* @classdesc If you need more fine-grained control over the handling of specific buttons you can create and use Phaser.GamepadButton objects. +* @constructor +* @param {Phaser.Game} game - Current game instance. +* @param {number} buttoncode - The button code this GamepadButton is responsible for. +*/ +Phaser.GamepadButton = function (game, buttoncode) { + + /** + * @property {Phaser.Game} game - A reference to the currently running game. + */ + this.game = game; + + /** + * @property {boolean} isDown - The "down" state of the button. + * @default + */ + this.isDown = false; + + /** + * @property {boolean} isUp - The "up" state of the button. + * @default + */ + this.isUp = false; + + /** + * @property {number} timeDown - The timestamp when the button was last pressed down. + * @default + */ + this.timeDown = 0; + + /** + * If the button is down this value holds the duration of that button press and is constantly updated. + * If the button is up it holds the duration of the previous down session. + * @property {number} duration - The number of milliseconds this button has been held down for. + * @default + */ + this.duration = 0; + + /** + * @property {number} timeUp - The timestamp when the button was last released. + * @default + */ + this.timeUp = 0; + + /** + * @property {number} repeats - If a button is held down this holds down the number of times the button has 'repeated'. + * @default + */ + this.repeats = 0; + + /** + * @property {number} value - Button value. Mainly useful for checking analog buttons (like shoulder triggers) + * @default + */ + this.value = 0; + + /** + * @property {number} buttonCode - The buttoncode of this button. + */ + this.buttonCode = buttoncode; + + /** + * @property {Phaser.Signal} onDown - This Signal is dispatched every time this GamepadButton is pressed down. It is only dispatched once (until the button is released again). + */ + this.onDown = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onUp - This Signal is dispatched every time this GamepadButton is pressed down. It is only dispatched once (until the button is released again). + */ + this.onUp = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onFloat - This Signal is dispatched every time this GamepadButton changes floating value (between (but not exactly) 0 and 1) + */ + this.onFloat = new Phaser.Signal(); + +}; + +Phaser.GamepadButton.prototype = { + + /** + * Called automatically by Phaser.SinglePad. + * @method Phaser.GamepadButton#processButtonDown + * @param {Object} value - Button value + * @protected + */ + processButtonDown: function (value) { + + if (this.isDown) + { + this.duration = this.game.time.now - this.timeDown; + this.repeats++; + } + else + { + this.isDown = true; + this.isUp = false; + this.timeDown = this.game.time.now; + this.duration = 0; + this.repeats = 0; + this.value = value; + + this.onDown.dispatch(this, value); + } + + }, + + /** + * Called automatically by Phaser.SinglePad. + * @method Phaser.GamepadButton#processButtonUp + * @param {Object} value - Button value + * @protected + */ + processButtonUp: function (value) { + + this.isDown = false; + this.isUp = true; + this.timeUp = this.game.time.now; + this.value = value; + + this.onUp.dispatch(this, value); + + }, + + /** + * Called automatically by Phaser.Gamepad. + * @method Phaser.GamepadButton#processButtonFloat + * @param {Object} value - Button value + * @protected + */ + processButtonFloat: function (value) { + + this.value = value; + this.onFloat.dispatch(this, value); + + }, + + /** + * Returns the "just pressed" state of this button. Just pressed is considered true if the button was pressed down within the duration given (default 250ms). + * @method Phaser.GamepadButton#justPressed + * @param {number} [duration=250] - The duration below which the button is considered as being just pressed. + * @return {boolean} True if the button is just pressed otherwise false. + */ + justPressed: function (duration) { + + if (typeof duration === "undefined") { duration = 250; } + + return (this.isDown && this.duration < duration); + + }, + + /** + * Returns the "just released" state of this button. Just released is considered as being true if the button was released within the duration given (default 250ms). + * @method Phaser.GamepadButton#justPressed + * @param {number} [duration=250] - The duration below which the button is considered as being just released. + * @return {boolean} True if the button is just pressed otherwise false. + */ + justReleased: function (duration) { + + if (typeof duration === "undefined") { duration = 250; } + + return (this.isDown === false && (this.game.time.now - this.timeUp < duration)); + } + +}; + +Phaser.GamepadButton.prototype.constructor = Phaser.GamepadButton; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -17346,6 +19184,7 @@ Phaser.InputHandler.prototype = { Phaser.Events = function (sprite) { this.parent = sprite; + this.onAddedToGroup = new Phaser.Signal(); this.onRemovedFromGroup = new Phaser.Signal(); this.onKilled = new Phaser.Signal(); @@ -17363,6 +19202,9 @@ Phaser.Events = function (sprite) { this.onAnimationComplete = null; this.onAnimationLoop = null; + this.onBeginContact = null; + this.onEndContact = null; + }; Phaser.Events.prototype = { @@ -17396,9 +19238,12 @@ Phaser.Events.prototype = { } }; + +Phaser.Events.prototype.constructor = Phaser.Events; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -17445,15 +19290,19 @@ Phaser.GameObjectFactory.prototype = { * @param {number} y - Y position of the new sprite. * @param {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture. * @param {string|number} [frame] - If the sprite uses an image from a texture atlas or sprite sheet you can pass the frame here. Either a number for a frame ID or a string for a frame name. + * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. * @returns {Phaser.Sprite} the newly created sprite object. */ - sprite: function (x, y, key, frame) { + sprite: function (x, y, key, frame, group) { - return this.world.create(x, y, key, frame); + if (typeof group === 'undefined') { group = this.world; } + + return group.create(x, y, key, frame); }, /** + * DEPRECATED - will be removed in Phaser 1.2 * Create a new Sprite with specific position and sprite sheet key that will automatically be added as a child of the given parent. * * @method Phaser.GameObjectFactory#child @@ -17487,8 +19336,8 @@ Phaser.GameObjectFactory.prototype = { * A Group is a container for display objects that allows for fast pooling, recycling and collision checks. * * @method Phaser.GameObjectFactory#group - * @param {*} parent - The parent Group or DisplayObjectContainer that will hold this group, if any. - * @param {string} [name=group] - A name for this Group. Not used internally but useful for debugging. + * @param {any} parent - The parent Group or DisplayObjectContainer that will hold this group, if any. + * @param {string} [name='group'] - A name for this Group. Not used internally but useful for debugging. * @return {Phaser.Group} The newly created group. */ group: function (parent, name) { @@ -17498,7 +19347,7 @@ Phaser.GameObjectFactory.prototype = { }, /** - * Creates a new instance of the Sound class. + * Creates a new Sound object. * * @method Phaser.GameObjectFactory#audio * @param {string} key - The Game.cache key of the sound that this object will use. @@ -17514,7 +19363,23 @@ Phaser.GameObjectFactory.prototype = { }, /** - * Creates a new TileSprite. + * Creates a new Sound object. + * + * @method Phaser.GameObjectFactory#sound + * @param {string} key - The Game.cache key of the sound that this object will use. + * @param {number} [volume=1] - The volume at which the sound will be played. + * @param {boolean} [loop=false] - Whether or not the sound will loop. + * @param {boolean} [connect=true] - Controls if the created Sound object will connect to the master gainNode of the SoundManager when running under WebAudio. + * @return {Phaser.Sound} The newly created text object. + */ + sound: function (key, volume, loop, connect) { + + return this.game.sound.add(key, volume, loop, connect); + + }, + + /** + * Creates a new TileSprite object. * * @method Phaser.GameObjectFactory#tileSprite * @param {number} x - X position of the new tileSprite. @@ -17522,33 +19387,38 @@ Phaser.GameObjectFactory.prototype = { * @param {number} width - the width of the tilesprite. * @param {number} height - the height of the tilesprite. * @param {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture. - * @param {string|number} frame - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index. + * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. * @return {Phaser.TileSprite} The newly created tileSprite object. */ - tileSprite: function (x, y, width, height, key, frame) { + tileSprite: function (x, y, width, height, key, group) { - return this.world.add(new Phaser.TileSprite(this.game, x, y, width, height, key, frame)); + if (typeof group === 'undefined') { group = this.world; } + + return group.add(new Phaser.TileSprite(this.game, x, y, width, height, key)); }, /** - * Creates a new Text. + * Creates a new Text object. * * @method Phaser.GameObjectFactory#text * @param {number} x - X position of the new text object. * @param {number} y - Y position of the new text object. * @param {string} text - The actual text that will be written. * @param {object} style - The style object containing style attributes like font, font size , etc. + * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. * @return {Phaser.Text} The newly created text object. */ - text: function (x, y, text, style) { + text: function (x, y, text, style, group) { - return this.world.add(new Phaser.Text(this.game, x, y, text, style)); + if (typeof group === 'undefined') { group = this.world; } + + return group.add(new Phaser.Text(this.game, x, y, text, style)); }, /** - * Creates a new Button object. + * Creates a new Button object. * * @method Phaser.GameObjectFactory#button * @param {number} [x] X position of the new button object. @@ -17559,25 +19429,32 @@ Phaser.GameObjectFactory.prototype = { * @param {string|number} [overFrame] This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name. * @param {string|number} [outFrame] This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name. * @param {string|number} [downFrame] This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name. + * @param {string|number} [upFrame] This is the frame or frameName that will be set when this button is in an up state. Give either a number to use a frame ID or a string for a frame name. + * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. * @return {Phaser.Button} The newly created button object. */ - button: function (x, y, key, callback, callbackContext, overFrame, outFrame, downFrame) { + button: function (x, y, key, callback, callbackContext, overFrame, outFrame, downFrame, upFrame, group) { - return this.world.add(new Phaser.Button(this.game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame)); + if (typeof group === 'undefined') { group = this.world; } + + return group.add(new Phaser.Button(this.game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame, upFrame)); }, /** - * Creates a new Graphics object. + * Creates a new Graphics object. * * @method Phaser.GameObjectFactory#graphics * @param {number} x - X position of the new graphics object. * @param {number} y - Y position of the new graphics object. + * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. * @return {Phaser.Graphics} The newly created graphics object. */ - graphics: function (x, y) { + graphics: function (x, y, group) { - return this.world.add(new Phaser.Graphics(this.game, x, y)); + if (typeof group === 'undefined') { group = this.world; } + + return group.add(new Phaser.Graphics(this.game, x, y)); }, @@ -17599,16 +19476,19 @@ Phaser.GameObjectFactory.prototype = { }, /** - * * Create a new BitmapText. + * * Create a new BitmapText object. * * @method Phaser.GameObjectFactory#bitmapText * @param {number} x - X position of the new bitmapText object. * @param {number} y - Y position of the new bitmapText object. * @param {string} text - The actual text that will be written. * @param {object} style - The style object containing style attributes like font, font size , etc. + * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. * @return {Phaser.BitmapText} The newly created bitmapText object. */ - bitmapText: function (x, y, text, style) { + bitmapText: function (x, y, text, style, group) { + + if (typeof group === 'undefined') { group = this.world; } return this.world.add(new Phaser.BitmapText(this.game, x, y, text, style)); @@ -17618,41 +19498,13 @@ Phaser.GameObjectFactory.prototype = { * Creates a new Tilemap object. * * @method Phaser.GameObjectFactory#tilemap - * @param {string} key - Asset key for the JSON file. + * @param {string} key - Asset key for the JSON or CSV map data in the cache. + * @param {object|string} tilesets - An object mapping Cache.tileset keys with the tileset names in the JSON file. If a string is provided that will be used. * @return {Phaser.Tilemap} The newly created tilemap object. */ - tilemap: function (key) { + tilemap: function (key, tilesets) { - return new Phaser.Tilemap(this.game, key); - - }, - - /** - * Creates a new Tileset object. - * - * @method Phaser.GameObjectFactory#tileset - * @param {string} key - The image key as defined in the Game.Cache to use as the tileset. - * @return {Phaser.Tileset} The newly created tileset object. - */ - tileset: function (key) { - - return this.game.cache.getTileset(key); - - }, - - /** - * Creates a new Tilemap Layer object. - * - * @method Phaser.GameObjectFactory#tilemapLayer - * @param {number} x - X position of the new tilemapLayer. - * @param {number} y - Y position of the new tilemapLayer. - * @param {number} width - the width of the tilemapLayer. - * @param {number} height - the height of the tilemapLayer. - * @return {Phaser.TilemapLayer} The newly created tilemaplayer object. - */ - tilemapLayer: function (x, y, width, height, tileset, tilemap, layer) { - - return this.world.add(new Phaser.TilemapLayer(this.game, x, y, width, height, tileset, tilemap, layer)); + return new Phaser.Tilemap(this.game, key, tilesets); }, @@ -17676,7 +19528,7 @@ Phaser.GameObjectFactory.prototype = { }, /** - * A BitmapData object which can be manipulated and drawn to like a traditional Canvas object and used to texture Sprites. + * Experimental: A BitmapData object which can be manipulated and drawn to like a traditional Canvas object and used to texture Sprites. * * @method Phaser.GameObjectFactory#bitmapData * @param {number} [width=256] - The width of the BitmapData in pixels. @@ -17710,9 +19562,12 @@ Phaser.GameObjectFactory.prototype = { } }; + +Phaser.GameObjectFactory.prototype.constructor = Phaser.GameObjectFactory; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -18669,7 +20524,9 @@ Phaser.BitmapData.prototype = { } -} +}; + +Phaser.BitmapData.prototype.constructor = Phaser.BitmapData; // EaselJS Tiny API emulation @@ -18831,7 +20688,7 @@ Phaser.BitmapData.prototype.de = Phaser.BitmapData.prototype.ellipse; /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -19040,6 +20897,7 @@ Phaser.Sprite = function (game, x, y, key, frame) { */ this._cache = { + fresh: true, dirty: false, // Transform cache @@ -19185,7 +21043,7 @@ Phaser.Sprite = function (game, x, y, key, frame) { /** * @property {Phaser.Point} cameraOffset - If this Sprite is fixed to the camera then use this Point to specify how far away from the Camera x/y it's rendered. */ - this.cameraOffset = new Phaser.Point(); + this.cameraOffset = new Phaser.Point(x, y); /** * You can crop the Sprites texture by modifying the crop properties. For example crop.width = 50 would set the Sprite to only render 50px wide. @@ -19201,9 +21059,19 @@ Phaser.Sprite = function (game, x, y, key, frame) { */ this.cropEnabled = false; + /** + * @property {boolean} debug - Handy flag to use with Game.enableStep + * @default + */ + this.debug = false; + this.updateCache(); this.updateBounds(); + /** + * @property {PIXI.Point} pivot - The pivot point of the displayObject that it rotates around. + */ + }; // Needed to keep the PIXI.Sprite constructor in the prototype chain (as the core pixi renderer uses an instanceof check sadly) @@ -19218,6 +21086,24 @@ Phaser.Sprite.prototype.constructor = Phaser.Sprite; */ Phaser.Sprite.prototype.preUpdate = function() { + if (this._cache.fresh) + { + this.world.setTo(this.parent.position.x + this.x, this.parent.position.y + this.y); + this.worldTransform[2] = this.world.x; + this.worldTransform[5] = this.world.y; + this._cache.fresh = false; + + if (this.body) + { + this.body.x = (this.world.x - (this.anchor.x * this.width)) + this.body.offset.x; + this.body.y = (this.world.y - (this.anchor.y * this.height)) + this.body.offset.y; + this.body.preX = this.body.x; + this.body.preY = this.body.y; + } + + return; + } + if (!this.exists || (this.group && !this.group.exists)) { this.renderOrderID = -1; @@ -19333,7 +21219,6 @@ Phaser.Sprite.prototype.updateAnimation = function() { this._cache.halfHeight = Math.floor(this._cache.height / 2); this._cache.dirty = true; - } }; @@ -19428,12 +21313,6 @@ Phaser.Sprite.prototype.updateBounds = function() { this.renderable = this._cache.cameraVisible; } - // Update our physics bounds - if (this.body) - { - this.body.updateBounds(this.center.x, this.center.y, this._cache.scaleX, this._cache.scaleY); - } - }; /** @@ -19444,9 +21323,7 @@ Phaser.Sprite.prototype.updateBounds = function() { * @memberof Phaser.Sprite * @param {Phaser.Point} p - The Point object to store the results in. * @param {number} x - x coordinate within the Sprite to translate. -* @param {number} y - x coordinate within the Sprite to translate. -* @param {number} sx - Scale factor to be applied. -* @param {number} sy - Scale factor to be applied. +* @param {number} y - y coordinate within the Sprite to translate. * @return {Phaser.Point} The translated point. */ Phaser.Sprite.prototype.getLocalPosition = function(p, x, y) { @@ -19465,8 +21342,8 @@ Phaser.Sprite.prototype.getLocalPosition = function(p, x, y) { * @method Phaser.Sprite#getLocalUnmodifiedPosition * @memberof Phaser.Sprite * @param {Phaser.Point} p - The Point object to store the results in. -* @param {number} x - x coordinate within the Sprite to translate. -* @param {number} y - x coordinate within the Sprite to translate. +* @param {number} gx - x coordinate within the Sprite to translate. +* @param {number} gy - y coordinate within the Sprite to translate. * @return {Phaser.Point} The translated point. */ Phaser.Sprite.prototype.getLocalUnmodifiedPosition = function(p, gx, gy) { @@ -19507,7 +21384,6 @@ Phaser.Sprite.prototype.postUpdate = function() { if (this.exists) { - // The sprite is positioned in this call, after taking into consideration motion updates and collision if (this.body) { this.body.postUpdate(); @@ -19524,8 +21400,6 @@ Phaser.Sprite.prototype.postUpdate = function() { this._cache.y = this.y; } - this.world.setTo(this.game.camera.x + this.worldTransform[2], this.game.camera.y + this.worldTransform[5]); - this.position.x = this._cache.x; this.position.y = this._cache.y; } @@ -19603,8 +21477,17 @@ Phaser.Sprite.prototype.loadTexture = function (key, frame) { */ Phaser.Sprite.prototype.centerOn = function(x, y) { - this.x = x + (this.x - this.center.x); - this.y = y + (this.y - this.center.y); + if (this.fixedToCamera) + { + this.cameraOffset.x = x + (this.cameraOffset.x - this.center.x); + this.cameraOffset.y = y + (this.cameraOffset.y - this.center.y); + } + else + { + this.x = x + (this.x - this.center.x); + this.y = y + (this.y - this.center.y); + } + return this; }; @@ -19671,6 +21554,11 @@ Phaser.Sprite.prototype.kill = function() { */ Phaser.Sprite.prototype.destroy = function() { + if (this.filters) + { + this.filters = null; + } + if (this.group) { this.group.remove(this); @@ -19691,6 +21579,11 @@ Phaser.Sprite.prototype.destroy = function() { this.animations.destroy(); } + if (this.body) + { + this.body.destroy(); + } + this.alive = false; this.exists = false; this.visible = false; @@ -19742,6 +21635,7 @@ Phaser.Sprite.prototype.reset = function(x, y, health) { this.x = x; this.y = y; + this.world.setTo(x, y); this.position.x = this.x; this.position.y = this.y; this.alive = true; @@ -19754,7 +21648,7 @@ Phaser.Sprite.prototype.reset = function(x, y, health) { if (this.body) { - this.body.reset(); + this.body.reset(false); } return this; @@ -19805,6 +21699,34 @@ Phaser.Sprite.prototype.play = function (name, frameRate, loop, killOnComplete) }; +/** +* Returns the delta x value. The difference between Sprite.x now and in the previous step. +* @name Phaser.Sprite#deltaX +* @property {number} deltaX - The delta value. Positive if the motion was to the right, negative if to the left. +* @readonly +*/ +Object.defineProperty(Phaser.Sprite.prototype, 'deltaX', { + + get: function() { + return this.world.x - this._cache.prevX; + } + +}); + +/** +* Returns the delta x value. The difference between Sprite.y now and in the previous step. +* @name Phaser.Sprite#deltaY +* @property {number} deltaY - The delta value. Positive if the motion was downwards, negative if upwards. +* @readonly +*/ +Object.defineProperty(Phaser.Sprite.prototype, 'deltaY', { + + get: function() { + return this.world.y - this._cache.prevY; + } + +}); + /** * Indicates the rotation of the Sprite, in degrees, from its original orientation. Values from 0 to 180 represent clockwise rotation; values from 0 to -180 represent counterclockwise rotation. * Values outside this range are added to or subtracted from 360 to obtain a value within the range. For example, the statement player.angle = 450 is the same as player.angle = 90. @@ -19869,6 +21791,32 @@ Object.defineProperty(Phaser.Sprite.prototype, "inCamera", { }); +/** +* @name Phaser.Sprite#worldCenterX +* @property {number} worldCenterX - The center of the Sprite in world coordinates. +* @readonly +*/ +Object.defineProperty(Phaser.Sprite.prototype, "worldCenterX", { + + get: function () { + return this.game.camera.x + this.center.x; + } + +}); + +/** +* @name Phaser.Sprite#worldCenterY +* @property {number} worldCenterY - The center of the Sprite in world coordinates. +* @readonly +*/ +Object.defineProperty(Phaser.Sprite.prototype, "worldCenterY", { + + get: function () { + return this.game.camera.y + this.center.y; + } + +}); + /** * The width of the sprite in pixels, setting this will actually modify the scale to acheive the value desired. * If you wish to crop the Sprite instead see the Sprite.crop value. @@ -19932,8 +21880,6 @@ Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", { set: function (value) { - console.log('inputEnabled', value, this.input); - if (value) { if (this.input.enabled === false) @@ -19955,7 +21901,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -19970,18 +21916,16 @@ Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", { * @param {number} width - the width of the tilesprite. * @param {number} height - the height of the tilesprite. * @param {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture. -* @param {string|number} frame - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index. */ -Phaser.TileSprite = function (game, x, y, width, height, key, frame) { +Phaser.TileSprite = function (game, x, y, width, height, key) { x = x || 0; y = y || 0; width = width || 256; height = height || 256; key = key || null; - frame = frame || null; - Phaser.Sprite.call(this, game, x, y, key, frame); + Phaser.Sprite.call(this, game, x, y, key); /** * @property {PIXI.Texture} texture - The texture that the sprite renders with. @@ -20006,20 +21950,122 @@ Phaser.TileSprite = function (game, x, y, width, height, key, frame) { */ this.tilePosition = new Phaser.Point(0, 0); + this.body.width = width; + this.body.height = height; + }; Phaser.TileSprite.prototype = Phaser.Utils.extend(true, PIXI.TilingSprite.prototype, Phaser.Sprite.prototype); Phaser.TileSprite.prototype.constructor = Phaser.TileSprite; +/** +* Indicates the rotation of the Sprite, in degrees, from its original orientation. Values from 0 to 180 represent clockwise rotation; values from 0 to -180 represent counterclockwise rotation. +* Values outside this range are added to or subtracted from 360 to obtain a value within the range. For example, the statement player.angle = 450 is the same as player.angle = 90. +* If you wish to work in radians instead of degrees use the property Sprite.rotation instead. +* @name Phaser.TileSprite#angle +* @property {number} angle - Gets or sets the Sprites angle of rotation in degrees. +*/ +Object.defineProperty(Phaser.TileSprite.prototype, 'angle', { + + get: function() { + return Phaser.Math.wrapAngle(Phaser.Math.radToDeg(this.rotation)); + }, + + set: function(value) { + this.rotation = Phaser.Math.degToRad(Phaser.Math.wrapAngle(value)); + } + +}); + +/** +* @name Phaser.TileSprite#frame +* @property {number} frame - Gets or sets the current frame index and updates the Texture Cache for display. +*/ +Object.defineProperty(Phaser.TileSprite.prototype, "frame", { + + get: function () { + return this.animations.frame; + }, + + set: function (value) { + this.animations.frame = value; + } + +}); + +/** +* @name Phaser.TileSprite#frameName +* @property {string} frameName - Gets or sets the current frame name and updates the Texture Cache for display. +*/ +Object.defineProperty(Phaser.TileSprite.prototype, "frameName", { + + get: function () { + return this.animations.frameName; + }, + + set: function (value) { + this.animations.frameName = value; + } + +}); + +/** +* @name Phaser.TileSprite#inCamera +* @property {boolean} inCamera - Is this sprite visible to the camera or not? +* @readonly +*/ +Object.defineProperty(Phaser.TileSprite.prototype, "inCamera", { + + get: function () { + return this._cache.cameraVisible; + } + +}); + +/** +* By default a Sprite won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is +* activated for this Sprite instance and it will then start to process click/touch events and more. +* +* @name Phaser.TileSprite#inputEnabled +* @property {boolean} inputEnabled - Set to true to allow this Sprite to receive input events, otherwise false. +*/ +Object.defineProperty(Phaser.TileSprite.prototype, "inputEnabled", { + + get: function () { + + return (this.input.enabled); + + }, + + set: function (value) { + + if (value) + { + if (this.input.enabled === false) + { + this.input.start(); + } + } + else + { + if (this.input.enabled) + { + this.input.stop(); + } + } + + } + +}); /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** -* Create a new Text. +* Create a new `Text` object. * @class Phaser.Text * @constructor * @param {Phaser.Game} game - Current game instance. @@ -20104,6 +22150,18 @@ Phaser.Text = function (game, x, y, text, style) { */ this.scale = new Phaser.Point(1, 1); + /** + * An object that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera. + * @property {boolean} fixedToCamera - Fixes this object to the Camera. + * @default + */ + this.fixedToCamera = false; + + /** + * @property {Phaser.Point} cameraOffset - If this object is fixed to the camera then use this Point to specify how far away from the Camera x/y it's rendered. + */ + this.cameraOffset = new Phaser.Point(x, y); + /** * @property {object} _cache - A mini cache for storing all of the calculated values. * @private @@ -20155,6 +22213,12 @@ Phaser.Text.prototype.update = function() { return; } + if (this.fixedToCamera) + { + this.x = this.game.camera.view.x + this.cameraOffset.x; + this.y = this.game.camera.view.y + this.cameraOffset.y; + } + this._cache.dirty = false; this._cache.x = this.x; @@ -20298,7 +22362,7 @@ Object.defineProperty(Phaser.Text.prototype, 'font', { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -20418,11 +22482,6 @@ Phaser.BitmapText = function (game, x, y, text, style) { this._cache.x = this.x; this._cache.y = this.y; - /** - * @property {boolean} renderable - A renderable object will be rendered to the context each frame. - */ - this.renderable = true; - }; Phaser.BitmapText.prototype = Object.create(PIXI.BitmapText.prototype); @@ -20451,8 +22510,8 @@ Phaser.BitmapText.prototype.update = function() { this._cache.dirty = true; } - this.pivot.x = this.anchor.x*this.width; - this.pivot.y = this.anchor.y*this.height; + this.pivot.x = this.anchor.x * this.width; + this.pivot.y = this.anchor.y * this.height; } @@ -20537,7 +22596,7 @@ Object.defineProperty(Phaser.BitmapText.prototype, 'y', { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -20556,16 +22615,17 @@ Object.defineProperty(Phaser.BitmapText.prototype, 'y', { * @constructor * * @param {Phaser.Game} game Current game instance. -* @param {number} [x] - X position of the Button. -* @param {number} [y] - Y position of the Button. +* @param {number} [x=0] - X position of the Button. +* @param {number} [y=0] - Y position of the Button. * @param {string} [key] - The image key as defined in the Game.Cache to use as the texture for this Button. * @param {function} [callback] - The function to call when this Button is pressed. * @param {object} [callbackContext] - The context in which the callback will be called (usually 'this'). * @param {string|number} [overFrame] - This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name. * @param {string|number} [outFrame] - This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name. * @param {string|number} [downFrame] - This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name. +* @param {string|number} [upFrame] - This is the frame or frameName that will be set when this button is in an up state. Give either a number to use a frame ID or a string for a frame name. */ -Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame) { +Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame, upFrame) { x = x || 0; y = y || 0; @@ -20600,7 +22660,7 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, * @default */ this._onDownFrameName = null; - + /** * @property {string} _onUpFrameName - Internal variable. * @private @@ -20628,7 +22688,7 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, * @default */ this._onDownFrameID = null; - + /** * @property {number} _onUpFrameID - Internal variable. * @private @@ -20710,13 +22770,13 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, this.freezeFrames = false; /** - * When the Button is clicked you can optionally force the state to "out". + * When the Button is touched / clicked and then released you can force it to enter a state of "out" instead of "up". * @property {boolean} forceOut * @default */ - this.forceOut = true; + this.forceOut = false; - this.setFrames(overFrame, outFrame, downFrame); + this.setFrames(overFrame, outFrame, downFrame, upFrame); if (callback !== null) { @@ -20738,15 +22798,38 @@ Phaser.Button.prototype = Phaser.Utils.extend(true, Phaser.Button.prototype, Pha Phaser.Button.prototype.constructor = Phaser.Button; /** -* Used to manually set the frames that will be used for the different states of the button -* exactly like setting them in the constructor. +* Clears all of the frames set on this Button. +* +* @method Phaser.Button.prototype.clearFrames +*/ +Phaser.Button.prototype.clearFrames = function () { + + this._onOverFrameName = null; + this._onOverFrameID = null; + + this._onOutFrameName = null; + this._onOutFrameID = null; + + this._onDownFrameName = null; + this._onDownFrameID = null; + + this._onUpFrameName = null; + this._onUpFrameID = null; + +} + +/** +* Used to manually set the frames that will be used for the different states of the Button. * * @method Phaser.Button.prototype.setFrames * @param {string|number} [overFrame] - This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name. * @param {string|number} [outFrame] - This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name. * @param {string|number} [downFrame] - This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name. +* @param {string|number} [upFrame] - This is the frame or frameName that will be set when this button is in an up state. Give either a number to use a frame ID or a string for a frame name. */ -Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) { +Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame, upFrame) { + + this.clearFrames(); if (overFrame !== null) { @@ -20775,7 +22858,6 @@ Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) { if (typeof outFrame === 'string') { this._onOutFrameName = outFrame; - this._onUpFrameName = outFrame; if (this.input.pointerOver() === false) { @@ -20785,7 +22867,6 @@ Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) { else { this._onOutFrameID = outFrame; - this._onUpFrameID = outFrame; if (this.input.pointerOver() === false) { @@ -20816,6 +22897,28 @@ Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) { } } + if (upFrame !== null) + { + if (typeof upFrame === 'string') + { + this._onUpFrameName = upFrame; + + if (this.input.pointerUp()) + { + this.frameName = upFrame; + } + } + else + { + this._onUpFrameID = upFrame; + + if (this.input.pointerUp()) + { + this.frame = upFrame; + } + } + } + }; /** @@ -20837,8 +22940,8 @@ Phaser.Button.prototype.setSounds = function (overSound, overMarker, downSound, this.setOverSound(overSound, overMarker); this.setOutSound(outSound, outMarker); - this.setUpSound(upSound, upMarker); this.setDownSound(downSound, downMarker); + this.setUpSound(upSound, upMarker); } @@ -20891,31 +22994,7 @@ Phaser.Button.prototype.setOutSound = function (sound, marker) { } /** -* The Sound to be played when a Pointer clicks on this Button. -* -* @method Phaser.Button.prototype.setUpSound -* @param {Phaser.Sound} sound - The Sound that will be played. -* @param {string} [marker] - A Sound Marker that will be used in the playback. -*/ -Phaser.Button.prototype.setUpSound = function (sound, marker) { - - this.onUpSound = null; - this.onUpSoundMarker = ''; - - if (sound instanceof Phaser.Sound) - { - this.onUpSound = sound; - } - - if (typeof marker === 'string') - { - this.onUpSoundMarker = marker; - } - -} - -/** -* The Sound to be played when a Pointer clicks on this Button. +* The Sound to be played when a Pointer presses down on this Button. * * @method Phaser.Button.prototype.setDownSound * @param {Phaser.Sound} sound - The Sound that will be played. @@ -20938,25 +23017,43 @@ Phaser.Button.prototype.setDownSound = function (sound, marker) { } +/** +* The Sound to be played when a Pointer has pressed down and is released from this Button. +* +* @method Phaser.Button.prototype.setUpSound +* @param {Phaser.Sound} sound - The Sound that will be played. +* @param {string} [marker] - A Sound Marker that will be used in the playback. +*/ +Phaser.Button.prototype.setUpSound = function (sound, marker) { + + this.onUpSound = null; + this.onUpSoundMarker = ''; + + if (sound instanceof Phaser.Sound) + { + this.onUpSound = sound; + } + + if (typeof marker === 'string') + { + this.onUpSoundMarker = marker; + } + +} + /** * Internal function that handles input events. * * @protected * @method Phaser.Button.prototype.onInputOverHandler +* @param {Phaser.Button} sprite - The Button that the event occured on. * @param {Phaser.Pointer} pointer - The Pointer that activated the Button. */ -Phaser.Button.prototype.onInputOverHandler = function (pointer) { +Phaser.Button.prototype.onInputOverHandler = function (sprite, pointer) { if (this.freezeFrames === false) { - if (this._onOverFrameName != null) - { - this.frameName = this._onOverFrameName; - } - else if (this._onOverFrameID != null) - { - this.frame = this._onOverFrameID; - } + this.setState(1); } if (this.onOverSound) @@ -20975,20 +23072,14 @@ Phaser.Button.prototype.onInputOverHandler = function (pointer) { * * @protected * @method Phaser.Button.prototype.onInputOverHandler +* @param {Phaser.Button} sprite - The Button that the event occured on. * @param {Phaser.Pointer} pointer - The Pointer that activated the Button. */ -Phaser.Button.prototype.onInputOutHandler = function (pointer) { +Phaser.Button.prototype.onInputOutHandler = function (sprite, pointer) { if (this.freezeFrames === false) { - if (this._onOutFrameName != null) - { - this.frameName = this._onOutFrameName; - } - else if (this._onOutFrameID != null) - { - this.frame = this._onOutFrameID; - } + this.setState(2); } if (this.onOutSound) @@ -21007,20 +23098,14 @@ Phaser.Button.prototype.onInputOutHandler = function (pointer) { * * @protected * @method Phaser.Button.prototype.onInputOverHandler +* @param {Phaser.Button} sprite - The Button that the event occured on. * @param {Phaser.Pointer} pointer - The Pointer that activated the Button. */ -Phaser.Button.prototype.onInputDownHandler = function (pointer) { +Phaser.Button.prototype.onInputDownHandler = function (sprite, pointer) { if (this.freezeFrames === false) { - if (this._onDownFrameName != null) - { - this.frameName = this._onDownFrameName; - } - else if (this._onDownFrameID != null) - { - this.frame = this._onDownFrameID; - } + this.setState(3); } if (this.onDownSound) @@ -21039,12 +23124,100 @@ Phaser.Button.prototype.onInputDownHandler = function (pointer) { * * @protected * @method Phaser.Button.prototype.onInputOverHandler +* @param {Phaser.Button} sprite - The Button that the event occured on. * @param {Phaser.Pointer} pointer - The Pointer that activated the Button. */ -Phaser.Button.prototype.onInputUpHandler = function (pointer) { +Phaser.Button.prototype.onInputUpHandler = function (sprite, pointer, isOver) { - if (this.freezeFrames === false) + if (this.onUpSound) { + this.onUpSound.play(this.onUpSoundMarker); + } + + if (this.onInputUp) + { + this.onInputUp.dispatch(this, pointer, isOver); + } + + if (this.freezeFrames) + { + return; + } + + if (this.forceOut) + { + // Button should be forced to the Out frame when released. + this.setState(2); + } + else + { + if (this._onUpFrameName || this._onUpFrameID) + { + this.setState(4); + } + else + { + if (isOver) + { + this.setState(1); + } + else + { + this.setState(2); + } + } + } + +}; + +/** +* Internal function that handles Button state changes. +* +* @protected +* @method Phaser.Button.prototype.setState +* @param {number} newState - The new State of the Button. +*/ +Phaser.Button.prototype.setState = function (newState) { + + if (newState === 1) + { + // Over + if (this._onOverFrameName != null) + { + this.frameName = this._onOverFrameName; + } + else if (this._onOverFrameID != null) + { + this.frame = this._onOverFrameID; + } + } + else if (newState === 2) + { + // Out + if (this._onOutFrameName != null) + { + this.frameName = this._onOutFrameName; + } + else if (this._onOutFrameID != null) + { + this.frame = this._onOutFrameID; + } + } + else if (newState === 3) + { + // Down + if (this._onDownFrameName != null) + { + this.frameName = this._onDownFrameName; + } + else if (this._onDownFrameID != null) + { + this.frame = this._onDownFrameID; + } + } + else if (newState === 4) + { + // Up if (this._onUpFrameName != null) { this.frameName = this._onUpFrameName; @@ -21055,33 +23228,11 @@ Phaser.Button.prototype.onInputUpHandler = function (pointer) { } } - if (this.onUpSound) - { - this.onUpSound.play(this.onUpSoundMarker); - } - - if (this.forceOut && this.freezeFrames === false) - { - if (this._onOutFrameName != null) - { - this.frameName = this._onOutFrameName; - } - else if (this._onOutFrameID != null) - { - this.frame = this._onOutFrameID; - } - } - - if (this.onInputUp) - { - this.onInputUp.dispatch(this, pointer); - } - }; /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -21186,7 +23337,7 @@ Object.defineProperty(Phaser.Graphics.prototype, 'y', { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -21257,16 +23408,19 @@ Phaser.RenderTexture.prototype.constructor = PIXI.RenderTexture; /** * This function will draw the display object to the texture. If the display object is a Group or has children it will * draw all children as well. -* -* @method render +* +* @method Phaser.RenderTexture#render +* @memberof Phaser.RenderTexture * @param {DisplayObject} displayObject - The display object to render this texture on. * @param {Phaser.Point} [position] - Where to draw the display object. * @param {boolean} [clear=false] - If true the texture will be cleared before the displayObject is drawn. +* @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered. */ -Phaser.RenderTexture.prototype.render = function(displayObject, position, clear) { +Phaser.RenderTexture.prototype.render = function(displayObject, position, clear, renderHidden) { if (typeof position === 'undefined') { position = false; } if (typeof clear === 'undefined') { clear = false; } + if (typeof renderHidden === 'undefined') { renderHidden = false; } if (displayObject instanceof Phaser.Group) { @@ -21275,11 +23429,11 @@ Phaser.RenderTexture.prototype.render = function(displayObject, position, clear) if (PIXI.gl) { - this.renderWebGL(displayObject, position, clear); + this.renderWebGL(displayObject, position, clear, renderHidden); } else { - this.renderCanvas(displayObject, position, clear); + this.renderCanvas(displayObject, position, clear, renderHidden); } } @@ -21288,29 +23442,32 @@ Phaser.RenderTexture.prototype.render = function(displayObject, position, clear) * This function will draw the display object to the texture at the given x/y coordinates. * If the display object is a Group or has children it will draw all children as well. * -* @method renderXY +* @method Phaser.RenderTexture#renderXY +* @memberof Phaser.RenderTexture * @param {DisplayObject} displayObject - The display object to render this texture on. * @param {number} x - The x coordinate to draw the display object at. * @param {number} y - The y coordinate to draw the display object at. * @param {boolean} [clear=false] - If true the texture will be cleared before the displayObject is drawn. +* @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered. */ -Phaser.RenderTexture.prototype.renderXY = function(displayObject, x, y, clear) { +Phaser.RenderTexture.prototype.renderXY = function(displayObject, x, y, clear, renderHidden) { this._tempPoint.x = x; this._tempPoint.y = y; - this.render(displayObject, this._tempPoint, clear); + this.render(displayObject, this._tempPoint, clear, renderHidden); } /** - * Initializes the webgl data for this texture - * - * @method initWebGL - * @private - */ -Phaser.RenderTexture.prototype.initWebGL = function() -{ +* Initializes the webgl data for this texture +* +* @method Phaser.RenderTexture#initWebGL +* @memberof Phaser.RenderTexture +* @private +*/ +Phaser.RenderTexture.prototype.initWebGL = function() { + var gl = PIXI.gl; this.glFramebuffer = gl.createFramebuffer(); @@ -21346,7 +23503,12 @@ Phaser.RenderTexture.prototype.initWebGL = function() // this.render = this.renderWebGL; } - +/** +* Resizes the RenderTexture. +* +* @method Phaser.RenderTexture#resize +* @memberof Phaser.RenderTexture +*/ Phaser.RenderTexture.prototype.resize = function(width, height) { @@ -21372,11 +23534,12 @@ Phaser.RenderTexture.prototype.resize = function(width, height) } /** - * Initializes the canvas data for this texture - * - * @method initCanvas - * @private - */ +* Initializes the canvas data for this texture +* +* @method Phaser.RenderTexture#initCanvas +* @memberof Phaser.RenderTexture +* @private +*/ Phaser.RenderTexture.prototype.initCanvas = function() { this.renderer = new PIXI.CanvasRenderer(this.width, this.height, null, 0); @@ -21388,14 +23551,17 @@ Phaser.RenderTexture.prototype.initCanvas = function() } /** - * This function will draw the display object to the texture. - * - * @method renderWebGL - * @param displayObject {DisplayObject} The display object to render this texture on - * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn - * @private - */ -Phaser.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear) +* This function will draw the display object to the texture. +* +* @method Phaser.RenderTexture#renderWebGL +* @memberof Phaser.RenderTexture +* @private +* @param {DisplayObject} displayObject - The display object to render this texture on. +* @param {Phaser.Point} [position] - Where to draw the display object. +* @param {boolean} [clear=false] - If true the texture will be cleared before the displayObject is drawn. +* @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered. +*/ +Phaser.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear, renderHidden) { var gl = PIXI.gl; @@ -21466,12 +23632,15 @@ Phaser.RenderTexture.prototype.renderWebGL = function(displayObject, position, c /** * This function will draw the display object to the texture. * - * @method renderCanvas - * @param displayObject {DisplayObject} The display object to render this texture on - * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn - * @private - */ -Phaser.RenderTexture.prototype.renderCanvas = function(displayObject, position, clear) +* @method Phaser.RenderTexture#renderCanvas +* @memberof Phaser.RenderTexture +* @private +* @param {DisplayObject} displayObject - The display object to render this texture on. +* @param {Phaser.Point} [position] - Where to draw the display object. +* @param {boolean} [clear=false] - If true the texture will be cleared before the displayObject is drawn. +* @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered. +*/ +Phaser.RenderTexture.prototype.renderCanvas = function(displayObject, position, clear, renderHidden) { var children = displayObject.children; @@ -21492,22 +23661,21 @@ Phaser.RenderTexture.prototype.renderCanvas = function(displayObject, position, { this.renderer.context.clearRect(0, 0, this.width, this.height); } - - this.renderer.renderDisplayObject(displayObject); + + this.renderer.renderDisplayObject(displayObject, renderHidden); this.renderer.context.setTransform(1, 0, 0, 1, 0, 0); - // PIXI.texturesToUpdate.push(this.baseTexture); } /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** -* The Canvas class handles everything related to the <canvas> tag as a DOM Element, like styles, offset, aspect ratio +* The Canvas class handles everything related to creating the `canvas` DOM tag that Phaser will use, including styles, offset and aspect ratio. * * @class Phaser.Canvas * @static @@ -21515,21 +23683,29 @@ Phaser.RenderTexture.prototype.renderCanvas = function(displayObject, position, Phaser.Canvas = { /** - * Creates the <canvas> tag + * Creates a `canvas` DOM element. The element is not automatically added to the document. * * @method Phaser.Canvas.create - * @param {number} width - The desired width. - * @param {number} height - The desired height. - * @return {HTMLCanvasElement} The newly created <canvas> tag. + * @param {number} [width=256] - The width of the canvas element. + * @param {number} [height=256] - The height of the canvas element.. + * @param {string} [id=''] - If given this will be set as the ID of the canvas element, otherwise no ID will be set. + * @return {HTMLCanvasElement} The newly created canvas element. */ - create: function (width, height) { + create: function (width, height, id) { width = width || 256; height = height || 256; var canvas = document.createElement('canvas'); + + if (typeof id === 'string') + { + canvas.id = id; + } + canvas.width = width; canvas.height = height; + canvas.style.display = 'block'; return canvas; @@ -21550,8 +23726,22 @@ Phaser.Canvas = { var box = element.getBoundingClientRect(); var clientTop = element.clientTop || document.body.clientTop || 0; var clientLeft = element.clientLeft || document.body.clientLeft || 0; - var scrollTop = window.pageYOffset || element.scrollTop || document.body.scrollTop; - var scrollLeft = window.pageXOffset || element.scrollLeft || document.body.scrollLeft; + + // Without this check Chrome is now throwing console warnings about strict vs. quirks :( + + var scrollTop = 0; + var scrollLeft = 0; + + if (document.compatMode === 'CSS1Compat') + { + scrollTop = window.pageYOffset || document.documentElement.scrollTop || element.scrollTop || 0; + scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || element.scrollLeft || 0; + } + else + { + scrollTop = window.pageYOffset || document.body.scrollTop || element.scrollTop || 0; + scrollLeft = window.pageXOffset || document.body.scrollLeft || element.scrollLeft || 0; + } point.x = box.left + scrollLeft - clientLeft; point.y = box.top + scrollTop - clientTop; @@ -21639,8 +23829,8 @@ Phaser.Canvas = { * * @method Phaser.Canvas.addToDOM * @param {HTMLCanvasElement} canvas - The canvas to set the touch action on. - * @param {string|HTMLElement} parent - The DOM element to add the canvas to. Defaults to ''. - * @param {boolean} overflowHidden - If set to true it will add the overflow='hidden' style to the parent DOM element. + * @param {string|HTMLElement} parent - The DOM element to add the canvas to. + * @param {boolean} [overflowHidden=true] - If set to true it will add the overflow='hidden' style to the parent DOM element. * @return {HTMLCanvasElement} Returns the source canvas. */ addToDOM: function (canvas, parent, overflowHidden) { @@ -21651,29 +23841,29 @@ Phaser.Canvas = { if (parent) { - // hopefully an element ID if (typeof parent === 'string') { + // hopefully an element ID target = document.getElementById(parent); } - // quick test for a HTMLelement else if (typeof parent === 'object' && parent.nodeType === 1) { + // quick test for a HTMLelement target = parent; } - - if (overflowHidden) - { - target.style.overflow = 'hidden'; - } } - // fallback, covers an invalid ID and a none HTMLelement object - if(!target) + // Fallback, covers an invalid ID and a non HTMLelement object + if (!target) { target = document.body; } + if (overflowHidden && target.style) + { + target.style.overflow = 'hidden'; + } + target.appendChild(canvas); return canvas; @@ -21735,9 +23925,11 @@ Phaser.Canvas = { */ setImageRenderingCrisp: function (canvas) { + canvas.style['image-rendering'] = 'optimizeSpeed'; canvas.style['image-rendering'] = 'crisp-edges'; canvas.style['image-rendering'] = '-moz-crisp-edges'; canvas.style['image-rendering'] = '-webkit-optimize-contrast'; + canvas.style['image-rendering'] = 'optimize-contrast'; canvas.style.msInterpolationMode = 'nearest-neighbor'; return canvas; @@ -21765,7 +23957,7 @@ Phaser.Canvas = { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -22025,7 +24217,8 @@ Phaser.StageScaleMode.prototype = { this._width = this.width; this._height = this.height; - console.log('startFullScreen', this._width, this._height); + // This needs updating to match the final spec: + // http://generatedcontent.org/post/70347573294/is-your-fullscreen-api-code-up-to-date-find-out-how-to if (element['requestFullScreen']) { @@ -22033,7 +24226,7 @@ Phaser.StageScaleMode.prototype = { } else if (element['mozRequestFullScreen']) { - element['mozRequestFullScreen'](); + element.parentNode['mozRequestFullScreen'](); } else if (element['webkitRequestFullScreen']) { @@ -22075,16 +24268,24 @@ Phaser.StageScaleMode.prototype = { if (this.isFullScreen) { - this.game.stage.canvas.style['width'] = '100%'; - this.game.stage.canvas.style['height'] = '100%'; + if (this.game.stage.fullScreenScaleMode === Phaser.StageScaleMode.EXACT_FIT) + { + this.game.stage.canvas.style['width'] = '100%'; + this.game.stage.canvas.style['height'] = '100%'; - this.setMaximum(); + this.setMaximum(); - this.game.input.scale.setTo(this.game.width / this.width, this.game.height / this.height); + this.game.input.scale.setTo(this.game.width / this.width, this.game.height / this.height); - this.aspectRatio = this.width / this.height; - this.scaleFactor.x = this.game.width / this.width; - this.scaleFactor.y = this.game.height / this.height; + this.aspectRatio = this.width / this.height; + this.scaleFactor.x = this.game.width / this.width; + this.scaleFactor.y = this.game.height / this.height; + } + else if (this.game.stage.fullScreenScaleMode === Phaser.StageScaleMode.SHOW_ALL) + { + this.game.stage.scale.setShowAll(); + this.game.stage.scale.refresh(); + } } else { @@ -22325,13 +24526,27 @@ Phaser.StageScaleMode.prototype = { { this.setMaximum(); } - else if (this.game.stage.scaleMode == Phaser.StageScaleMode.EXACT_FIT) + else if (!this.isFullScreen) { - this.setExactFit(); + if (this.game.stage.scaleMode == Phaser.StageScaleMode.EXACT_FIT) + { + this.setExactFit(); + } + else if (this.game.stage.scaleMode == Phaser.StageScaleMode.SHOW_ALL) + { + this.setShowAll(); + } } - else if (this.game.stage.scaleMode == Phaser.StageScaleMode.SHOW_ALL) + else { - this.setShowAll(); + if (this.game.stage.fullScreenScaleMode == Phaser.StageScaleMode.EXACT_FIT) + { + this.setExactFit(); + } + else if (this.game.stage.fullScreenScaleMode == Phaser.StageScaleMode.SHOW_ALL) + { + this.setShowAll(); + } } this.setSize(); @@ -22452,8 +24667,6 @@ Phaser.StageScaleMode.prototype = { var availableWidth = window.innerWidth; var availableHeight = window.innerHeight; - // console.log('available', availableWidth, availableHeight); - if (this.maxWidth && availableWidth > this.maxWidth) { this.width = this.maxWidth; @@ -22476,6 +24689,8 @@ Phaser.StageScaleMode.prototype = { }; +Phaser.StageScaleMode.prototype.constructor = Phaser.StageScaleMode; + /** * @name Phaser.StageScaleMode#isFullScreen * @property {boolean} isFullScreen - Returns true if the browser is in full screen mode, otherwise false. @@ -22519,7 +24734,7 @@ Object.defineProperty(Phaser.StageScaleMode.prototype, "isLandscape", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -22559,6 +24774,12 @@ Phaser.Device = function () { */ this.cocoonJS = false; + /** + * @property {boolean} ejecta - Is the game running under Ejecta? + * @default + */ + this.ejecta = false; + /** * @property {boolean} android - Is running on android? * @default @@ -22657,6 +24878,18 @@ Phaser.Device = function () { */ this.typedArray = false; + /** + * @property {boolean} vibration - Does the device support the Vibration API? + * @default + */ + this.vibration = false; + + /** + * @property {boolean} quirksMode - Is the browser running in strict mode (false) or quirks mode? (true) + * @default + */ + this.quirksMode = false; + // Browser /** @@ -22695,6 +24928,18 @@ Phaser.Device = function () { */ this.ieVersion = 0; + /** + * @property {boolean} trident - Set to true if running a Trident version of Internet Explorer (IE11+) + * @default + */ + this.trident = false; + + /** + * @property {number} tridentVersion - If running in Internet Explorer 11 this will contain the major version number. See http://msdn.microsoft.com/en-us/library/ie/ms537503(v=vs.85).aspx + * @default + */ + this.tridentVersion = 0; + /** * @property {boolean} mobileSafari - Set to true if running in Mobile Safari. * @default @@ -22725,6 +24970,12 @@ Phaser.Device = function () { */ this.webApp = false; + /** + * @property {boolean} silk - Set to true if running in the Silk browser (as used on the Amazon Kindle) + * @default + */ + this.silk = false; + // Audio /** @@ -22829,21 +25080,33 @@ Phaser.Device.prototype = { var ua = navigator.userAgent; - if (/Android/.test(ua)) { + if (/Android/.test(ua)) + { this.android = true; - } else if (/CrOS/.test(ua)) { + } + else if (/CrOS/.test(ua)) + { this.chromeOS = true; - } else if (/iP[ao]d|iPhone/i.test(ua)) { + } + else if (/iP[ao]d|iPhone/i.test(ua)) + { this.iOS = true; - } else if (/Linux/.test(ua)) { + } + else if (/Linux/.test(ua)) + { this.linux = true; - } else if (/Mac OS/.test(ua)) { + } + else if (/Mac OS/.test(ua)) + { this.macOS = true; - } else if (/Windows/.test(ua)) { + } + else if (/Windows/.test(ua)) + { this.windows = true; } - if (this.windows || this.macOS || this.linux) { + if (this.windows || this.macOS || (this.linux && this.silk === false)) + { this.desktop = true; } @@ -22879,16 +25142,20 @@ Phaser.Device.prototype = { this.worker = !!window['Worker']; - if ('ontouchstart' in document.documentElement || (window.navigator.maxTouchPoints && window.navigator.maxTouchPoints > 1)) { + if ('ontouchstart' in document.documentElement || (window.navigator.maxTouchPoints && window.navigator.maxTouchPoints > 1)) + { this.touch = true; } - if (window.navigator.msPointerEnabled || window.navigator.pointerEnabled) { + if (window.navigator.msPointerEnabled || window.navigator.pointerEnabled) + { this.mspointer = true; } this.pointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document; + this.quirksMode = (document.compatMode === 'CSS1Compat') ? false : true; + }, /** @@ -22900,36 +25167,70 @@ Phaser.Device.prototype = { var ua = navigator.userAgent; - if (/Arora/.test(ua)) { + if (/Arora/.test(ua)) + { this.arora = true; - } else if (/Chrome/.test(ua)) { + } + else if (/Chrome/.test(ua)) + { this.chrome = true; - } else if (/Epiphany/.test(ua)) { + } + else if (/Epiphany/.test(ua)) + { this.epiphany = true; - } else if (/Firefox/.test(ua)) { + } + else if (/Firefox/.test(ua)) + { this.firefox = true; - } else if (/Mobile Safari/.test(ua)) { + } + else if (/Mobile Safari/.test(ua)) + { this.mobileSafari = true; - } else if (/MSIE (\d+\.\d+);/.test(ua)) { + } + else if (/MSIE (\d+\.\d+);/.test(ua)) + { this.ie = true; this.ieVersion = parseInt(RegExp.$1, 10); - } else if (/Midori/.test(ua)) { + } + else if (/Midori/.test(ua)) + { this.midori = true; - } else if (/Opera/.test(ua)) { + } + else if (/Opera/.test(ua)) + { this.opera = true; - } else if (/Safari/.test(ua)) { + } + else if (/Safari/.test(ua)) + { this.safari = true; } + else if (/Silk/.test(ua)) + { + this.silk = true; + } + else if (/Trident\/(\d+\.\d+);/.test(ua)) + { + this.ie = true; + this.trident = true; + this.tridentVersion = parseInt(RegExp.$1, 10); + } // WebApp mode in iOS - if (navigator['standalone']) { + if (navigator['standalone']) + { this.webApp = true; } - if (navigator['isCocoonJS']) { + if (navigator['isCocoonJS']) + { this.cocoonJS = true; } + if (typeof window.ejecta !== "undefined") + { + this.ejecta = true; + } + }, /** @@ -23002,6 +25303,13 @@ Phaser.Device.prototype = { this.typedArray = false; } + navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate; + + if (navigator.vibrate) + { + this.vibration = true; + } + }, /** @@ -23024,8 +25332,10 @@ Phaser.Device.prototype = { // Add it to the body to get the computed style. document.body.insertBefore(el, null); - for (var t in transforms) { - if (el.style[t] !== undefined) { + for (var t in transforms) + { + if (el.style[t] !== undefined) + { el.style[t] = "translate3d(1px,1px,1px)"; has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]); } @@ -23100,9 +25410,11 @@ Phaser.Device.prototype = { }; +Phaser.Device.prototype.constructor = Phaser.Device; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -23162,7 +25474,7 @@ Phaser.RequestAnimationFrame = function(game) { Phaser.RequestAnimationFrame.prototype = { /** - * Starts the requestAnimatioFrame running or setTimeout if unavailable in browser + * Starts the requestAnimationFrame running or setTimeout if unavailable in browser * @method Phaser.RequestAnimationFrame#start */ start: function () { @@ -23257,11 +25569,14 @@ Phaser.RequestAnimationFrame.prototype = { } }; + +Phaser.RequestAnimationFrame.prototype.constructor = Phaser.RequestAnimationFrame; + /* jshint noempty: false */ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -23505,9 +25820,11 @@ Phaser.RandomDataGenerator.prototype = { }; +Phaser.RandomDataGenerator.prototype.constructor = Phaser.RandomDataGenerator; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -23834,7 +26151,7 @@ Phaser.Math = { }, /** - * Find the angle of a segment from (x1, y1) -> (x2, y2 ). + * Find the angle of a segment from (x1, y1) -> (x2, y2). * @method Phaser.Math#angleBetween * @param {number} x1 * @param {number} y1 @@ -23847,24 +26164,58 @@ Phaser.Math = { }, /** - * Set an angle within the bounds of -π toπ. - * @method Phaser.Math#normalizeAngle - * @param {number} angle - * @param {boolean} radians - True if angle size is expressed in radians. - * @return {number} + * Reverses an angle. + * @method Phaser.Math#reverseAngle + * @param {number} angleRad - The angle to reverse, in radians. + * @return {number} Returns the reverse angle, in radians. */ - normalizeAngle: function (angle, radians) { + reverseAngle: function (angleRad) { + return this.normalizeAngle(angleRad + Math.PI, true); + }, - if (typeof radians === "undefined") { radians = true; } + /** + * Normalizes an angle to the [0,2pi) range. + * @method Phaser.Math#normalizeAngle + * @param {number} angleRad - The angle to normalize, in radians. + * @return {number} Returns the angle, fit within the [0,2pi] range, in radians. + */ + normalizeAngle: function (angleRad) { - var rd = (radians) ? Math.PI : 180; - return this.wrap(angle, -rd, rd); + angleRad = angleRad % (2 * Math.PI); + return angleRad >= 0 ? angleRad : angleRad + 2 * Math.PI; }, /** - * Closest angle between two angles from a1 to a2 - * absolute value the return for exact angle + * Normalizes a latitude to the [-90,90] range. Latitudes above 90 or below -90 are capped, not wrapped. + * @method Phaser.Math#normalizeLatitude + * @param {number} lat - The latitude to normalize, in degrees. + * @return {number} Returns the latitude, fit within the [-90,90] range. + */ + normalizeLatitude: function (lat) { + return Math.max(-90, Math.min(90, lat)); + }, + + /** + * Normalizes a longitude to the [-180,180] range. Longitudes above 180 or below -180 are wrapped. + * @method Phaser.Math#normalizeLongitude + * @param {number} lng - The longitude to normalize, in degrees. + * @return {number} Returns the longitude, fit within the [-180,180] range. + */ + normalizeLongitude: function (lng) { + + if (lng % 360 == 180) + { + return 180; + } + + lng = lng % 360; + return lng < -180 ? lng + 360 : lng > 180 ? lng - 360 : lng; + + }, + + /** + * Closest angle between two angles from a1 to a2 absolute value the return for exact angle * @method Phaser.Math#nearestAngleBetween * @param {number} a1 * @param {number} a2 @@ -24018,13 +26369,13 @@ Phaser.Math = { /** * Ensures that the value always stays between min and max, by wrapping the value around. - *

max should be larger than min, or the function will return 0

+ * max should be larger than min, or the function will return 0. * * @method Phaser.Math#wrap - * @param value The value to wrap - * @param min The minimum the value is allowed to be - * @param max The maximum the value is allowed to be - * @return {number} The wrapped value + * @param {number} value - The value to wrap. + * @param {number} min - The minimum the value is allowed to be. + * @param {number} max - The maximum the value is allowed to be. + * @return {number} The wrapped value. */ wrap: function (value, min, max) { @@ -24133,7 +26484,7 @@ Phaser.Math = { }, /** - * Significantly faster version of Math.min + * Updated version of Math.min that can be passed either an array of numbers or the numbers as parameters. * See http://jsperf.com/math-s-min-max-vs-homemade/5 * * @method Phaser.Math#min @@ -24141,15 +26492,113 @@ Phaser.Math = { */ min: function () { - for (var i =1 , min = 0, len = arguments.length; i < len; i++) + if (arguments.length === 1 && typeof arguments[0] === 'object') { - if (arguments[i] < arguments[min]) + var data = arguments[0]; + } + else + { + var data = arguments; + } + + for (var i = 1, min = 0, len = data.length; i < len; i++) + { + if (data[i] < data[min]) { min = i; } } - return arguments[min]; + return data[min]; + + }, + + /** + * Updated version of Math.max that can be passed either an array of numbers or the numbers as parameters. + * + * @method Phaser.Math#max + * @return {number} The largest value from those given. + */ + max: function () { + + if (arguments.length === 1 && typeof arguments[0] === 'object') + { + var data = arguments[0]; + } + else + { + var data = arguments; + } + + for (var i = 1, max = 0, len = data.length; i < len; i++) + { + if (data[i] > data[max]) + { + max = i; + } + } + + return data[max]; + + }, + + /** + * Updated version of Math.min that can be passed a property and either an array of objects or the objects as parameters. + * It will find the lowest matching property value from the given objects. + * + * @method Phaser.Math#minProperty + * @return {number} The lowest value from those given. + */ + minProperty: function (property) { + + if (arguments.length === 2 && typeof arguments[1] === 'object') + { + var data = arguments[1]; + } + else + { + var data = arguments.slice(1); + } + + for (var i = 1, min = 0, len = data.length; i < len; i++) + { + if (data[i][property] < data[min][property]) + { + min = i; + } + } + + return data[min][property]; + + }, + + /** + * Updated version of Math.max that can be passed a property and either an array of objects or the objects as parameters. + * It will find the largest matching property value from the given objects. + * + * @method Phaser.Math#maxProperty + * @return {number} The largest value from those given. + */ + maxProperty: function (property) { + + if (arguments.length === 2 && typeof arguments[1] === 'object') + { + var data = arguments[1]; + } + else + { + var data = arguments.slice(1); + } + + for (var i = 1, max = 0, len = data.length; i < len; i++) + { + if (data[i][property] > data[max][property]) + { + max = i; + } + } + + return data[max][property]; }, @@ -24195,7 +26644,7 @@ Phaser.Math = { }, /** - * Description. + * A Linear Interpolation Method, mostly used by Phaser.Tween. * @method Phaser.Math#linearInterpolation * @param {number} v * @param {number} k @@ -24222,7 +26671,7 @@ Phaser.Math = { }, /** - * Description. + * A Bezier Interpolation Method, mostly used by Phaser.Tween. * @method Phaser.Math#bezierInterpolation * @param {number} v * @param {number} k @@ -24243,7 +26692,7 @@ Phaser.Math = { }, /** - * Description. + * A Catmull Rom Interpolation Method, mostly used by Phaser.Tween. * @method Phaser.Math#catmullRomInterpolation * @param {number} v * @param {number} k @@ -24478,7 +26927,7 @@ Phaser.Math = { * @param {number} y1 * @param {number} x2 * @param {number} y2 - * @return {number} The distance between this Point object and the destination Point object. + * @return {number} The distance between the two sets of coordinates. */ distance: function (x1, y1, x2, y2) { @@ -24489,6 +26938,25 @@ Phaser.Math = { }, + /** + * Returns the distance between the two given set of coordinates at the power given. + * + * @method Phaser.Math#distancePow + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @param {number} [pow=2] + * @return {number} The distance between the two sets of coordinates. + */ + distancePow: function (x1, y1, x2, y2, pow) { + + if (typeof pow === 'undefined') { pow = 2; } + + return Math.sqrt(Math.pow(x2 - x1, pow) + Math.pow(y2 - y1, pow)); + + }, + /** * Returns the rounded distance between the two given set of coordinates. * @@ -24676,23 +27144,23 @@ Phaser.Math = { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** - * Javascript QuadTree - * @version 1.0 - * @author Timo Hausmann - * - * @version 1.2, September 4th 2013 - * @author Richard Davey - * The original code was a conversion of the Java code posted to GameDevTuts. However I've tweaked - * it massively to add node indexing, removed lots of temp. var creation and significantly - * increased performance as a result. - * - * Original version at https://github.com/timohausmann/quadtree-js/ - */ +* Javascript QuadTree +* @version 1.0 +* @author Timo Hausmann +* +* @version 1.2, September 4th 2013 +* @author Richard Davey +* The original code was a conversion of the Java code posted to GameDevTuts. However I've tweaked +* it massively to add node indexing, removed lots of temp. var creation and significantly +* increased performance as a result. +* +* Original version at https://github.com/timohausmann/quadtree-js/ +*/ /** * @copyright © 2012 Timo Hausmann @@ -24718,27 +27186,23 @@ Phaser.Math = { */ /** - * QuadTree Constructor - * - * @class Phaser.QuadTree - * @classdesc A QuadTree implementation. The original code was a conversion of the Java code posted to GameDevTuts. However I've tweaked - * it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result. Original version at https://github.com/timohausmann/quadtree-js/ - * @constructor - * @param {Description} physicsManager - Description. - * @param {Description} x - Description. - * @param {Description} y - Description. - * @param {number} width - The width of your game in game pixels. - * @param {number} height - The height of your game in game pixels. - * @param {number} maxObjects - Description. - * @param {number} maxLevels - Description. - * @param {number} level - Description. - */ -Phaser.QuadTree = function (physicsManager, x, y, width, height, maxObjects, maxLevels, level) { +* QuadTree Constructor +* +* @class Phaser.QuadTree +* @classdesc A QuadTree implementation. The original code was a conversion of the Java code posted to GameDevTuts. +* However I've tweaked it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result. +* Original version at https://github.com/timohausmann/quadtree-js/ +* @constructor +* @param {number} x - The top left coordinate of the quadtree. +* @param {number} y - The top left coordinate of the quadtree. +* @param {number} width - The width of the quadtree in pixels. +* @param {number} height - The height of the quadtree in pixels. +* @param {number} [maxObjects=10] - The maximum number of objects per node. +* @param {number} [maxLevels=4] - The maximum number of levels to iterate to. +* @param {number} [level=0] - Which level is this? +*/ +Phaser.QuadTree = function (x, y, width, height, maxObjects, maxLevels, level) { - this.physicsManager = physicsManager; - this.ID = physicsManager.quadTreeID; - physicsManager.quadTreeID++; - this.maxObjects = maxObjects || 10; this.maxLevels = maxLevels || 4; this.level = level || 0; @@ -24762,35 +27226,60 @@ Phaser.QuadTree = function (physicsManager, x, y, width, height, maxObjects, max Phaser.QuadTree.prototype = { /* - * Split the node into 4 subnodes + * Populates this quadtree with the members of the given Group. * - * @method Phaser.QuadTree#split + * @method Phaser.QuadTree#populate + * @param {Phaser.Group} group - The Group to add to the quadtree. */ - split: function() { + populate: function (group) { - this.level++; - - // top right node - this.nodes[0] = new Phaser.QuadTree(this.physicsManager, this.bounds.right, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); - - // top left node - this.nodes[1] = new Phaser.QuadTree(this.physicsManager, this.bounds.x, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); - - // bottom left node - this.nodes[2] = new Phaser.QuadTree(this.physicsManager, this.bounds.x, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); - - // bottom right node - this.nodes[3] = new Phaser.QuadTree(this.physicsManager, this.bounds.right, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); + group.forEach(this.populateHandler, this, true); }, /* - * Insert the object into the node. If the node - * exceeds the capacity, it will split and add all - * objects to their corresponding subnodes. + * Handler for the populate method. + * + * @method Phaser.QuadTree#populateHandler + * @param {Phaser.Sprite} sprite - The Sprite to check. + */ + populateHandler: function (sprite) { + + if (sprite.body && sprite.body.checkCollision.none === false && sprite.alive) + { + this.insert(sprite.body); + } + + }, + + /* + * Split the node into 4 subnodes + * + * @method Phaser.QuadTree#split + */ + split: function () { + + this.level++; + + // top right node + this.nodes[0] = new Phaser.QuadTree(this.bounds.right, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); + + // top left node + this.nodes[1] = new Phaser.QuadTree(this.bounds.x, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); + + // bottom left node + this.nodes[2] = new Phaser.QuadTree(this.bounds.x, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); + + // bottom right node + this.nodes[3] = new Phaser.QuadTree(this.bounds.right, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); + + }, + + /* + * Insert the object into the node. If the node exceeds the capacity, it will split and add all objects to their corresponding subnodes. * * @method Phaser.QuadTree#insert - * @param {object} body - Description. + * @param {Phaser.Physics.Arcade.Body|object} body - The Body object to insert into the quadtree. */ insert: function (body) { @@ -24842,7 +27331,7 @@ Phaser.QuadTree.prototype = { * Determine which node the object belongs to. * * @method Phaser.QuadTree#getIndex - * @param {object} rect - Description. + * @param {Phaser.Rectangle|object} rect - The bounds in which to check. * @return {number} index - Index of the subnode (0-3), or -1 if rect cannot completely fit within a subnode and is part of the parent node. */ getIndex: function (rect) { @@ -24882,12 +27371,12 @@ Phaser.QuadTree.prototype = { }, - /* - * Return all objects that could collide with the given object. + /* + * Return all objects that could collide with the given Sprite. * * @method Phaser.QuadTree#retrieve - * @param {object} rect - Description. - * @Return {array} - Array with all detected objects. + * @param {Phaser.Sprite} sprite - The sprite to check against. + * @return {array} - Array with all detected objects. */ retrieve: function (sprite) { @@ -24896,7 +27385,7 @@ Phaser.QuadTree.prototype = { sprite.body.quadTreeIndex = this.getIndex(sprite.body); // Temp store for the node IDs this sprite is in, we can use this for fast elimination later - sprite.body.quadTreeIDs.push(this.ID); + // sprite.body.quadTreeIDs.push(this.ID); if (this.nodes[0]) { @@ -24929,7 +27418,6 @@ Phaser.QuadTree.prototype = { for (var i = 0, len = this.nodes.length; i < len; i++) { - // if (typeof this.nodes[i] !== 'undefined') if (this.nodes[i]) { this.nodes[i].clear(); @@ -24940,9 +27428,11 @@ Phaser.QuadTree.prototype = { }; +Phaser.QuadTree.prototype.constructor = Phaser.QuadTree; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -24951,9 +27441,9 @@ Phaser.QuadTree.prototype = { * @class Circle * @classdesc Phaser - Circle * @constructor -* @param {number} [x] The x coordinate of the center of the circle. -* @param {number} [y] The y coordinate of the center of the circle. -* @param {number} [diameter] The diameter of the circle. +* @param {number} [x=0] - The x coordinate of the center of the circle. +* @param {number} [y=0] - The y coordinate of the center of the circle. +* @param {number} [diameter=0] - The diameter of the circle. * @return {Phaser.Circle} This circle object */ Phaser.Circle = function (x, y, diameter) { @@ -25137,6 +27627,8 @@ Phaser.Circle.prototype = { }; +Phaser.Circle.prototype.constructor = Phaser.Circle; + /** * The largest distance between any two points on the circle. The same as the radius * 2. * @name Phaser.Circle#diameter @@ -25418,7 +27910,7 @@ Phaser.Circle.intersectsRectangle = function (c, r) { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -25706,6 +28198,8 @@ Phaser.Point.prototype = { }; +Phaser.Point.prototype.constructor = Phaser.Point; + /** * Adds the coordinates of two points together to create a new point. * @method Phaser.Point.add @@ -25849,7 +28343,7 @@ Phaser.Point.rotate = function (a, x, y, angle, asDegrees, distance) { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -26115,6 +28609,8 @@ Phaser.Rectangle.prototype = { }; +Phaser.Rectangle.prototype.constructor = Phaser.Rectangle; + /** * @name Phaser.Rectangle#halfWidth * @property {number} halfWidth - Half of the width of the Rectangle. @@ -26493,12 +28989,12 @@ Phaser.Rectangle.intersection = function (a, b, out) { */ Phaser.Rectangle.intersects = function (a, b) { - return (a.x < b.right && b.x < a.right && a.y < b.bottom && b.y < a.bottom); + if (a.width <= 0 || a.height <= 0 || b.width <= 0 || b.height <= 0) + { + return false; + } - // return (a.x <= b.right && b.x <= a.right && a.y <= b.bottom && b.y <= a.bottom); - - // return (a.left <= b.right && b.left <= a.right && a.top <= b.bottom && b.top <= a.bottom); - // return !(a.x > b.right + tolerance || a.right < b.x - tolerance || a.y > b.bottom + tolerance || a.bottom < b.y - tolerance); + return !(a.right < b.x || a.bottom < b.y || a.x > b.right || a.y > b.bottom); }; @@ -26538,7 +29034,7 @@ Phaser.Rectangle.union = function (a, b, out) { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -26568,7 +29064,7 @@ Phaser.Polygon.prototype = Object.create(PIXI.Polygon.prototype); Phaser.Polygon.prototype.constructor = Phaser.Polygon; /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -26696,8 +29192,8 @@ Phaser.Net.prototype = { var output = {}; var keyValues = location.search.substring(1).split('&'); - for (var i in keyValues) { - + for (var i in keyValues) + { var key = keyValues[i].split('='); if (key.length > 1) @@ -26731,9 +29227,11 @@ Phaser.Net.prototype = { }; +Phaser.Net.prototype.constructor = Phaser.Net; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -26761,13 +29259,13 @@ Phaser.TweenManager = function (game) { this.game = game; /** - * @property {array} _tweens - Description. + * @property {array} _tweens - All of the currently running tweens. * @private */ this._tweens = []; /** - * @property {array} _add - Description. + * @property {array} _add - All of the tweens queued to be added in the next update. * @private */ this._add = []; @@ -26779,13 +29277,6 @@ Phaser.TweenManager = function (game) { Phaser.TweenManager.prototype = { - /** - * Version number of this library. - * @property {string} REVISION - * @default - */ - REVISION: '11dev', - /** * Get all the tween objects in an array. * @method Phaser.TweenManager#getAll @@ -26798,12 +29289,17 @@ Phaser.TweenManager.prototype = { }, /** - * Remove all tween objects. + * Remove all tweens running and in the queue. Doesn't call any of the tween onComplete events. * @method Phaser.TweenManager#removeAll */ removeAll: function () { - this._tweens = []; + for (var i = 0; i < this._tweens.length; i++) + { + this._tweens[i].pendingDelete = true; + } + + this._add = []; }, @@ -26814,9 +29310,9 @@ Phaser.TweenManager.prototype = { * @param {Phaser.Tween} tween - The tween object you want to add. * @returns {Phaser.Tween} The tween object you added to the manager. */ - add: function ( tween ) { + add: function (tween) { - this._add.push( tween ); + this._add.push(tween); }, @@ -26839,14 +29335,13 @@ Phaser.TweenManager.prototype = { * @method Phaser.TweenManager#remove * @param {Phaser.Tween} tween - The tween object you want to remove. */ - remove: function ( tween ) { + remove: function (tween) { - var i = this._tweens.indexOf( tween ); - - if ( i !== -1 ) { + var i = this._tweens.indexOf(tween); + if (i !== -1) + { this._tweens[i].pendingDelete = true; - } }, @@ -26859,7 +29354,7 @@ Phaser.TweenManager.prototype = { */ update: function () { - if ( this._tweens.length === 0 && this._add.length === 0 ) + if (this._tweens.length === 0 && this._add.length === 0) { return false; } @@ -26867,20 +29362,18 @@ Phaser.TweenManager.prototype = { var i = 0; var numTweens = this._tweens.length; - while ( i < numTweens ) { - - if ( this._tweens[ i ].update( this.game.time.now ) ) { - + while (i < numTweens) + { + if (this._tweens[i].update(this.game.time.now)) + { i++; - - } else { - - this._tweens.splice( i, 1 ); + } + else + { + this._tweens.splice(i, 1); numTweens--; - } - } // If there are any new tweens to be added, do so now - otherwise they can be spliced out of the array before ever running @@ -26916,7 +29409,8 @@ Phaser.TweenManager.prototype = { */ pauseAll: function () { - for (var i = this._tweens.length - 1; i >= 0; i--) { + for (var i = this._tweens.length - 1; i >= 0; i--) + { this._tweens[i].pause(); } @@ -26929,16 +29423,20 @@ Phaser.TweenManager.prototype = { */ resumeAll: function () { - for (var i = this._tweens.length - 1; i >= 0; i--) { + for (var i = this._tweens.length - 1; i >= 0; i--) + { this._tweens[i].resume(); } } }; + +Phaser.TweenManager.prototype.constructor = Phaser.TweenManager; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -26966,119 +29464,112 @@ Phaser.Tween = function (object, game) { this.game = game; /** - * @property {object} _manager - Description. + * @property {Phaser.TweenManager} _manager - Reference to the TweenManager. * @private */ this._manager = this.game.tweens; /** - * @property {object} _valuesStart - Description. + * @property {object} _valuesStart - Private value object. * @private */ this._valuesStart = {}; /** - * @property {object} _valuesEnd - Description. + * @property {object} _valuesEnd - Private value object. * @private */ this._valuesEnd = {}; /** - * @property {object} _valuesStartRepeat - Description. + * @property {object} _valuesStartRepeat - Private value object. * @private */ this._valuesStartRepeat = {}; /** - * @property {number} _duration - Description. + * @property {number} _duration - Private duration counter. * @private * @default */ this._duration = 1000; /** - * @property {number} _repeat - Description. + * @property {number} _repeat - Private repeat counter. * @private * @default */ this._repeat = 0; /** - * @property {boolean} _yoyo - Description. + * @property {boolean} _yoyo - Private yoyo flag. * @private * @default */ this._yoyo = false; /** - * @property {boolean} _reversed - Description. + * @property {boolean} _reversed - Private reversed flag. * @private * @default */ this._reversed = false; /** - * @property {number} _delayTime - Description. + * @property {number} _delayTime - Private delay counter. * @private * @default */ this._delayTime = 0; /** - * @property {Description} _startTime - Description. + * @property {number} _startTime - Private start time counter. * @private * @default null */ this._startTime = null; /** - * @property {Description} _easingFunction - Description. + * @property {function} _easingFunction - The easing function used for the tween. * @private */ this._easingFunction = Phaser.Easing.Linear.None; /** - * @property {Description} _interpolationFunction - Description. + * @property {function} _interpolationFunction - The interpolation function used for the tween. * @private */ this._interpolationFunction = Phaser.Math.linearInterpolation; /** - * @property {Description} _chainedTweens - Description. + * @property {array} _chainedTweens - A private array of chained tweens. * @private */ this._chainedTweens = []; /** - * @property {Description} _onStartCallback - Description. - * @private - * @default - */ - this._onStartCallback = null; - - /** - * @property {boolean} _onStartCallbackFired - Description. + * @property {boolean} _onStartCallbackFired - Private flag. * @private * @default */ this._onStartCallbackFired = false; /** - * @property {Description} _onUpdateCallback - Description. + * @property {function} _onUpdateCallback - An onUpdate callback. * @private * @default null */ this._onUpdateCallback = null; - + /** - * @property {Description} _onCompleteCallback - Description. + * @property {object} _onUpdateCallbackContext - The context in which to call the onUpdate callback. * @private * @default null */ - this._onCompleteCallback = null; - + this._onUpdateCallbackContext = null; + /** - * @property {number} _pausedTime - Description. + * @property {number} _pausedTime - Private pause timer. * @private * @default */ @@ -27091,22 +29582,28 @@ Phaser.Tween = function (object, game) { this.pendingDelete = false; // Set all starting values present on the target object - for ( var field in object ) { - this._valuesStart[ field ] = parseFloat(object[field], 10); + for (var field in object) + { + this._valuesStart[field] = parseFloat(object[field], 10); } /** - * @property {Phaser.Signal} onStart - Description. + * @property {Phaser.Signal} onStart - The onStart event is fired when the Tween begins. */ this.onStart = new Phaser.Signal(); /** - * @property {Phaser.Signal} onComplete - Description. + * @property {Phaser.Signal} onLoop - The onLoop event is fired if the Tween loops. + */ + this.onLoop = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onComplete - The onComplete event is fired when the Tween completes. Does not fire if the Tween is set to loop. */ this.onComplete = new Phaser.Signal(); /** - * @property {boolean} isRunning - Description. + * @property {boolean} isRunning - If the tween is running this is set to true, otherwise false. Tweens that are in a delayed state, waiting to start, are considered as being running. * @default */ this.isRunning = false; @@ -27120,15 +29617,15 @@ Phaser.Tween.prototype = { * * @method Phaser.Tween#to * @param {object} properties - Properties you want to tween. - * @param {number} duration - Duration of this tween. - * @param {function} ease - Easing function. - * @param {boolean} autoStart - Whether this tween will start automatically or not. - * @param {number} delay - Delay before this tween will start, defaults to 0 (no delay). - * @param {boolean} repeat - Should the tween automatically restart once complete? (ignores any chained tweens). - * @param {Phaser.Tween} yoyo - Description. - * @return {Phaser.Tween} Itself. + * @param {number} [duration=1000] - Duration of this tween in ms. + * @param {function} [ease=null] - Easing function. If not set it will default to Phaser.Easing.Linear.None. + * @param {boolean} [autoStart=false] - Whether this tween will start automatically or not. + * @param {number} [delay=0] - Delay before this tween will start, defaults to 0 (no delay). Value given is in ms. + * @param {boolean} [repeat=0] - Should the tween automatically restart once complete? (ignores any chained tweens). + * @param {boolean} [yoyo=false] - A tween that yoyos will reverse itself when it completes. + * @return {Phaser.Tween} This Tween object. */ - to: function ( properties, duration, ease, autoStart, delay, repeat, yoyo ) { + to: function (properties, duration, ease, autoStart, delay, repeat, yoyo) { duration = duration || 1000; ease = ease || null; @@ -27138,6 +29635,7 @@ Phaser.Tween.prototype = { yoyo = yoyo || false; var self; + if (this._parent) { self = this._manager.create(this._object); @@ -27167,9 +29665,12 @@ Phaser.Tween.prototype = { self._yoyo = yoyo; - if (autoStart) { + if (autoStart) + { return this.start(); - } else { + } + else + { return this; } @@ -27183,43 +29684,41 @@ Phaser.Tween.prototype = { */ start: function () { - if (this.game === null || this._object === null) { + if (this.game === null || this._object === null) + { return; } this._manager.add(this); - this.onStart.dispatch(this._object); - this.isRunning = true; this._onStartCallbackFired = false; this._startTime = this.game.time.now + this._delayTime; - for ( var property in this._valuesEnd ) { - + for (var property in this._valuesEnd) + { // check if an Array was provided as property value - if ( this._valuesEnd[ property ] instanceof Array ) { - - if ( this._valuesEnd[ property ].length === 0 ) { - + if (this._valuesEnd[property] instanceof Array) + { + if (this._valuesEnd[property].length === 0) + { continue; - } // create a local copy of the Array with the start value at the front - this._valuesEnd[ property ] = [ this._object[ property ] ].concat( this._valuesEnd[ property ] ); - + this._valuesEnd[property] = [this._object[property]].concat(this._valuesEnd[property]); } - this._valuesStart[ property ] = this._object[ property ]; + this._valuesStart[property] = this._object[property]; - if ( ( this._valuesStart[ property ] instanceof Array ) === false ) { - this._valuesStart[ property ] *= 1.0; // Ensures we're using numbers, not strings + if ((this._valuesStart[property] instanceof Array) === false) + { + this._valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings } - this._valuesStartRepeat[ property ] = this._valuesStart[ property ] || 0; + this._valuesStartRepeat[property] = this._valuesStart[property] || 0; } @@ -27237,6 +29736,8 @@ Phaser.Tween.prototype = { this.isRunning = false; + this._onUpdateCallback = null; + this._manager.remove(this); return this; @@ -27250,7 +29751,7 @@ Phaser.Tween.prototype = { * @param {number} amount - The amount of the delay in ms. * @return {Phaser.Tween} Itself. */ - delay: function ( amount ) { + delay: function (amount) { this._delayTime = amount; return this; @@ -27264,7 +29765,7 @@ Phaser.Tween.prototype = { * @param {number} times - How many times to repeat. * @return {Phaser.Tween} Itself. */ - repeat: function ( times ) { + repeat: function (times) { this._repeat = times; return this; @@ -27279,7 +29780,7 @@ Phaser.Tween.prototype = { * @param {boolean} yoyo - Set to true to yoyo this tween. * @return {Phaser.Tween} Itself. */ - yoyo: function( yoyo ) { + yoyo: function(yoyo) { this._yoyo = yoyo; return this; @@ -27293,7 +29794,7 @@ Phaser.Tween.prototype = { * @param {function} easing - The easing function this tween will use, i.e. Phaser.Easing.Linear.None. * @return {Phaser.Tween} Itself. */ - easing: function ( easing ) { + easing: function (easing) { this._easingFunction = easing; return this; @@ -27302,12 +29803,13 @@ Phaser.Tween.prototype = { /** * Set interpolation function the tween will use, by default it uses Phaser.Math.linearInterpolation. + * Also available: Phaser.Math.bezierInterpolation and Phaser.Math.catmullRomInterpolation. * * @method Phaser.Tween#interpolation * @param {function} interpolation - The interpolation function to use (Phaser.Math.linearInterpolation by default) * @return {Phaser.Tween} Itself. */ - interpolation: function ( interpolation ) { + interpolation: function (interpolation) { this._interpolationFunction = interpolation; return this; @@ -27347,20 +29849,6 @@ Phaser.Tween.prototype = { }, - /** - * Sets a callback to be fired when the tween starts. Note: callback will be called in the context of the global scope. - * - * @method Phaser.Tween#onStartCallback - * @param {function} callback - The callback to invoke on start. - * @return {Phaser.Tween} Itself. - */ - onStartCallback: function ( callback ) { - - this._onStartCallback = callback; - return this; - - }, - /** * Sets a callback to be fired each time this tween updates. Note: callback will be called in the context of the global scope. * @@ -27368,23 +29856,11 @@ Phaser.Tween.prototype = { * @param {function} callback - The callback to invoke each time this tween is updated. * @return {Phaser.Tween} Itself. */ - onUpdateCallback: function ( callback ) { + onUpdateCallback: function (callback, callbackContext) { this._onUpdateCallback = callback; - return this; + this._onUpdateCallbackContext = callbackContext; - }, - - /** - * Sets a callback to be fired when the tween completes. Note: callback will be called in the context of the global scope. - * - * @method Phaser.Tween#onCompleteCallback - * @param {function} callback - The callback to invoke on completion. - * @return {Phaser.Tween} Itself. - */ - onCompleteCallback: function ( callback ) { - - this._onCompleteCallback = callback; return this; }, @@ -27395,8 +29871,10 @@ Phaser.Tween.prototype = { * @method Phaser.Tween#pause */ pause: function () { + this._paused = true; this._pausedTime = this.game.time.now; + }, /** @@ -27405,8 +29883,10 @@ Phaser.Tween.prototype = { * @method Phaser.Tween#resume */ resume: function () { + this._paused = false; this._startTime += (this.game.time.now - this._pausedTime); + }, /** @@ -27416,127 +29896,112 @@ Phaser.Tween.prototype = { * @param {number} time - A timestamp passed in by the TweenManager. * @return {boolean} false if the tween has completed and should be deleted from the manager, otherwise true (still active). */ - update: function ( time ) { + update: function (time) { if (this.pendingDelete) { return false; } - if (this._paused || time < this._startTime) { - + if (this._paused || time < this._startTime) + { return true; - } var property; - if ( time < this._startTime ) { - + if (time < this._startTime) + { return true; - } - if ( this._onStartCallbackFired === false ) { - - if ( this._onStartCallback !== null ) { - - this._onStartCallback.call( this._object ); - - } - + if (this._onStartCallbackFired === false) + { + this.onStart.dispatch(this._object); this._onStartCallbackFired = true; - } - var elapsed = ( time - this._startTime ) / this._duration; + var elapsed = (time - this._startTime) / this._duration; elapsed = elapsed > 1 ? 1 : elapsed; - var value = this._easingFunction( elapsed ); + var value = this._easingFunction(elapsed); - for ( property in this._valuesEnd ) { - - var start = this._valuesStart[ property ] || 0; - var end = this._valuesEnd[ property ]; - - if ( end instanceof Array ) { - - this._object[ property ] = this._interpolationFunction( end, value ); - - } else { + for (property in this._valuesEnd) + { + var start = this._valuesStart[property] || 0; + var end = this._valuesEnd[property]; + if (end instanceof Array) + { + this._object[property] = this._interpolationFunction(end, value); + } + else + { // Parses relative end values with start as base (e.g.: +10, -3) - if ( typeof(end) === "string" ) { + if (typeof(end) === 'string') + { end = start + parseFloat(end, 10); } // protect against non numeric properties. - if ( typeof(end) === "number" ) { - this._object[ property ] = start + ( end - start ) * value; + if (typeof(end) === 'number') + { + this._object[property] = start + ( end - start ) * value; } - } - } - if ( this._onUpdateCallback !== null ) { - - this._onUpdateCallback.call( this._object, value ); - + if (this._onUpdateCallback !== null) + { + this._onUpdateCallback.call(this._onUpdateCallbackContext, this, value); } - if ( elapsed == 1 ) { - - if ( this._repeat > 0 ) { - - if ( isFinite( this._repeat ) ) { + if (elapsed == 1) + { + if (this._repeat > 0) + { + if (isFinite(this._repeat)) + { this._repeat--; } // reassign starting values, restart by making startTime = now - for ( property in this._valuesStartRepeat ) { - - if ( typeof( this._valuesEnd[ property ] ) === "string" ) { - this._valuesStartRepeat[ property ] = this._valuesStartRepeat[ property ] + parseFloat(this._valuesEnd[ property ], 10); + for (property in this._valuesStartRepeat) + { + if (typeof(this._valuesEnd[property]) === 'string') + { + this._valuesStartRepeat[property] = this._valuesStartRepeat[property] + parseFloat(this._valuesEnd[property], 10); } - if (this._yoyo) { - var tmp = this._valuesStartRepeat[ property ]; - this._valuesStartRepeat[ property ] = this._valuesEnd[ property ]; - this._valuesEnd[ property ] = tmp; + if (this._yoyo) + { + var tmp = this._valuesStartRepeat[property]; + this._valuesStartRepeat[property] = this._valuesEnd[property]; + this._valuesEnd[property] = tmp; this._reversed = !this._reversed; } - this._valuesStart[ property ] = this._valuesStartRepeat[ property ]; + this._valuesStart[property] = this._valuesStartRepeat[property]; } this._startTime = time + this._delayTime; - this.onComplete.dispatch(this._object); - - if ( this._onCompleteCallback !== null ) { - this._onCompleteCallback.call( this._object ); - } + this.onLoop.dispatch(this._object); return true; - } else { - + } + else + { this.isRunning = false; this.onComplete.dispatch(this._object); - if ( this._onCompleteCallback !== null ) { - this._onCompleteCallback.call( this._object ); - } - - for ( var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i ++ ) { - - this._chainedTweens[ i ].start( time ); - + for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i ++) + { + this._chainedTweens[i].start(time); } return false; - } } @@ -27547,11 +30012,13 @@ Phaser.Tween.prototype = { }; +Phaser.Tween.prototype.constructor = Phaser.Tween; + /* jshint curly: false */ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -28113,7 +30580,7 @@ Phaser.Easing = { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -28127,243 +30594,358 @@ Phaser.Easing = { */ Phaser.Time = function (game) { - /** - * @property {Phaser.Game} game - Local reference to game. - */ - this.game = game; + /** + * @property {Phaser.Game} game - Local reference to game. + */ + this.game = game; - /** - * @property {number} _started - The time at which the Game instance started. - * @private - */ - this._started = 0; + /** + * @property {number} time - Game time counter. If you need a value for in-game calculation please use Phaser.Time.now instead. + * @protected + */ + this.time = 0; - /** - * @property {number} _timeLastSecond - The time (in ms) that the last second counter ticked over. - * @private - */ - this._timeLastSecond = 0; + /** + * @property {number} now - The time right now. + * @protected + */ + this.now = 0; - /** - * @property {number} _pauseStarted - The time the game started being paused. - * @private - */ - this._pauseStarted = 0; + /** + * @property {number} elapsed - Elapsed time since the last frame (in ms). + * @protected + */ + this.elapsed = 0; - /** - * @property {number} physicsElapsed - The elapsed time calculated for the physics motion updates. - */ - this.physicsElapsed = 0; + /** + * @property {number} pausedTime - Records how long the game has been paused for. Is reset each time the game pauses. + * @protected + */ + this.pausedTime = 0; - /** - * @property {number} time - Game time counter. - */ - this.time = 0; + /** + * @property {number} fps - Frames per second. + * @protected + */ + this.fps = 0; - /** - * @property {number} pausedTime - Records how long the game has been paused for. Is reset each time the game pauses. - */ - this.pausedTime = 0; + /** + * @property {number} fpsMin - The lowest rate the fps has dropped to. + */ + this.fpsMin = 1000; - /** - * @property {number} now - The time right now. - */ - this.now = 0; + /** + * @property {number} fpsMax - The highest rate the fps has reached (usually no higher than 60fps). + */ + this.fpsMax = 0; - /** - * @property {number} elapsed - Elapsed time since the last frame. - */ - this.elapsed = 0; + /** + * @property {number} msMin - The minimum amount of time the game has taken between two frames. + * @default + */ + this.msMin = 1000; - /** - * @property {number} fps - Frames per second. - */ - this.fps = 0; + /** + * @property {number} msMax - The maximum amount of time the game has taken between two frames. + */ + this.msMax = 0; - /** - * @property {number} fpsMin - The lowest rate the fps has dropped to. - */ - this.fpsMin = 1000; + /** + * @property {number} physicsElapsed - The elapsed time calculated for the physics motion updates. + */ + this.physicsElapsed = 0; - /** - * @property {number} fpsMax - The highest rate the fps has reached (usually no higher than 60fps). - */ - this.fpsMax = 0; + /** + * @property {number} frames - The number of frames record in the last second. + */ + this.frames = 0; - /** - * @property {number} msMin - The minimum amount of time the game has taken between two frames. - * @default - */ - this.msMin = 1000; + /** + * @property {number} pauseDuration - Records how long the game was paused for in miliseconds. + */ + this.pauseDuration = 0; - /** - * @property {number} msMax - The maximum amount of time the game has taken between two frames. - */ - this.msMax = 0; + /** + * @property {number} timeToCall - The value that setTimeout needs to work out when to next update + */ + this.timeToCall = 0; - /** - * @property {number} frames - The number of frames record in the last second. - */ - this.frames = 0; + /** + * @property {number} lastTime - Internal value used by timeToCall as part of the setTimeout loop + */ + this.lastTime = 0; - /** - * @property {number} pauseDuration - Records how long the game was paused for in miliseconds. - */ - this.pauseDuration = 0; + /** + * @property {Phaser.Timer} events - This is a Phaser.Timer object bound to the master clock to which you can add timed events. + */ + this.events = new Phaser.Timer(this.game, false); - /** - * @property {number} timeToCall - The value that setTimeout needs to work out when to next update - */ - this.timeToCall = 0; - - /** - * @property {number} lastTime - Internal value used by timeToCall as part of the setTimeout loop - */ - this.lastTime = 0; - - // Listen for game pause/resume events - this.game.onPause.add(this.gamePaused, this); - this.game.onResume.add(this.gameResumed, this); - - /** - * @property {boolean} _justResumed - Internal value used to recover from the game pause state. + /** + * @property {number} _started - The time at which the Game instance started. * @private - */ - this._justResumed = false; + */ + this._started = 0; + + /** + * @property {number} _timeLastSecond - The time (in ms) that the last second counter ticked over. + * @private + */ + this._timeLastSecond = 0; + + /** + * @property {number} _pauseStarted - The time the game started being paused. + * @private + */ + this._pauseStarted = 0; + + /** + * @property {boolean} _justResumed - Internal value used to recover from the game pause state. + * @private + */ + this._justResumed = false; + + /** + * @property {array} _timers - Internal store of Phaser.Timer objects. + * @private + */ + this._timers = []; + + /** + * @property {number} _len - Temp. array length variable. + * @private + */ + this._len = 0; + + /** + * @property {number} _i - Temp. array counter variable. + * @private + */ + this._i = 0; + + // Listen for game pause/resume events + this.game.onPause.add(this.gamePaused, this); + this.game.onResume.add(this.gameResumed, this); }; Phaser.Time.prototype = { - /** - * Updates the game clock and calculate the fps. This is called automatically by Phaser.Game. - * @method Phaser.Time#update - * @param {number} time - The current timestamp, either performance.now or Date.now depending on the browser. - */ - update: function (time) { + /** + * @method Phaser.Time#boot + */ + boot: function () { - this.now = time; + this.events.start(); - if (this._justResumed) - { - this.time = this.now; - this._justResumed = false; - } + }, - this.timeToCall = this.game.math.max(0, 16 - (time - this.lastTime)); + /** + * Creates a new stand-alone Phaser.Timer object. + * @method Phaser.Time#create + * @param {boolean} [autoDestroy=true] - A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events). + * @return {Phaser.Timer} The Timer object that was created. + */ + create: function (autoDestroy) { - this.elapsed = this.now - this.time; + if (typeof autoDestroy === 'undefined') { autoDestroy = true; } - this.msMin = this.game.math.min(this.msMin, this.elapsed); - this.msMax = this.game.math.max(this.msMax, this.elapsed); + var timer = new Phaser.Timer(this.game, autoDestroy); - this.frames++; + this._timers.push(timer); - if (this.now > this._timeLastSecond + 1000) - { - this.fps = Math.round((this.frames * 1000) / (this.now - this._timeLastSecond)); - this.fpsMin = this.game.math.min(this.fpsMin, this.fps); - this.fpsMax = this.game.math.max(this.fpsMax, this.fps); - this._timeLastSecond = this.now; - this.frames = 0; - } + return timer; - this.time = this.now; + }, + + /** + * Remove all Timer objects, regardless of their state. + * @method Phaser.Time#removeAll + */ + removeAll: function () { + + for (var i = 0; i < this._timers.length; i++) + { + this._timers[i].destroy(); + } + + this._timers = []; + + }, + + /** + * Updates the game clock and calculate the fps. This is called automatically by Phaser.Game. + * @method Phaser.Time#update + * @param {number} time - The current timestamp, either performance.now or Date.now depending on the browser. + */ + update: function (time) { + + this.now = time; + + if (this._justResumed) + { + this.time = this.now; + this._justResumed = false; + + this.events.resume(); + + for (var i = 0; i < this._timers.length; i++) + { + this._timers[i].resume(); + } + } + + this.timeToCall = this.game.math.max(0, 16 - (time - this.lastTime)); + + this.elapsed = this.now - this.time; + + this.msMin = this.game.math.min(this.msMin, this.elapsed); + this.msMax = this.game.math.max(this.msMax, this.elapsed); + + this.frames++; + + if (this.now > this._timeLastSecond + 1000) + { + this.fps = Math.round((this.frames * 1000) / (this.now - this._timeLastSecond)); + this.fpsMin = this.game.math.min(this.fpsMin, this.fps); + this.fpsMax = this.game.math.max(this.fpsMax, this.fps); + this._timeLastSecond = this.now; + this.frames = 0; + } + + this.time = this.now; this.lastTime = time + this.timeToCall; - this.physicsElapsed = 1.0 * (this.elapsed / 1000); + this.physicsElapsed = 1.0 * (this.elapsed / 1000); - // Clamp the delta - if (this.physicsElapsed > 1) - { - this.physicsElapsed = 1; - } + // Clamp the delta + if (this.physicsElapsed > 0.05) + { + this.physicsElapsed = 0.05; + } - // Paused? - if (this.game.paused) - { - this.pausedTime = this.now - this._pauseStarted; - } + // Paused? + if (this.game.paused) + { + this.pausedTime = this.now - this._pauseStarted; + } + else + { + // Our internal Phaser.Timer + this.events.update(this.now); - }, + // Any game level timers + this._i = 0; + this._len = this._timers.length; - /** - * Called when the game enters a paused state. - * @method Phaser.Time#gamePaused - * @private - */ - gamePaused: function () { - - this._pauseStarted = this.now; + while (this._i < this._len) + { + if (this._timers[this._i].update(this.now)) + { + this._i++; + } + else + { + this._timers.splice(this._i, 1); - }, + this._len--; + } + } + } - /** - * Called when the game resumes from a paused state. - * @method Phaser.Time#gameResumed - * @private - */ - gameResumed: function () { + }, - // Level out the elapsed timer to avoid spikes - this.time = Date.now(); - this.pauseDuration = this.pausedTime; - this._justResumed = true; + /** + * Called when the game enters a paused state. + * @method Phaser.Time#gamePaused + * @private + */ + gamePaused: function () { + + this._pauseStarted = this.now; - }, + this.events.pause(); - /** - * The number of seconds that have elapsed since the game was started. - * @method Phaser.Time#totalElapsedSeconds - * @return {number} - */ - totalElapsedSeconds: function() { - return (this.now - this._started) * 0.001; - }, + for (var i = 0; i < this._timers.length; i++) + { + this._timers[i].pause(); + } - /** - * How long has passed since the given time. - * @method Phaser.Time#elapsedSince - * @param {number} since - The time you want to measure against. - * @return {number} The difference between the given time and now. - */ - elapsedSince: function (since) { - return this.now - since; - }, + }, - /** - * How long has passed since the given time (in seconds). - * @method Phaser.Time#elapsedSecondsSince - * @param {number} since - The time you want to measure (in seconds). - * @return {number} Duration between given time and now (in seconds). - */ - elapsedSecondsSince: function (since) { - return (this.now - since) * 0.001; - }, + /** + * Called when the game resumes from a paused state. + * @method Phaser.Time#gameResumed + * @private + */ + gameResumed: function () { - /** - * Resets the private _started value to now. - * @method Phaser.Time#reset - */ - reset: function () { - this._started = this.now; - } + // Level out the elapsed timer to avoid spikes + this.time = Date.now(); + this.pauseDuration = this.pausedTime; + this._justResumed = true; + + }, + + /** + * The number of seconds that have elapsed since the game was started. + * @method Phaser.Time#totalElapsedSeconds + * @return {number} + */ + totalElapsedSeconds: function() { + return (this.now - this._started) * 0.001; + }, + + /** + * How long has passed since the given time. + * @method Phaser.Time#elapsedSince + * @param {number} since - The time you want to measure against. + * @return {number} The difference between the given time and now. + */ + elapsedSince: function (since) { + return this.now - since; + }, + + /** + * How long has passed since the given time (in seconds). + * @method Phaser.Time#elapsedSecondsSince + * @param {number} since - The time you want to measure (in seconds). + * @return {number} Duration between given time and now (in seconds). + */ + elapsedSecondsSince: function (since) { + return (this.now - since) * 0.001; + }, + + /** + * Resets the private _started value to now. + * @method Phaser.Time#reset + */ + reset: function () { + this._started = this.now; + } }; + +Phaser.Time.prototype.constructor = Phaser.Time; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** -* Timer constructor. +* A Timer is a way to create small re-usable or disposable objects that do nothing but wait for a specific moment in time, and then dispatch an event. +* You can add as many events to a Timer as you like, each with their own delays. A Timer uses milliseconds as its unit of time. There are 1000 ms in 1 second. +* So if you want to fire an event every quarter of a second you'd need to set the delay to 250. * * @class Phaser.Timer -* @classdesc A Timer +* @classdesc A Timer is a way to create small re-usable or disposable objects that do nothing but wait for a specific moment in time, and then dispatch an event. * @constructor * @param {Phaser.Game} game A reference to the currently running game. +* @param {boolean} [autoDestroy=true] - A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events). */ -Phaser.Timer = function (game) { +Phaser.Timer = function (game, autoDestroy) { + + if (typeof autoDestroy === 'undefined') { autoDestroy = true; } /** * @property {Phaser.Game} game - Local reference to game. @@ -28371,67 +30953,208 @@ Phaser.Timer = function (game) { this.game = game; /** - * The time at which this Timer instance started. - * @property {number} _started + * @property {boolean} running - True if the Timer is actively running. Do not switch this boolean, if you wish to pause the timer then use Timer.pause() instead. + * @default + */ + this.running = false; + + /** + * @property {boolean} autoDestroy - A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events). + */ + this.autoDestroy = autoDestroy; + + /** + * @property {boolean} expired - An expired Timer is one in which all of its events have been dispatched and none are pending. + * @readonly + * @default + */ + this.expired = false; + + /** + * @property {array} events - An array holding all of this timers Phaser.TimerEvent objects. Use the methods add, repeat and loop to populate it. + */ + this.events = []; + + /** + * @property {Phaser.Signal} onComplete - This signal will be dispatched when this Timer has completed, meaning there are no more events in the queue. + */ + this.onComplete = new Phaser.Signal(); + + /** + * @property {number} nextTick - The time the next tick will occur. + * @readonly + * @protected + */ + this.nextTick = 0; + + /** + * @property {boolean} paused - The paused state of the Timer. You can pause the timer by calling Timer.pause() and Timer.resume() or by the game pausing. + * @readonly + * @default + */ + this.paused = false; + + /** + * @property {number} _started - The time at which this Timer instance started running. * @private * @default */ this._started = 0; /** - * The time (in ms) that the last second counter ticked over. - * @property {number} _timeLastSecond + * @property {number} _pauseStarted - The time the game started being paused. * @private - * @default */ - this._timeLastSecond = 0; + this._pauseStarted = 0; - this.running = false; + /** + * @property {number} _now - The current start-time adjusted time. + * @private + */ + this._now = 0; - this.events = []; + /** + * @property {number} _len - Temp. array length variable. + * @private + */ + this._len = 0; - this.onEvent = new Phaser.Signal(); + /** + * @property {number} _i - Temp. array counter variable. + * @private + */ + this._i = 0; - // Need to add custom FPS rate, for now we'll just use seconds +}; -} +/** +* @constant +* @type {number} +*/ +Phaser.Timer.MINUTE = 60000; + +/** +* @constant +* @type {number} +*/ +Phaser.Timer.SECOND = 1000; + +/** +* @constant +* @type {number} +*/ +Phaser.Timer.HALF = 500; + +/** +* @constant +* @type {number} +*/ +Phaser.Timer.QUARTER = 250; Phaser.Timer.prototype = { - // delay could be from now, when the timer is created, or relative to an already running timer + /** + * Creates a new TimerEvent on this Timer. Use the methods add, repeat or loop instead of this. + * @method Phaser.Timer#create + * @private + * @param {number} delay - The number of milliseconds that should elapse before the Timer will call the given callback. + * @param {boolean} loop - Should the event loop or not? + * @param {number} repeatCount - The number of times the event will repeat. + * @param {function} callback - The callback that will be called when the Timer event occurs. + * @param {object} callbackContext - The context in which the callback will be called. + * @param {array} arguments - The values to be sent to your callback function when it is called. + * @return {Phaser.TimerEvent} The Phaser.TimerEvent object that was created. + */ + create: function (delay, loop, repeatCount, callback, callbackContext, args) { - // add: function (delay, callback, callbackContext) { - add: function (delay) { + var tick = delay; - this.events.push({ - delay: delay, - dispatched: false, - args: Array.prototype.splice.call(arguments, 1) - }); + if (this.running) + { + tick += this._now; + } - // this.events.push({ - // delay: delay, - // dispatched: false, - // callback: callback, - // callbackContext: callbackContext, - // args: Array.prototype.splice.call(arguments, 3) - // }); + var event = new Phaser.TimerEvent(this, delay, tick, repeatCount, loop, callback, callbackContext, args); + + this.events.push(event); + + this.order(); + + this.expired = false; + + return event; }, + /** + * Adds a new Event to this Timer. The event will fire after the given amount of 'delay' in milliseconds has passed, once the Timer has started running. + * Call Timer.start() once you have added all of the Events you require for this Timer. The delay is in relation to when the Timer starts, not the time it was added. + * If the Timer is already running the delay will be calculated based on the timers current time. + * @method Phaser.Timer#add + * @param {number} delay - The number of milliseconds that should elapse before the Timer will call the given callback. + * @param {function} callback - The callback that will be called when the Timer event occurs. + * @param {object} callbackContext - The context in which the callback will be called. + * @param {...*} arguments - The values to be sent to your callback function when it is called. + * @return {Phaser.TimerEvent} The Phaser.TimerEvent object that was created. + */ + add: function (delay, callback, callbackContext) { + + return this.create(delay, false, 0, callback, callbackContext, Array.prototype.splice.call(arguments, 3)); + + }, + + /** + * Adds a new Event to this Timer that will repeat for the given number of iterations. + * The event will fire after the given amount of 'delay' milliseconds has passed once the Timer has started running. + * Call Timer.start() once you have added all of the Events you require for this Timer. The delay is in relation to when the Timer starts, not the time it was added. + * If the Timer is already running the delay will be calculated based on the timers current time. + * @method Phaser.Timer#repeat + * @param {number} delay - The number of milliseconds that should elapse before the Timer will call the given callback. + * @param {number} repeatCount - The number of times the event will repeat. + * @param {function} callback - The callback that will be called when the Timer event occurs. + * @param {object} callbackContext - The context in which the callback will be called. + * @param {...*} arguments - The values to be sent to your callback function when it is called. + * @return {Phaser.TimerEvent} The Phaser.TimerEvent object that was created. + */ + repeat: function (delay, repeatCount, callback, callbackContext) { + + return this.create(delay, false, repeatCount, callback, callbackContext, Array.prototype.splice.call(arguments, 4)); + + }, + + /** + * Adds a new looped Event to this Timer that will repeat forever or until the Timer is stopped. + * The event will fire after the given amount of 'delay' milliseconds has passed once the Timer has started running. + * Call Timer.start() once you have added all of the Events you require for this Timer. The delay is in relation to when the Timer starts, not the time it was added. + * If the Timer is already running the delay will be calculated based on the timers current time. + * @method Phaser.Timer#loop + * @param {number} delay - The number of milliseconds that should elapse before the Timer will call the given callback. + * @param {function} callback - The callback that will be called when the Timer event occurs. + * @param {object} callbackContext - The context in which the callback will be called. + * @param {...*} arguments - The values to be sent to your callback function when it is called. + * @return {Phaser.TimerEvent} The Phaser.TimerEvent object that was created. + */ + loop: function (delay, callback, callbackContext) { + + return this.create(delay, true, 0, callback, callbackContext, Array.prototype.splice.call(arguments, 3)); + + }, + + /** + * Starts this Timer running. + * @method Phaser.Timer#start + */ start: function() { this._started = this.game.time.now; this.running = true; - // sort the events based on delay here, also don't run unless events is populated - // add ability to auto-stop once all events are done - // add support for maximum duration - // add support for delay before starting - // add signals? - }, + /** + * Stops this Timer from running. Does not cause it to be destroyed if autoDestroy is set to true. + * @method Phaser.Timer#stop + */ stop: function() { this.running = false; @@ -28439,36 +31162,329 @@ Phaser.Timer.prototype = { }, - update: function() { + /** + * Removes a pending TimerEvent from the queue. + * @param {Phaser.TimerEvent} event - The event to remove from the queue. + * @method Phaser.Timer#remove + */ + remove: function(event) { - // TODO: Game Paused support - - if (this.running) + for (var i = 0; i < this.events.length; i++) { - var seconds = this.seconds(); - - for (var i = 0, len = this.events.length; i < len; i++) + if (this.events[i] === event) { - if (this.events[i].dispatched === false && seconds >= this.events[i].delay) - { - this.events[i].dispatched = true; - // this.events[i].callback.apply(this.events[i].callbackContext, this.events[i].args); - this.onEvent.dispatch.apply(this, this.events[i].args); - // ought to slice it now - } + this.events.splice(i, 1); + return true; } } + return false; + + }, + + /** + * Orders the events on this Timer so they are in tick order. This is called automatically when new events are created. + * @method Phaser.Timer#order + */ + order: function () { + + if (this.events.length > 0) + { + // Sort the events so the one with the lowest tick is first + this.events.sort(this.sortHandler); + + this.nextTick = this.events[0].tick; + } + }, - seconds: function() { - return (this.game.time.now - this._started) * 0.001; + /** + * Sort handler used by Phaser.Timer.order. + * @method Phaser.Timer#sortHandler + * @protected + */ + sortHandler: function (a, b) { + + if (a.tick < b.tick) + { + return -1; + } + else if (a.tick > b.tick) + { + return 1; + } + + return 0; + + }, + + /** + * The main Timer update event, called automatically by the Game clock. + * @method Phaser.Timer#update + * @protected + * @param {number} time - The time from the core game clock. + * @return {boolean} True if there are still events waiting to be dispatched, otherwise false if this Timer can be destroyed. + */ + update: function(time) { + + if (this.paused) + { + return true; + } + + this._now = time - this._started; + + this._len = this.events.length; + + if (this.running && this._now >= this.nextTick && this._len > 0) + { + this._i = 0; + + while (this._i < this._len) + { + if (this._now >= this.events[this._i].tick) + { + if (this.events[this._i].loop === true) + { + this.events[this._i].tick += this.events[this._i].delay - (this._now - this.events[this._i].tick); + this.events[this._i].callback.apply(this.events[this._i].callbackContext, this.events[this._i].args); + } + else if (this.events[this._i].repeatCount > 0) + { + this.events[this._i].repeatCount--; + this.events[this._i].tick += this.events[this._i].delay - (this._now - this.events[this._i].tick); + this.events[this._i].callback.apply(this.events[this._i].callbackContext, this.events[this._i].args); + } + else + { + this.events[this._i].callback.apply(this.events[this._i].callbackContext, this.events[this._i].args); + this.events.splice(this._i, 1); + this._len--; + } + + this._i++; + } + else + { + break; + } + } + + // Are there any events left? + if (this.events.length > 0) + { + this.order(); + } + else + { + this.expired = true; + this.onComplete.dispatch(this); + } + } + + if (this.expired && this.autoDestroy) + { + return false; + } + else + { + return true; + } + + }, + + /** + * Pauses the Timer and all events in the queue. + * @method Phaser.Timer#pause + */ + pause: function () { + + this._pauseStarted = this.game.time.now; + + this.paused = true; + + }, + + /** + * Resumes the Timer and updates all pending events. + * @method Phaser.Timer#resume + */ + resume: function () { + + var pauseDuration = this.game.time.now - this._pauseStarted; + + for (var i = 0; i < this.events.length; i++) + { + this.events[i].tick += pauseDuration; + } + + this.nextTick += pauseDuration; + + this.paused = false; + + }, + + /** + * Destroys this Timer. Events are not dispatched. + * @method Phaser.Timer#destroy + */ + destroy: function() { + + this.onComplete.removeAll(); + this.running = false; + this.events = []; + } -} +}; + +/** +* @name Phaser.Timer#next +* @property {number} next - The time at which the next event will occur. +* @readonly +*/ +Object.defineProperty(Phaser.Timer.prototype, "next", { + + get: function () { + return this.nextTick; + } + +}); + +/** +* @name Phaser.Timer#duration +* @property {number} duration - The duration in ms remaining until the next event will occur. +* @readonly +*/ +Object.defineProperty(Phaser.Timer.prototype, "duration", { + + get: function () { + + if (this.running && this.nextTick > this._now) + { + return this.nextTick - this._now; + } + else + { + return 0; + } + + } + +}); + +/** +* @name Phaser.Timer#length +* @property {number} length - The number of pending events in the queue. +* @readonly +*/ +Object.defineProperty(Phaser.Timer.prototype, "length", { + + get: function () { + return this.events.length; + } + +}); + +/** +* @name Phaser.Timer#ms +* @property {number} ms - The duration in milliseconds that this Timer has been running for. +* @readonly +*/ +Object.defineProperty(Phaser.Timer.prototype, "ms", { + + get: function () { + return this._now; + } + +}); + +/** +* @name Phaser.Timer#seconds +* @property {number} seconds - The duration in seconds that this Timer has been running for. +* @readonly +*/ +Object.defineProperty(Phaser.Timer.prototype, "seconds", { + + get: function () { + return this._now * 0.001; + } + +}); + +Phaser.Timer.prototype.constructor = Phaser.Timer; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* A TimerEvent is a single event that is processed by a Phaser.Timer. It consists of a delay, which is a value in milliseconds after which the event will fire. +* It can call a specific callback, passing in optional parameters. +* +* @class Phaser.TimerEvent +* @classdesc A TimerEvent is a single event that is processed by a Phaser.Timer. It consists of a delay, which is a value in milliseconds after which the event will fire. +* @constructor +* @param {Phaser.Timer} timer - The Timer object that this TimerEvent belongs to. +* @param {number} delay - The delay in ms at which this TimerEvent fires. +* @param {number} tick - The tick is the next game clock time that this event will fire at. +* @param {number} repeatCount - If this TimerEvent repeats it will do so this many times. +* @param {boolean} loop - True if this TimerEvent loops, otherwise false. +* @param {function} callback - The callback that will be called when the TimerEvent occurs. +* @param {object} callbackContext - The context in which the callback will be called. +* @param {array} arguments - The values to be passed to the callback. +*/ +Phaser.TimerEvent = function (timer, delay, tick, repeatCount, loop, callback, callbackContext, args) { + + /** + * @property {Phaser.Timer} timer - The Timer object that this TimerEvent belongs to. + */ + this.timer = timer; + + /** + * @property {number} delay - The delay in ms at which this TimerEvent fires. + */ + this.delay = delay; + + /** + * @property {number} tick - The tick is the next game clock time that this event will fire at. + */ + this.tick = tick; + + /** + * @property {number} repeatCount - If this TimerEvent repeats it will do so this many times. + */ + this.repeatCount = repeatCount - 1; + + /** + * @property {boolean} loop - True if this TimerEvent loops, otherwise false. + */ + this.loop = loop; + + /** + * @property {function} callback - The callback that will be called when the TimerEvent occurs. + */ + this.callback = callback; + + /** + * @property {object} callbackContext - The context in which the callback will be called. + */ + this.callbackContext = callbackContext; + + /** + * @property {array} arguments - The values to be passed to the callback. + */ + this.args = args; + +}; + +Phaser.TimerEvent.prototype.constructor = Phaser.TimerEvent; + +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -28734,7 +31750,7 @@ Phaser.AnimationManager.prototype = { * * @method Phaser.AnimationManager#getAnimation * @param {string} name - The name of the animation to be returned, e.g. "fire". - * @return {Phaser.Animation|boolean} The Animation instance, if found, otherwise false. + * @return {Phaser.Animation} The Animation instance, if found, otherwise null. */ getAnimation: function (name) { @@ -28746,7 +31762,7 @@ Phaser.AnimationManager.prototype = { } } - return false; + return null; }, @@ -28779,6 +31795,8 @@ Phaser.AnimationManager.prototype = { }; +Phaser.AnimationManager.prototype.constructor = Phaser.AnimationManager; + /** * @name Phaser.AnimationManager#frameData * @property {Phaser.FrameData} frameData - The current animations FrameData. @@ -28896,7 +31914,7 @@ Object.defineProperty(Phaser.AnimationManager.prototype, 'frameName', { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -28939,7 +31957,7 @@ Phaser.Animation = function (game, parent, name, frameData, frames, delay, loope this.name = name; /** - * @property {object} _frames + * @property {array} _frames * @private */ this._frames = []; @@ -28956,7 +31974,8 @@ Phaser.Animation = function (game, parent, name, frameData, frames, delay, loope this.looped = looped; /** - * @property {boolean} looped - The loop state of the Animation. + * @property {boolean} killOnComplete - Should the parent of this Animation be killed when the animation completes? + * @default */ this.killOnComplete = false; @@ -29223,6 +32242,8 @@ Phaser.Animation.prototype = { }; +Phaser.Animation.prototype.constructor = Phaser.Animation; + /** * @name Phaser.Animation#paused * @property {boolean} paused - Gets and sets the paused state of this Animation. @@ -29367,7 +32388,7 @@ Phaser.Animation.generateFrameNames = function (prefix, start, stop, suffix, zer /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -29526,9 +32547,11 @@ Phaser.Frame.prototype = { }; +Phaser.Frame.prototype.constructor = Phaser.Frame; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -29751,6 +32774,8 @@ Phaser.FrameData.prototype = { }; +Phaser.FrameData.prototype.constructor = Phaser.FrameData; + /** * @name Phaser.FrameData#total * @property {number} total - The total number of frames in this FrameData set. @@ -29766,7 +32791,7 @@ Object.defineProperty(Phaser.FrameData.prototype, "total", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -29786,9 +32811,11 @@ Phaser.AnimationParser = { * @param {number} frameWidth - The fixed width of each frame of the animation. * @param {number} frameHeight - The fixed height of each frame of the animation. * @param {number} [frameMax=-1] - The total number of animation frames to extact from the Sprite Sheet. The default value of -1 means "extract all frames". + * @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here. + * @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here. * @return {Phaser.FrameData} A FrameData object containing the parsed frames. */ - spriteSheet: function (game, key, frameWidth, frameHeight, frameMax) { + spriteSheet: function (game, key, frameWidth, frameHeight, frameMax, margin, spacing) { // How big is our image? var img = game.cache.getImage(key); @@ -29829,8 +32856,8 @@ Phaser.AnimationParser = { // Let's create some frames then var data = new Phaser.FrameData(); - var x = 0; - var y = 0; + var x = margin; + var y = margin; for (var i = 0; i < total; i++) { @@ -29845,12 +32872,12 @@ Phaser.AnimationParser = { height: frameHeight }); - x += frameWidth; + x += frameWidth + spacing; if (x === width) { - x = 0; - y += frameHeight; + x = margin; + y += frameHeight + spacing; } } @@ -30092,16 +33119,15 @@ Phaser.AnimationParser = { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** * Phaser.Cache constructor. * -* @class Phaser.Cache -* @classdesc A game only has one instance of a Cache and it is used to store all externally loaded assets such -* as images, sounds and data files as a result of Loader calls. Cache items use string based keys for look-up. +* @class Phaser.Cache +* @classdesc A game only has one instance of a Cache and it is used to store all externally loaded assets such as images, sounds and data files as a result of Loader calls. Cached items use string based keys for look-up. * @constructor * @param {Phaser.Game} game - A reference to the currently running game. */ @@ -30149,10 +33175,10 @@ Phaser.Cache = function (game) { this._tilemaps = {}; /** - * @property {object} _tilesets - Tileset key-value container. + * @property {object} _binary - Binary file key-value container. * @private */ - this._tilesets = {}; + this._binary = {}; /** * @property {object} _bitmapDatas - BitmapData key-value container. @@ -30185,6 +33211,18 @@ Phaser.Cache.prototype = { }, + /** + * Add a binary object in to the cache. + * @method Phaser.Cache#addBinary + * @param {string} key - Asset key for this binary data. + * @param {object} binaryData - The binary object to be addded to the cache. + */ + addBinary: function (key, binaryData) { + + this._binary[key] = binaryData; + + }, + /** * Add a BitmapData object in to the cache. * @method Phaser.Cache#addBitmapData @@ -30224,40 +33262,18 @@ Phaser.Cache.prototype = { * @param {object} data - Extra sprite sheet data. * @param {number} frameWidth - Width of the sprite sheet. * @param {number} frameHeight - Height of the sprite sheet. - * @param {number} frameMax - How many frames stored in the sprite sheet. + * @param {number} [frameMax=-1] - How many frames stored in the sprite sheet. If -1 then it divides the whole sheet evenly. + * @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here. + * @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here. */ - addSpriteSheet: function (key, url, data, frameWidth, frameHeight, frameMax) { + addSpriteSheet: function (key, url, data, frameWidth, frameHeight, frameMax, margin, spacing) { - this._images[key] = { url: url, data: data, spriteSheet: true, frameWidth: frameWidth, frameHeight: frameHeight }; + this._images[key] = { url: url, data: data, spriteSheet: true, frameWidth: frameWidth, frameHeight: frameHeight, margin: margin, spacing: spacing }; PIXI.BaseTextureCache[key] = new PIXI.BaseTexture(data); PIXI.TextureCache[key] = new PIXI.Texture(PIXI.BaseTextureCache[key]); - this._images[key].frameData = Phaser.AnimationParser.spriteSheet(this.game, key, frameWidth, frameHeight, frameMax); - - }, - - /** - * Add a new tile set in to the cache. - * - * @method Phaser.Cache#addTileset - * @param {string} key - The unique key by which you will reference this object. - * @param {string} url - URL of this tile set file. - * @param {object} data - Extra tile set data. - * @param {number} tileWidth - Width of the sprite sheet. - * @param {number} tileHeight - Height of the sprite sheet. - * @param {number} tileMax - How many tiles stored in the sprite sheet. - * @param {number} [tileMargin=0] - If the tiles have been drawn with a margin, specify the amount here. - * @param {number} [tileSpacing=0] - If the tiles have been drawn with spacing between them, specify the amount here. - */ - addTileset: function (key, url, data, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) { - - this._tilesets[key] = { url: url, data: data, tileWidth: tileWidth, tileHeight: tileHeight, tileMargin: tileMargin, tileSpacing: tileSpacing }; - - PIXI.BaseTextureCache[key] = new PIXI.BaseTexture(data); - PIXI.TextureCache[key] = new PIXI.Texture(PIXI.BaseTextureCache[key]); - - this._tilesets[key].tileData = Phaser.TilemapParser.tileset(this.game, key, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing); + this._images[key].frameData = Phaser.AnimationParser.spriteSheet(this.game, key, frameWidth, frameHeight, frameMax, margin, spacing); }, @@ -30267,15 +33283,13 @@ Phaser.Cache.prototype = { * @method Phaser.Cache#addTilemap * @param {string} key - The unique key by which you will reference this object. * @param {string} url - URL of the tilemap image. - * @param {object} mapData - The tilemap data object. + * @param {object} mapData - The tilemap data object (either a CSV or JSON file). * @param {number} format - The format of the tilemap data. */ addTilemap: function (key, url, mapData, format) { this._tilemaps[key] = { url: url, data: mapData, format: format }; - this._tilemaps[key].layers = Phaser.TilemapParser.parse(this.game, mapData, format); - }, /** @@ -30425,12 +33439,13 @@ Phaser.Cache.prototype = { decoded = true; } - this._sounds[key] = { url: url, data: data, isDecoding: false, decoded: decoded, webAudio: webAudio, audioTag: audioTag }; + this._sounds[key] = { url: url, data: data, isDecoding: false, decoded: decoded, webAudio: webAudio, audioTag: audioTag, locked: this.game.sound.touchLocked }; }, /** * Reload a sound. + * * @method Phaser.Cache#reloadSound * @param {string} key - Asset key for the sound. */ @@ -30451,7 +33466,8 @@ Phaser.Cache.prototype = { }, /** - * Description. + * Fires the onSoundUnlock event when the sound has completed reloading. + * * @method Phaser.Cache#reloadSoundComplete * @param {string} key - Asset key for the sound. */ @@ -30466,7 +33482,8 @@ Phaser.Cache.prototype = { }, /** - * Description. + * Updates the sound object in the cache. + * * @method Phaser.Cache#updateSound * @param {string} key - Asset key for the sound. */ @@ -30498,8 +33515,8 @@ Phaser.Cache.prototype = { * Get a canvas object from the cache by its key. * * @method Phaser.Cache#getCanvas - * @param {string} key - Asset key of the canvas you want. - * @return {object} The canvas you want. + * @param {string} key - Asset key of the canvas to retrieve from the Cache. + * @return {object} The canvas object. */ getCanvas: function (key) { @@ -30507,8 +33524,10 @@ Phaser.Cache.prototype = { { return this._canvases[key].canvas; } - - return null; + else + { + console.warn('Phaser.Cache.getCanvas: Invalid key: "' + key + '"'); + } }, @@ -30516,7 +33535,7 @@ Phaser.Cache.prototype = { * Get a BitmapData object from the cache by its key. * * @method Phaser.Cache#getBitmapData - * @param {string} key - Asset key of the BitmapData object you want. + * @param {string} key - Asset key of the BitmapData object to retrieve from the Cache. * @return {Phaser.BitmapData} The requested BitmapData object if found, or null if not. */ getBitmapData: function (key) { @@ -30525,8 +33544,10 @@ Phaser.Cache.prototype = { { return this._bitmapDatas[key]; } - - return null; + else + { + console.warn('Phaser.Cache.getBitmapData: Invalid key: "' + key + '"'); + } }, @@ -30534,7 +33555,7 @@ Phaser.Cache.prototype = { * Checks if an image key exists. * * @method Phaser.Cache#checkImageKey - * @param {string} key - Asset key of the image you want. + * @param {string} key - Asset key of the image to check is in the Cache. * @return {boolean} True if the key exists, otherwise false. */ checkImageKey: function (key) { @@ -30552,8 +33573,8 @@ Phaser.Cache.prototype = { * Get image data by key. * * @method Phaser.Cache#getImage - * @param {string} key - Asset key of the image you want. - * @return {object} The image data you want. + * @param {string} key - Asset key of the image to retrieve from the Cache. + * @return {object} The image data. */ getImage: function (key) { @@ -30561,53 +33582,19 @@ Phaser.Cache.prototype = { { return this._images[key].data; } - - return null; - - }, - - /** - * Get tile set image data by key. - * - * @method Phaser.Cache#getTileSetImage - * @param {string} key - Asset key of the image you want. - * @return {object} The image data you want. - */ - getTilesetImage: function (key) { - - if (this._tilesets[key]) + else { - return this._tilesets[key].data; + console.warn('Phaser.Cache.getImage: Invalid key: "' + key + '"'); } - return null; - - }, - - /** - * Get tile set image data by key. - * - * @method Phaser.Cache#getTileset - * @param {string} key - Asset key of the image you want. - * @return {Phaser.Tileset} The tileset data. The tileset image is in the data property, the tile data in tileData. - */ - getTileset: function (key) { - - if (this._tilesets[key]) - { - return this._tilesets[key].tileData; - } - - return null; - }, /** * Get tilemap data by key. * * @method Phaser.Cache#getTilemap - * @param {string} key - Asset key of the tilemap you want. - * @return {Object} The tilemap data. The tileset image is in the data property, the map data in mapData. + * @param {string} key - Asset key of the tilemap data to retrieve from the Cache. + * @return {Object} The raw tilemap data in CSV or JSON format. */ getTilemapData: function (key) { @@ -30615,16 +33602,19 @@ Phaser.Cache.prototype = { { return this._tilemaps[key]; } + else + { + console.warn('Phaser.Cache.getTilemapData: Invalid key: "' + key + '"'); + } - return null; }, /** * Get frame data by key. * * @method Phaser.Cache#getFrameData - * @param {string} key - Asset key of the frame data you want. - * @return {Phaser.FrameData} The frame data you want. + * @param {string} key - Asset key of the frame data to retrieve from the Cache. + * @return {Phaser.FrameData} The frame data. */ getFrameData: function (key) { @@ -30640,8 +33630,8 @@ Phaser.Cache.prototype = { * Get a single frame out of a frameData set by key. * * @method Phaser.Cache#getFrameByIndex - * @param {string} key - Asset key of the frame data you want. - * @return {Phaser.Frame} The frame data you want. + * @param {string} key - Asset key of the frame data to retrieve from the Cache. + * @return {Phaser.Frame} The frame object. */ getFrameByIndex: function (key, frame) { @@ -30657,8 +33647,8 @@ Phaser.Cache.prototype = { * Get a single frame out of a frameData set by key. * * @method Phaser.Cache#getFrameByName - * @param {string} key - Asset key of the frame data you want. - * @return {Phaser.Frame} The frame data you want. + * @param {string} key - Asset key of the frame data to retrieve from the Cache. + * @return {Phaser.Frame} The frame object. */ getFrameByName: function (key, frame) { @@ -30674,8 +33664,8 @@ Phaser.Cache.prototype = { * Get a single frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image. * * @method Phaser.Cache#getFrame - * @param {string} key - Asset key of the frame data you want. - * @return {Phaser.Frame} The frame data you want. + * @param {string} key - Asset key of the frame data to retrieve from the Cache. + * @return {Phaser.Frame} The frame data. */ getFrame: function (key) { @@ -30688,11 +33678,11 @@ Phaser.Cache.prototype = { }, /** - * Get a single frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image. + * Get a single texture frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image. * * @method Phaser.Cache#getTextureFrame - * @param {string} key - Asset key of the frame data you want. - * @return {Phaser.Frame} The frame data you want. + * @param {string} key - Asset key of the frame to retrieve from the Cache. + * @return {Phaser.Frame} The frame data. */ getTextureFrame: function (key) { @@ -30708,8 +33698,8 @@ Phaser.Cache.prototype = { * Get a RenderTexture by key. * * @method Phaser.Cache#getTexture - * @param {string} key - Asset key of the RenderTexture you want. - * @return {Phaser.RenderTexture} The RenderTexture you want. + * @param {string} key - Asset key of the RenderTexture to retrieve from the Cache. + * @return {Phaser.RenderTexture} The RenderTexture object. */ getTexture: function (key) { @@ -30717,8 +33707,10 @@ Phaser.Cache.prototype = { { return this._textures[key]; } - - return null; + else + { + console.warn('Phaser.Cache.getTexture: Invalid key: "' + key + '"'); + } }, @@ -30726,8 +33718,8 @@ Phaser.Cache.prototype = { * Get sound by key. * * @method Phaser.Cache#getSound - * @param {string} key - Asset key of the sound you want. - * @return {Phaser.Sound} The sound you want. + * @param {string} key - Asset key of the sound to retrieve from the Cache. + * @return {Phaser.Sound} The sound object. */ getSound: function (key) { @@ -30735,8 +33727,10 @@ Phaser.Cache.prototype = { { return this._sounds[key]; } - - return null; + else + { + console.warn('Phaser.Cache.getSound: Invalid key: "' + key + '"'); + } }, @@ -30744,8 +33738,8 @@ Phaser.Cache.prototype = { * Get sound data by key. * * @method Phaser.Cache#getSoundData - * @param {string} key - Asset key of the sound you want. - * @return {object} The sound data you want. + * @param {string} key - Asset key of the sound to retrieve from the Cache. + * @return {object} The sound data. */ getSoundData: function (key) { @@ -30753,8 +33747,10 @@ Phaser.Cache.prototype = { { return this._sounds[key].data; } - - return null; + else + { + console.warn('Phaser.Cache.getSoundData: Invalid key: "' + key + '"'); + } }, @@ -30762,7 +33758,7 @@ Phaser.Cache.prototype = { * Check if the given sound has finished decoding. * * @method Phaser.Cache#isSoundDecoded - * @param {string} key - Asset key of the sound you want. + * @param {string} key - Asset key of the sound in the Cache. * @return {boolean} The decoded state of the Sound object. */ isSoundDecoded: function (key) { @@ -30778,7 +33774,7 @@ Phaser.Cache.prototype = { * Check if the given sound is ready for playback. A sound is considered ready when it has finished decoding and the device is no longer touch locked. * * @method Phaser.Cache#isSoundReady - * @param {string} key - Asset key of the sound you want. + * @param {string} key - Asset key of the sound in the Cache. * @return {boolean} True if the sound is decoded and the device is not touch locked. */ isSoundReady: function (key) { @@ -30809,8 +33805,8 @@ Phaser.Cache.prototype = { * Get text data by key. * * @method Phaser.Cache#getText - * @param {string} key - Asset key of the text data you want. - * @return {object} The text data you want. + * @param {string} key - Asset key of the text data to retrieve from the Cache. + * @return {object} The text data. */ getText: function (key) { @@ -30818,8 +33814,30 @@ Phaser.Cache.prototype = { { return this._text[key].data; } + else + { + console.warn('Phaser.Cache.getText: Invalid key: "' + key + '"'); + } + + }, - return null; + /** + * Get binary data by key. + * + * @method Phaser.Cache#getBinary + * @param {string} key - Asset key of the binary data object to retrieve from the Cache. + * @return {object} The binary data object. + */ + getBinary: function (key) { + + if (this._binary[key]) + { + return this._binary[key]; + } + else + { + console.warn('Phaser.Cache.getBinary: Invalid key: "' + key + '"'); + } }, @@ -30837,7 +33855,7 @@ Phaser.Cache.prototype = { for (var item in array) { - if (item !== '__default') + if (item !== '__default' && item !== '__missing') { output.push(item); } @@ -30947,9 +33965,11 @@ Phaser.Cache.prototype = { }; +Phaser.Cache.prototype.constructor = Phaser.Cache; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -30983,7 +34003,7 @@ Phaser.Loader = function (game) { this._fileIndex = 0; /** - * @property {number} _progressChunk - Indicates assets loading progress. (from 0 to 100) + * @property {number} _progressChunk - Indicates the size of 1 file in terms of a percentage out of 100. * @private * @default */ @@ -31008,11 +34028,17 @@ Phaser.Loader = function (game) { this.hasLoaded = false; /** - * @property {number} progress - The Load progress percentage value (from 0 to 100) + * @property {number} progress - The rounded load progress percentage value (from 0 to 100) * @default */ this.progress = 0; + /** + * @property {number} progressFloat - The non-rounded load progress value (from 0.0 to 100.0) + * @default + */ + this.progressFloat = 0; + /** * You can optionally link a sprite to the preloader. * If you do so the Sprite's width or height will be cropped based on the percentage loaded. @@ -31312,6 +34338,29 @@ Phaser.Loader.prototype = { }, + /** + * Add a binary file to the Loader. It will be loaded via xhr with a responseType of "arraybuffer". You can specify an optional callback to process the file after load. + * When the callback is called it will be passed 2 parameters: the key of the file and the file data. + * WARNING: If you specify a callback, the file data will be set to whatever your callback returns. So always return the data object, even if you didn't modify it. + * + * @method Phaser.Loader#binary + * @param {string} key - Unique asset key of the binary file. + * @param {string} url - URL of the binary file. + * @param {function} [callback] - Optional callback that will be passed the file after loading, so you can perform additional processing on it. + * @param {function} [callbackContext] - The context under which the callback will be applied. If not specified it will use the callback itself as the context. + * @return {Phaser.Loader} This Loader instance. + */ + binary: function (key, url, callback, callbackContext) { + + if (typeof callback === 'undefined') { callback = false; } + if (callback !== false && typeof callbackContext === 'undefined') { callbackContext = callback; } + + this.addToFileList('binary', key, url, { callback: callback, callbackContext: callbackContext }); + + return this; + + }, + /** * Add a new sprite sheet to the loader. * @@ -31321,38 +34370,17 @@ Phaser.Loader.prototype = { * @param {number} frameWidth - Width of each single frame. * @param {number} frameHeight - Height of each single frame. * @param {number} [frameMax=-1] - How many frames in this sprite sheet. If not specified it will divide the whole image into frames. + * @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here. + * @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here. * @return {Phaser.Loader} This Loader instance. */ - spritesheet: function (key, url, frameWidth, frameHeight, frameMax) { + spritesheet: function (key, url, frameWidth, frameHeight, frameMax, margin, spacing) { if (typeof frameMax === "undefined") { frameMax = -1; } + if (typeof margin === "undefined") { margin = 0; } + if (typeof spacing === "undefined") { spacing = 0; } - this.addToFileList('spritesheet', key, url, { frameWidth: frameWidth, frameHeight: frameHeight, frameMax: frameMax }); - - return this; - - }, - - /** - * Add a new tile set to the loader. These are used in the rendering of tile maps. - * - * @method Phaser.Loader#tileset - * @param {string} key - Unique asset key of the tileset file. - * @param {string} url - URL of the tileset. - * @param {number} tileWidth - Width of each single tile in pixels. - * @param {number} tileHeight - Height of each single tile in pixels. - * @param {number} [tileMax=-1] - How many tiles in this tileset. If not specified it will divide the whole image into tiles. - * @param {number} [tileMargin=0] - If the tiles have been drawn with a margin, specify the amount here. - * @param {number} [tileSpacing=0] - If the tiles have been drawn with spacing between them, specify the amount here. - * @return {Phaser.Loader} This Loader instance. - */ - tileset: function (key, url, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) { - - if (typeof tileMax === "undefined") { tileMax = -1; } - if (typeof tileMargin === "undefined") { tileMargin = 0; } - if (typeof tileSpacing === "undefined") { tileSpacing = 0; } - - this.addToFileList('tileset', key, url, { tileWidth: tileWidth, tileHeight: tileHeight, tileMax: tileMax, tileMargin: tileMargin, tileSpacing: tileSpacing }); + this.addToFileList('spritesheet', key, url, { frameWidth: frameWidth, frameHeight: frameHeight, frameMax: frameMax, margin: margin, spacing: spacing }); return this; @@ -31660,6 +34688,7 @@ Phaser.Loader.prototype = { } this.progress = 0; + this.progressFloat = 0; this.hasLoaded = false; this.isLoading = true; @@ -31674,6 +34703,7 @@ Phaser.Loader.prototype = { else { this.progress = 100; + this.progressFloat = 100; this.hasLoaded = true; this.onLoadComplete.dispatch(); } @@ -31704,7 +34734,6 @@ Phaser.Loader.prototype = { case 'spritesheet': case 'textureatlas': case 'bitmapfont': - case 'tileset': file.data = new Image(); file.data.name = file.key; file.data.onload = function () { @@ -31795,6 +34824,7 @@ Phaser.Loader.prototype = { break; case 'text': + case 'script': this._xhr.open("GET", this.baseURL + file.url, true); this._xhr.responseType = "text"; this._xhr.onload = function () { @@ -31806,10 +34836,9 @@ Phaser.Loader.prototype = { this._xhr.send(); break; - case 'script': - + case 'binary': this._xhr.open("GET", this.baseURL + file.url, true); - this._xhr.responseType = "text"; + this._xhr.responseType = "arraybuffer"; this._xhr.onload = function () { return _this.fileComplete(_this._fileIndex); }; @@ -31882,7 +34911,6 @@ Phaser.Loader.prototype = { console.warn('Phaser.Loader fileComplete invalid index ' + index); return; } - var file = this._fileList[index]; file.loaded = true; @@ -31899,12 +34927,7 @@ Phaser.Loader.prototype = { case 'spritesheet': - this.game.cache.addSpriteSheet(file.key, file.url, file.data, file.frameWidth, file.frameHeight, file.frameMax); - break; - - case 'tileset': - - this.game.cache.addTileset(file.key, file.url, file.data, file.tileWidth, file.tileHeight, file.tileMax, file.tileMargin, file.tileSpacing); + this.game.cache.addSpriteSheet(file.key, file.url, file.data, file.frameWidth, file.frameHeight, file.frameMax, file.margin, file.spacing); break; case 'textureatlas': @@ -31987,6 +35010,7 @@ Phaser.Loader.prototype = { if (buffer) { that.game.cache.decodedSound(key, buffer); + that.game.sound.onSoundDecode.dispatch(key, that.game.cache.getSound(key)); } }); } @@ -32011,6 +35035,20 @@ Phaser.Loader.prototype = { file.data.text = this._xhr.responseText; document.head.appendChild(file.data); break; + + case 'binary': + if (file.callback) + { + file.data = file.callback.call(file.callbackContext, file.key, this._xhr.response); + } + else + { + file.data = this._xhr.response; + } + + this.game.cache.addBinary(file.key, file.data); + + break; } if (loadNext) @@ -32156,7 +35194,8 @@ Phaser.Loader.prototype = { */ nextFile: function (previousIndex, success) { - this.progress = Math.round(this.progress + this._progressChunk); + this.progressFloat += this._progressChunk; + this.progress = Math.round(this.progressFloat); if (this.progress > 100) { @@ -32240,9 +35279,11 @@ Phaser.Loader.prototype = { }; +Phaser.Loader.prototype.constructor = Phaser.Loader; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -32325,7 +35366,7 @@ Phaser.LoaderParser = { }; /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -32671,25 +35712,25 @@ Phaser.Sound.prototype = { { if (this.loop) { - //console.log('loop1'); + // console.log('loop1'); // won't work with markers, needs to reset the position this.onLoop.dispatch(this); if (this.currentMarker === '') { - //console.log('loop2'); + // console.log('loop2'); this.currentTime = 0; this.startTime = this.game.time.now; } else { - //console.log('loop3'); + // console.log('loop3'); this.play(this.currentMarker, 0, this.volume, true, true); } } else { - //console.log('stopping, no loop for marker'); + // console.log('stopping, no loop for marker'); this.stop(); } } @@ -32877,7 +35918,7 @@ Phaser.Sound.prototype = { else { // console.log('sound not locked, state?', this._sound.readyState); - if (this._sound && this._sound.readyState == 4) + if (this._sound && (this.game.device.cocoonJS || this._sound.readyState === 4)) { this._sound.play(); // This doesn't become available until you call play(), wonderful ... @@ -32967,7 +36008,20 @@ Phaser.Sound.prototype = { this._sound = this.context.createBufferSource(); this._sound.buffer = this._buffer; - this._sound.connect(this.gainNode); + + if (this.externalNode) + { + this._sound.connect(this.externalNode.input); + } + else + { + this._sound.connect(this.gainNode); + } + + if (this.loop) + { + this._sound.loop = true; + } if (typeof this._sound.start === 'undefined') { @@ -33028,6 +36082,8 @@ Phaser.Sound.prototype = { }; +Phaser.Sound.prototype.constructor = Phaser.Sound; + /** * @name Phaser.Sound#isDecoding * @property {boolean} isDecoding - Returns true if the sound file is still decoding. @@ -33136,7 +36192,7 @@ Object.defineProperty(Phaser.Sound.prototype, "volume", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -33424,7 +36480,7 @@ Phaser.SoundManager.prototype = { that.game.cache.decodedSound(key, buffer); if (sound) { - that.onSoundDecode.dispatch(sound); + that.onSoundDecode.dispatch(key, sound); } }); } @@ -33505,6 +36561,8 @@ Phaser.SoundManager.prototype = { }; +Phaser.SoundManager.prototype.constructor = Phaser.SoundManager; + /** * @name Phaser.SoundManager#mute * @property {boolean} mute - Gets or sets the muted state of the SoundManager. This effects all sounds in the game. @@ -33617,7 +36675,7 @@ Object.defineProperty(Phaser.SoundManager.prototype, "volume", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -33647,6 +36705,11 @@ Phaser.Utils.Debug = function (game) { */ this.font = '14px Courier'; + /** + * @property {number} columnWidth - The spacing between columns. + */ + this.columnWidth = 100; + /** * @property {number} lineHeight - The line height between the debug text. */ @@ -33682,11 +36745,12 @@ Phaser.Utils.Debug.prototype = { /** * Internal method that resets and starts the debug output values. * @method Phaser.Utils.Debug#start - * @param {number} x - The X value the debug info will start from. - * @param {number} y - The Y value the debug info will start from. - * @param {string} color - The color the debug info will drawn in. + * @param {number} [x=0] - The X value the debug info will start from. + * @param {number} [y=0] - The Y value the debug info will start from. + * @param {string} [color='rgb(255,255,255)'] - The color the debug text will drawn in. + * @param {number} [columnWidth=0] - The spacing between columns. */ - start: function (x, y, color) { + start: function (x, y, color, columnWidth) { if (this.context == null) { @@ -33695,16 +36759,18 @@ Phaser.Utils.Debug.prototype = { if (typeof x !== 'number') { x = 0; } if (typeof y !== 'number') { y = 0; } - color = color || 'rgb(255,255,255)'; + if (typeof columnWidth === 'undefined') { columnWidth = 0; } this.currentX = x; this.currentY = y; this.currentColor = color; this.currentAlpha = this.context.globalAlpha; + this.columnWidth = columnWidth; this.context.save(); this.context.setTransform(1, 0, 0, 1, 0, 0); + this.context.strokeStyle = color; this.context.fillStyle = color; this.context.font = this.font; this.context.globalAlpha = 1; @@ -33717,7 +36783,6 @@ Phaser.Utils.Debug.prototype = { */ stop: function () { - this.context.restore(); this.context.globalAlpha = this.currentAlpha; @@ -33727,8 +36792,8 @@ Phaser.Utils.Debug.prototype = { * Internal method that outputs a single line of text. * @method Phaser.Utils.Debug#line * @param {string} text - The line of text to draw. - * @param {number} x - The X value the debug info will start from. - * @param {number} y - The Y value the debug info will start from. + * @param {number} [x] - The X value the debug info will start from. + * @param {number} [y] - The Y value the debug info will start from. */ line: function (text, x, y) { @@ -33737,16 +36802,8 @@ Phaser.Utils.Debug.prototype = { return; } - x = x || null; - y = y || null; - - if (x !== null) { - this.currentX = x; - } - - if (y !== null) { - this.currentY = y; - } + if (typeof x !== 'undefined') { this.currentX = x; } + if (typeof y !== 'undefined') { this.currentY = y; } if (this.renderShadow) { @@ -33760,6 +36817,38 @@ Phaser.Utils.Debug.prototype = { }, + /** + * Internal method that outputs a single line of text split over as many columns as needed, one per parameter. + * @method Phaser.Utils.Debug#splitline + * @param {string} text - The text to render. You can have as many columns of text as you want, just pass them as additional parameters. + */ + splitline: function (text) { + + if (this.context == null) + { + return; + } + + var x = this.currentX; + + for (var i = 0; i < arguments.length; i++) + { + if (this.renderShadow) + { + this.context.fillStyle = 'rgb(0,0,0)'; + this.context.fillText(arguments[i], x + 1, this.currentY + 1); + this.context.fillStyle = this.currentColor; + } + + this.context.fillText(arguments[i], x, this.currentY); + + x += this.columnWidth; + } + + this.currentY += this.lineHeight; + + }, + /** * Visually renders a QuadTree to the display. * @method Phaser.Utils.Debug#renderQuadTree @@ -34005,25 +37094,27 @@ Phaser.Utils.Debug.prototype = { }, /** - * Render Sprite collision. - * @method Phaser.Utils.Debug#renderSpriteCollision + * Render Sprite Body Physics Data as text. + * @method Phaser.Utils.Debug#renderBodyInfo * @param {Phaser.Sprite} sprite - The sprite to be rendered. * @param {number} x - X position of the debug info to be rendered. * @param {number} y - Y position of the debug info to be rendered. * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string). */ - renderSpriteCollision: function (sprite, x, y, color) { + renderBodyInfo: function (sprite, x, y, color) { color = color || 'rgb(255,255,255)'; - this.start(x, y, color); - this.line('Sprite Collision: (' + sprite.width + ' x ' + sprite.height + ')'); - this.line('left: ' + sprite.body.touching.left); - this.line('right: ' + sprite.body.touching.right); - this.line('up: ' + sprite.body.touching.up); - this.line('down: ' + sprite.body.touching.down); - this.line('velocity.x: ' + sprite.body.velocity.x); - this.line('velocity.y: ' + sprite.body.velocity.y); + this.start(x, y, color, 210); + + this.splitline('x: ' + sprite.body.x.toFixed(2), 'y: ' + sprite.body.y.toFixed(2), 'width: ' + sprite.width, 'height: ' + sprite.height); + this.splitline('speed: ' + sprite.body.speed.toFixed(2), 'angle: ' + sprite.body.angle.toFixed(2), 'linear damping: ' + sprite.body.linearDamping); + this.splitline('blocked left: ' + sprite.body.blocked.left, 'right: ' + sprite.body.blocked.right, 'up: ' + sprite.body.blocked.up, 'down: ' + sprite.body.blocked.down); + this.splitline('touching left: ' + sprite.body.touching.left, 'right: ' + sprite.body.touching.right, 'up: ' + sprite.body.touching.up, 'down: ' + sprite.body.touching.down); + this.splitline('gravity x: ' + sprite.body.gravity.x, 'y: ' + sprite.body.gravity.y, 'world gravity x: ' + this.game.physics.gravity.x, 'y: ' + this.game.physics.gravity.y); + this.splitline('acceleration x: ' + sprite.body.acceleration.x.toFixed(2), 'y: ' + sprite.body.acceleration.y.toFixed(2)); + this.splitline('velocity x: ' + sprite.body.velocity.x.toFixed(2), 'y: ' + sprite.body.velocity.y.toFixed(2), 'deltaX: ' + sprite.body.deltaX().toFixed(2), 'deltaY: ' + sprite.body.deltaY().toFixed(2)); + this.splitline('bounce x: ' + sprite.body.bounce.x.toFixed(2), 'y: ' + sprite.body.bounce.y.toFixed(2)); this.stop(); }, @@ -34086,17 +37177,15 @@ Phaser.Utils.Debug.prototype = { // 4 = scaleY // 5 = translateY - // this.line('id: ' + sprite._id); - // this.line('scale x: ' + sprite.worldTransform[0]); - // this.line('scale y: ' + sprite.worldTransform[4]); - // this.line('tx: ' + sprite.worldTransform[2]); - // this.line('ty: ' + sprite.worldTransform[5]); - // this.line('skew x: ' + sprite.worldTransform[3]); - // this.line('skew y: ' + sprite.worldTransform[1]); - this.line('deltaX: ' + sprite.body.deltaX()); - this.line('deltaY: ' + sprite.body.deltaY()); - // this.line('sdx: ' + sprite.deltaX()); - // this.line('sdy: ' + sprite.deltaY()); + this.line('id: ' + sprite._id); + this.line('scale x: ' + sprite.worldTransform[0]); + this.line('scale y: ' + sprite.worldTransform[4]); + this.line('tx: ' + sprite.worldTransform[2]); + this.line('ty: ' + sprite.worldTransform[5]); + this.line('skew x: ' + sprite.worldTransform[3]); + this.line('skew y: ' + sprite.worldTransform[1]); + this.line('sdx: ' + sprite.deltaX); + this.line('sdy: ' + sprite.deltaY); // this.line('inCamera: ' + this.game.renderer.spriteRenderer.inCamera(this.game.camera, sprite)); this.stop(); @@ -34104,65 +37193,13 @@ Phaser.Utils.Debug.prototype = { }, /** - * Render the World Transform information of the given Sprite. - * @method Phaser.Utils.Debug#renderWorldTransformInfo - * @param {Phaser.Sprite} sprite - Description. + * Renders the sprite coordinates in local, positional and world space. + * @method Phaser.Utils.Debug#renderSpriteCoords + * @param {Phaser.Sprite} line - The sprite to inspect. * @param {number} x - X position of the debug info to be rendered. * @param {number} y - Y position of the debug info to be rendered. * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string). */ - renderWorldTransformInfo: function (sprite, x, y, color) { - - if (this.context == null) - { - return; - } - - color = color || 'rgb(255, 255, 255)'; - - this.start(x, y, color); - - this.line('World Transform'); - this.line('skewX: ' + sprite.worldTransform[3]); - this.line('skewY: ' + sprite.worldTransform[1]); - this.line('scaleX: ' + sprite.worldTransform[0]); - this.line('scaleY: ' + sprite.worldTransform[4]); - this.line('transX: ' + sprite.worldTransform[2]); - this.line('transY: ' + sprite.worldTransform[5]); - this.stop(); - - }, - - /** - * Render the Local Transform information of the given Sprite. - * @method Phaser.Utils.Debug#renderLocalTransformInfo - * @param {Phaser.Sprite} sprite - Description. - * @param {number} x - X position of the debug info to be rendered. - * @param {number} y - Y position of the debug info to be rendered. - * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string). - */ - renderLocalTransformInfo: function (sprite, x, y, color) { - - if (this.context == null) - { - return; - } - - color = color || 'rgb(255, 255, 255)'; - - this.start(x, y, color); - - this.line('Local Transform'); - this.line('skewX: ' + sprite.localTransform[3]); - this.line('skewY: ' + sprite.localTransform[1]); - this.line('scaleX: ' + sprite.localTransform[0]); - this.line('scaleY: ' + sprite.localTransform[4]); - this.line('transX: ' + sprite.localTransform[2]); - this.line('transY: ' + sprite.localTransform[5]); - this.stop(); - - }, - renderSpriteCoords: function (sprite, x, y, color) { if (this.context == null) @@ -34172,29 +37209,28 @@ Phaser.Utils.Debug.prototype = { color = color || 'rgb(255, 255, 255)'; - this.start(x, y, color); + this.start(x, y, color, 100); if (sprite.name) { this.line(sprite.name); } - this.line('x: ' + sprite.x); - this.line('y: ' + sprite.y); - this.line('pos x: ' + sprite.position.x); - this.line('pos y: ' + sprite.position.y); - this.line('local x: ' + sprite.localTransform[2]); - this.line('local y: ' + sprite.localTransform[5]); - this.line('t x: ' + sprite.worldTransform[2]); - this.line('t y: ' + sprite.worldTransform[5]); - this.line('world x: ' + sprite.world.x); - this.line('world y: ' + sprite.world.y); + this.splitline('x:', sprite.x.toFixed(2), 'y:', sprite.y.toFixed(2)); + this.splitline('pos x:', sprite.position.x.toFixed(2), 'pos y:', sprite.position.y.toFixed(2)); + this.splitline('world x:', sprite.world.x.toFixed(2), 'world y:', sprite.world.y.toFixed(2)); this.stop(); }, - renderGroupInfo: function (group, x, y, color) { + /** + * Renders a Line object in the given color. + * @method Phaser.Utils.Debug#renderLine + * @param {Phaser.Line} line - The Line to render. + * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string). + */ + renderLine: function (line, color) { if (this.context == null) { @@ -34203,12 +37239,38 @@ Phaser.Utils.Debug.prototype = { color = color || 'rgb(255, 255, 255)'; - this.start(x, y, color); + this.start(0, 0, color); + this.context.lineWidth = 1; + this.context.beginPath(); + this.context.moveTo(line.start.x + 0.5, line.start.y + 0.5); + this.context.lineTo(line.end.x + 0.5, line.end.y + 0.5); + this.context.closePath(); + this.context.stroke(); + this.stop(); - this.line('Group (size: ' + group.length + ')'); - this.line('x: ' + group.x); - this.line('y: ' + group.y); + }, + /** + * Renders Line information in the given color. + * @method Phaser.Utils.Debug#renderLineInfo + * @param {Phaser.Line} line - The Line to render. + * @param {number} x - X position of the debug info to be rendered. + * @param {number} y - Y position of the debug info to be rendered. + * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string). + */ + renderLineInfo: function (line, x, y, color) { + + if (this.context == null) + { + return; + } + + color = color || 'rgb(255, 255, 255)'; + + this.start(x, y, color, 80); + this.splitline('start.x:', line.start.x.toFixed(2), 'start.y:', line.start.y.toFixed(2)); + this.splitline('end.x:', line.end.x.toFixed(2), 'end.y:', line.end.y.toFixed(2)); + this.splitline('length:', line.length.toFixed(2), 'angle:', line.angle); this.stop(); }, @@ -34237,24 +37299,36 @@ Phaser.Utils.Debug.prototype = { }, /** - * Renders just the Sprite.body bounds. - * @method Phaser.Utils.Debug#renderSpriteBody + * Renders just the full Sprite bounds. + * @method Phaser.Utils.Debug#renderSpriteBounds * @param {Phaser.Sprite} sprite - Description. * @param {string} [color] - Color of the debug info to be rendered (format is css color string). + * @param {boolean} [fill=false] - If false the bounds outline is rendered, if true the whole rectangle is rendered. */ - renderSpriteBody: function (sprite, color) { + renderSpriteBody: function (sprite, color, fill) { if (this.context == null) { return; } - color = color || 'rgba(255,0,255, 0.3)'; + color = color || 'rgb(255,0,255)'; + + if (typeof fill === 'undefined') { fill = false; } this.start(0, 0, color); - this.context.fillStyle = color; - this.context.fillRect(sprite.body.screenX, sprite.body.screenY, sprite.body.width, sprite.body.height); + if (fill) + { + this.context.fillStyle = color; + this.context.fillRect(sprite.body.left, sprite.body.top, sprite.body.width, sprite.body.height); + } + else + { + this.context.strokeStyle = color; + this.context.strokeRect(sprite.body.left, sprite.body.top, sprite.body.width, sprite.body.height); + this.context.stroke(); + } this.stop(); @@ -34416,90 +37490,114 @@ Phaser.Utils.Debug.prototype = { }, /** - * Dumps the Linked List to the console. - * - * @method Phaser.Utils.Debug#Phaser.LinkedList#dump - * @param {Phaser.LinkedList} list - The LinkedList to dump. + * @method Phaser.Utils.Debug#renderPhysicsBody + * @param {array} body + * @param {string} [color='rgb(255,255,255)'] - The color the polygon is stroked in. */ - dumpLinkedList: function (list) { + renderPhysicsBody: function (body, color, context) { - var spacing = 20; - - var output = "\n" + Phaser.Utils.pad('Node', spacing) + "|" + Phaser.Utils.pad('Next', spacing) + "|" + Phaser.Utils.pad('Previous', spacing) + "|" + Phaser.Utils.pad('First', spacing) + "|" + Phaser.Utils.pad('Last', spacing); - console.log(output); - - var output = Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing); - console.log(output); - - var entity = list; - - var testObject = entity.last.next; - entity = entity.first; - - do + if (this.context === null && context === null) { - var name = entity.sprite.name || '*'; - var nameNext = '-'; - var namePrev = '-'; - var nameFirst = '-'; - var nameLast = '-'; - - if (entity.next) - { - nameNext = entity.next.sprite.name; - } - - if (entity.prev) - { - namePrev = entity.prev.sprite.name; - } - - if (entity.first) - { - nameFirst = entity.first.sprite.name; - } - - if (entity.last) - { - nameLast = entity.last.sprite.name; - } - - if (typeof nameNext === 'undefined') - { - nameNext = '-'; - } - - if (typeof namePrev === 'undefined') - { - namePrev = '-'; - } - - if (typeof nameFirst === 'undefined') - { - nameFirst = '-'; - } - - if (typeof nameLast === 'undefined') - { - nameLast = '-'; - } - - var output = Phaser.Utils.pad(name, spacing) + "|" + Phaser.Utils.pad(nameNext, spacing) + "|" + Phaser.Utils.pad(namePrev, spacing) + "|" + Phaser.Utils.pad(nameFirst, spacing) + "|" + Phaser.Utils.pad(nameLast, spacing); - console.log(output); - - entity = entity.next; - + return; } - while(entity != testObject) + + color = color || 'rgb(255,255,255)'; + + var x = body.x - this.game.camera.x; + var y = body.y - this.game.camera.y; + + if (body.type === Phaser.Physics.Arcade.CIRCLE) + { + this.start(0, 0, color); + this.context.beginPath(); + this.context.strokeStyle = color; + this.context.arc(x, y, body.shape.r, 0, Math.PI * 2, false); + this.context.stroke(); + this.context.closePath(); + + // this.context.strokeStyle = 'rgb(0,0,255)'; + // this.context.strokeRect(body.left, body.top, body.width, body.height); + + this.stop(); + } + else + { + var points = body.polygon.points; + + this.start(0, 0, color); + + this.context.beginPath(); + this.context.moveTo(x + points[0].x, y + points[0].y); + + for (var i = 1; i < points.length; i++) + { + this.context.lineTo(x + points[i].x, y + points[i].y); + } + + this.context.closePath(); + this.context.strokeStyle = color; + this.context.stroke(); + + this.context.fillStyle = 'rgb(255,0,0)'; + this.context.fillRect(x + points[0].x - 2, y + points[0].y - 2, 5, 5); + + for (var i = 1; i < points.length; i++) + { + this.context.fillStyle = 'rgb(255,' + (i * 40) + ',0)'; + this.context.fillRect(x + points[i].x - 2, y + points[i].y - 2, 5, 5); + } + + // this.context.strokeStyle = 'rgb(0,255,255)'; + // this.context.strokeRect(body.left, body.top, body.width, body.height); + + this.stop(); + } + + }, + + /** + * @method Phaser.Utils.Debug#renderPolygon + * @param {array} polygon + * @param {string} [color='rgb(255,255,255)'] - The color the polygon is stroked in. + */ + renderPolygon: function (polygon, color, context) { + + if (this.context === null && context === null) + { + return; + } + + color = color || 'rgb(255,255,255)'; + + var points = polygon.points; + var x = polygon.pos.x; + var y = polygon.pos.y; + + this.start(0, 0, color); + + this.context.beginPath(); + this.context.moveTo(x + points[0].x, y + points[0].y); + + for (var i = 1; i < points.length; i++) + { + this.context.lineTo(x + points[i].x, y + points[i].y); + } + + this.context.closePath(); + this.context.strokeStyle = color; + this.context.stroke(); + + this.stop(); } - }; +Phaser.Utils.Debug.prototype.constructor = Phaser.Utils.Debug; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -34849,9 +37947,871 @@ Phaser.Color = { }; +// Version 0.2 - Copyright 2013 - Jim Riecken +// +// Released under the MIT License - https://github.com/jriecken/sat-js +// +// A simple library for determining intersections of circles and +// polygons using the Separating Axis Theorem. +/** @preserve SAT.js - Version 0.2 - Copyright 2013 - Jim Riecken - released under the MIT License. https://github.com/jriecken/sat-js */ + +/*global define: false, module: false*/ +/*jshint shadow:true, sub:true, forin:true, noarg:true, noempty:true, + eqeqeq:true, bitwise:true, strict:true, undef:true, + curly:true, browser:true */ + +// Create a UMD wrapper for SAT. Works in: +// +// - Plain browser via global SAT variable +// - AMD loader (like require.js) +// - Node.js +// +// The quoted properties all over the place are used so that the Closure Compiler +// does not mangle the exposed API in advanced mode. +/** + * @param {*} root - The global scope + * @param {Function} factory - Factory that creates SAT module + */ +(function (root, factory) { + "use strict"; + if (typeof define === 'function' && define['amd']) { + define(factory); + } else if (typeof exports === 'object') { + module['exports'] = factory(); + } else { + root['SAT'] = factory(); + } +}(this, function () { + "use strict"; + + var SAT = {}; + + // + // ## Vector + // + // Represents a vector in two dimensions with `x` and `y` properties. + + + // Create a new Vector, optionally passing in the `x` and `y` coordinates. If + // a coordinate is not specified, it will be set to `0` + /** + * @param {?number=} x The x position. + * @param {?number=} y The y position. + * @constructor + */ + function Vector(x, y) { + this['x'] = x || 0; + this['y'] = y || 0; + } + SAT['Vector'] = Vector; + // Alias `Vector` as `V` + SAT['V'] = Vector; + + + // Copy the values of another Vector into this one. + /** + * @param {Vector} other The other Vector. + * @return {Vector} This for chaining. + */ + Vector.prototype['copy'] = Vector.prototype.copy = function(other) { + this['x'] = other['x']; + this['y'] = other['y']; + return this; + }; + + // Change this vector to be perpendicular to what it was before. (Effectively + // roatates it 90 degrees in a clockwise direction) + /** + * @return {Vector} This for chaining. + */ + Vector.prototype['perp'] = Vector.prototype.perp = function() { + var x = this['x']; + this['x'] = this['y']; + this['y'] = -x; + return this; + }; + + // Rotate this vector (counter-clockwise) by the specified angle (in radians). + /** + * @param {number} angle The angle to rotate (in radians) + * @return {Vector} This for chaining. + */ + Vector.prototype['rotate'] = Vector.prototype.rotate = function (angle) { + var x = this['x']; + var y = this['y']; + this['x'] = x * Math.cos(angle) - y * Math.sin(angle); + this['y'] = x * Math.sin(angle) + y * Math.cos(angle); + return this; + }; + + // Rotate this vector (counter-clockwise) by the specified angle (in radians) which has already been calculated into sin and cos. + /** + * @param {number} sin - The Math.sin(angle) + * @param {number} cos - The Math.cos(angle) + * @return {Vector} This for chaining. + */ + Vector.prototype['rotatePrecalc'] = Vector.prototype.rotatePrecalc = function (sin, cos) { + var x = this['x']; + var y = this['y']; + this['x'] = x * cos - y * sin; + this['y'] = x * sin + y * cos; + return this; + }; + + // Reverse this vector. + /** + * @return {Vector} This for chaining. + */ + Vector.prototype['reverse'] = Vector.prototype.reverse = function() { + this['x'] = -this['x']; + this['y'] = -this['y']; + return this; + }; + + + // Normalize this vector. (make it have length of `1`) + /** + * @return {Vector} This for chaining. + */ + Vector.prototype['normalize'] = Vector.prototype.normalize = function() { + var d = this.len(); + if(d > 0) { + this['x'] = this['x'] / d; + this['y'] = this['y'] / d; + } + return this; + }; + + // Add another vector to this one. + /** + * @param {Vector} other The other Vector. + * @return {Vector} This for chaining. + */ + Vector.prototype['add'] = Vector.prototype.add = function(other) { + this['x'] += other['x']; + this['y'] += other['y']; + return this; + }; + + // Subtract another vector from this one. + /** + * @param {Vector} other The other Vector. + * @return {Vector} This for chaiing. + */ + Vector.prototype['sub'] = Vector.prototype.sub = function(other) { + this['x'] -= other['x']; + this['y'] -= other['y']; + return this; + }; + + // Scale this vector. An independant scaling factor can be provided + // for each axis, or a single scaling factor that will scale both `x` and `y`. + /** + * @param {number} x The scaling factor in the x direction. + * @param {?number=} y The scaling factor in the y direction. If this + * is not specified, the x scaling factor will be used. + * @return {Vector} This for chaining. + */ + Vector.prototype['scale'] = Vector.prototype.scale = function(x,y) { + this['x'] *= x; + this['y'] *= y || x; + return this; + }; + + // Project this vector on to another vector. + /** + * @param {Vector} other The vector to project onto. + * @return {Vector} This for chaining. + */ + Vector.prototype['project'] = Vector.prototype.project = function(other) { + var amt = this.dot(other) / other.len2(); + this['x'] = amt * other['x']; + this['y'] = amt * other['y']; + return this; + }; + + // Project this vector onto a vector of unit length. This is slightly more efficient + // than `project` when dealing with unit vectors. + /** + * @param {Vector} other The unit vector to project onto. + * @return {Vector} This for chaining. + */ + Vector.prototype['projectN'] = Vector.prototype.projectN = function(other) { + var amt = this.dot(other); + this['x'] = amt * other['x']; + this['y'] = amt * other['y']; + return this; + }; + + // Reflect this vector on an arbitrary axis. + /** + * @param {Vector} axis The vector representing the axis. + * @return {Vector} This for chaining. + */ + Vector.prototype['reflect'] = Vector.prototype.reflect = function(axis) { + var x = this['x']; + var y = this['y']; + this.project(axis).scale(2); + this['x'] -= x; + this['y'] -= y; + return this; + }; + + // Reflect this vector on an arbitrary axis (represented by a unit vector). This is + // slightly more efficient than `reflect` when dealing with an axis that is a unit vector. + /** + * @param {Vector} axis The unit vector representing the axis. + * @return {Vector} This for chaining. + */ + Vector.prototype['reflectN'] = Vector.prototype.reflectN = function(axis) { + var x = this['x']; + var y = this['y']; + this.projectN(axis).scale(2); + this['x'] -= x; + this['y'] -= y; + return this; + }; + + // Get the dot product of this vector and another. + /** + * @param {Vector} other The vector to dot this one against. + * @return {number} The dot product. + */ + Vector.prototype['dot'] = Vector.prototype.dot = function(other) { + return this['x'] * other['x'] + this['y'] * other['y']; + }; + + // Get the squared length of this vector. + /** + * @return {number} The length^2 of this vector. + */ + Vector.prototype['len2'] = Vector.prototype.len2 = function() { + return this.dot(this); + }; + + // Get the length of this vector. + /** + * @return {number} The length of this vector. + */ + Vector.prototype['len'] = Vector.prototype.len = function() { + return Math.sqrt(this.len2()); + }; + + // ## Circle + // + // Represents a circle with a position and a radius. + + // Create a new circle, optionally passing in a position and/or radius. If no position + // is given, the circle will be at `(0,0)`. If no radius is provided, the circle will + // have a radius of `0`. + /** + * @param {Vector=} pos A vector representing the position of the center of the circle + * @param {?number=} r The radius of the circle + * @constructor + */ + function Circle(pos, r) { + this['pos'] = pos || new Vector(); + this['r'] = r || 0; + } + SAT['Circle'] = Circle; + + // ## Polygon + // + // Represents a *convex* polygon with any number of points (specified in counter-clockwise order) + // + // The edges/normals of the polygon will be calculated on creation and stored in the + // `edges` and `normals` properties. If you change the polygon's points, you will need + // to call `recalc` to recalculate the edges/normals. + + // Create a new polygon, passing in a position vector, and an array of points (represented + // by vectors relative to the position vector). If no position is passed in, the position + // of the polygon will be `(0,0)`. + /** + * @param {Vector=} pos A vector representing the origin of the polygon. (all other + * points are relative to this one) + * @param {Array.=} points An array of vectors representing the points in the polygon, + * in counter-clockwise order. + * @constructor + */ + function Polygon(pos, points) { + this['pos'] = pos || new Vector(); + this['points'] = points || []; + this.recalc(); + } + SAT['Polygon'] = Polygon; + + // Recalculates the edges and normals of the polygon. This **must** be called + // if the `points` array is modified at all and the edges or normals are to be + // accessed. + /** + * @return {Polygon} This for chaining. + */ + Polygon.prototype['recalc'] = Polygon.prototype.recalc = function() { + // The edges here are the direction of the `n`th edge of the polygon, relative to + // the `n`th point. If you want to draw a given edge from the edge value, you must + // first translate to the position of the starting point. + this['edges'] = []; + // The normals here are the direction of the normal for the `n`th edge of the polygon, relative + // to the position of the `n`th point. If you want to draw an edge normal, you must first + // translate to the position of the starting point. + this['normals'] = []; + var points = this['points']; + var len = points.length; + for (var i = 0; i < len; i++) { + var p1 = points[i]; + var p2 = i < len - 1 ? points[i + 1] : points[0]; + var e = new Vector().copy(p2).sub(p1); + var n = new Vector().copy(e).perp().normalize(); + this['edges'].push(e); + this['normals'].push(n); + } + return this; + }; + + // Rotates this polygon counter-clockwise around the origin of *its local coordinate system* (i.e. `pos`). + // + // Note: You do **not** need to call `recalc` after rotation. + /** + * @param {number} angle The angle to rotate (in radians) + * @return {Polygon} This for chaining. + */ + Polygon.prototype['rotate'] = Polygon.prototype.rotate = function(angle) { + var i; + var points = this['points']; + var edges = this['edges']; + var normals = this['normals']; + var len = points.length; + + // Calc it just the once, rather than 4 times per array element + var cos = Math.cos(angle); + var sin = Math.sin(angle); + + for (i = 0; i < len; i++) { + points[i].rotatePrecalc(sin, cos); + edges[i].rotatePrecalc(sin, cos); + normals[i].rotatePrecalc(sin, cos); + } + return this; + }; + + // Rotates this polygon counter-clockwise around the origin of *its local coordinate system* (i.e. `pos`). + // + // Note: You do **not** need to call `recalc` after rotation. + /** + * @param {number} angle The angle to rotate (in radians) + * @return {Polygon} This for chaining. + */ + Polygon.prototype['scale'] = Polygon.prototype.scale = function(x, y) { + var i; + var points = this['points']; + var edges = this['edges']; + var normals = this['normals']; + var len = points.length; + for (i = 0; i < len; i++) { + points[i].scale(x,y); + edges[i].scale(x,y); + normals[i].scale(x,y); + } + return this; + }; + + // Translates the points of this polygon by a specified amount relative to the origin of *its own coordinate + // system* (i.e. `pos`). + // + // This is most useful to change the "center point" of a polygon. + // + // Note: You do **not** need to call `recalc` after translation. + /** + * @param {number} x The horizontal amount to translate. + * @param {number} y The vertical amount to translate. + * @return {Polygon} This for chaining. + */ + Polygon.prototype['translate'] = Polygon.prototype.translate = function (x, y) { + var i; + var points = this['points']; + var len = points.length; + for (i = 0; i < len; i++) { + points[i].x += x; + points[i].y += y; + } + return this; + }; + + // ## Box + // + // Represents an axis-aligned box, with a width and height. + + + // Create a new box, with the specified position, width, and height. If no position + // is given, the position will be `(0,0)`. If no width or height are given, they will + // be set to `0`. + /** + * @param {Vector=} pos A vector representing the top-left of the box. + * @param {?number=} w The width of the box. + * @param {?number=} h The height of the box. + * @constructor + */ + function Box(pos, w, h) { + this['pos'] = pos || new Vector(); + this['w'] = w || 0; + this['h'] = h || 0; + } + SAT['Box'] = Box; + + // Returns a polygon whose edges are the same as this box. + /** + * @return {Polygon} A new Polygon that represents this box. + */ + Box.prototype['toPolygon'] = Box.prototype.toPolygon = function() { + var pos = this['pos']; + var w = this['w']; + var h = this['h']; + return new Polygon(new Vector(pos['x'], pos['y']), [ + new Vector(), new Vector(w, 0), + new Vector(w,h), new Vector(0,h) + ]); + }; + + // ## Response + // + // An object representing the result of an intersection. Contains: + // - The two objects participating in the intersection + // - The vector representing the minimum change necessary to extract the first object + // from the second one (as well as a unit vector in that direction and the magnitude + // of the overlap) + // - Whether the first object is entirely inside the second, and vice versa. + /** + * @constructor + */ + function Response() { + this['a'] = null; + this['b'] = null; + this['overlapN'] = new Vector(); + this['overlapV'] = new Vector(); + this.clear(); + } + SAT['Response'] = Response; + + // Set some values of the response back to their defaults. Call this between tests if + // you are going to reuse a single Response object for multiple intersection tests (recommented + // as it will avoid allcating extra memory) + /** + * @return {Response} This for chaining + */ + Response.prototype['clear'] = Response.prototype.clear = function() { + this['aInB'] = true; + this['bInA'] = true; + this['overlap'] = Number.MAX_VALUE; + return this; + }; + + // ## Object Pools + + // A pool of `Vector` objects that are used in calculations to avoid + // allocating memory. + /** + * @type {Array.} + */ + var T_VECTORS = []; + for (var i = 0; i < 10; i++) { T_VECTORS.push(new Vector()); } + + // A pool of arrays of numbers used in calculations to avoid allocating + // memory. + /** + * @type {Array.>} + */ + var T_ARRAYS = []; + for (var i = 0; i < 5; i++) { T_ARRAYS.push([]); } + + // ## Helper Functions + + // Flattens the specified array of points onto a unit vector axis, + // resulting in a one dimensional range of the minimum and + // maximum value on that axis. + /** + * @param {Array.} points The points to flatten. + * @param {Vector} normal The unit vector axis to flatten on. + * @param {Array.} result An array. After calling this function, + * result[0] will be the minimum value, + * result[1] will be the maximum value. + */ + function flattenPointsOn(points, normal, result) { + var min = Number.MAX_VALUE; + var max = -Number.MAX_VALUE; + var len = points.length; + for (var i = 0; i < len; i++ ) { + // The magnitude of the projection of the point onto the normal + var dot = points[i].dot(normal); + if (dot < min) { min = dot; } + if (dot > max) { max = dot; } + } + result[0] = min; result[1] = max; + } + + // Check whether two convex polygons are separated by the specified + // axis (must be a unit vector). + /** + * @param {Vector} aPos The position of the first polygon. + * @param {Vector} bPos The position of the second polygon. + * @param {Array.} aPoints The points in the first polygon. + * @param {Array.} bPoints The points in the second polygon. + * @param {Vector} axis The axis (unit sized) to test against. The points of both polygons + * will be projected onto this axis. + * @param {Response=} response A Response object (optional) which will be populated + * if the axis is not a separating axis. + * @return {boolean} true if it is a separating axis, false otherwise. If false, + * and a response is passed in, information about how much overlap and + * the direction of the overlap will be populated. + */ + function isSeparatingAxis(aPos, bPos, aPoints, bPoints, axis, response) { + var rangeA = T_ARRAYS.pop(); + var rangeB = T_ARRAYS.pop(); + // The magnitude of the offset between the two polygons + var offsetV = T_VECTORS.pop().copy(bPos).sub(aPos); + var projectedOffset = offsetV.dot(axis); + // Project the polygons onto the axis. + flattenPointsOn(aPoints, axis, rangeA); + flattenPointsOn(bPoints, axis, rangeB); + // Move B's range to its position relative to A. + rangeB[0] += projectedOffset; + rangeB[1] += projectedOffset; + // Check if there is a gap. If there is, this is a separating axis and we can stop + if (rangeA[0] > rangeB[1] || rangeB[0] > rangeA[1]) { + T_VECTORS.push(offsetV); + T_ARRAYS.push(rangeA); + T_ARRAYS.push(rangeB); + return true; + } + // This is not a separating axis. If we're calculating a response, calculate the overlap. + if (response) { + var overlap = 0; + // A starts further left than B + if (rangeA[0] < rangeB[0]) { + response['aInB'] = false; + // A ends before B does. We have to pull A out of B + if (rangeA[1] < rangeB[1]) { + overlap = rangeA[1] - rangeB[0]; + response['bInA'] = false; + // B is fully inside A. Pick the shortest way out. + } else { + var option1 = rangeA[1] - rangeB[0]; + var option2 = rangeB[1] - rangeA[0]; + overlap = option1 < option2 ? option1 : -option2; + } + // B starts further left than A + } else { + response['bInA'] = false; + // B ends before A ends. We have to push A out of B + if (rangeA[1] > rangeB[1]) { + overlap = rangeA[0] - rangeB[1]; + response['aInB'] = false; + // A is fully inside B. Pick the shortest way out. + } else { + var option1 = rangeA[1] - rangeB[0]; + var option2 = rangeB[1] - rangeA[0]; + overlap = option1 < option2 ? option1 : -option2; + } + } + // If this is the smallest amount of overlap we've seen so far, set it as the minimum overlap. + var absOverlap = Math.abs(overlap); + if (absOverlap < response['overlap']) { + response['overlap'] = absOverlap; + response['overlapN'].copy(axis); + if (overlap < 0) { + response['overlapN'].reverse(); + } + } + } + T_VECTORS.push(offsetV); + T_ARRAYS.push(rangeA); + T_ARRAYS.push(rangeB); + return false; + } + + // Calculates which Vornoi region a point is on a line segment. + // It is assumed that both the line and the point are relative to `(0,0)` + // + // | (0) | + // (-1) [S]--------------[E] (1) + // | (0) | + /** + * @param {Vector} line The line segment. + * @param {Vector} point The point. + * @return {number} LEFT_VORNOI_REGION (-1) if it is the left region, + * MIDDLE_VORNOI_REGION (0) if it is the middle region, + * RIGHT_VORNOI_REGION (1) if it is the right region. + */ + function vornoiRegion(line, point) { + var len2 = line.len2(); + var dp = point.dot(line); + // If the point is beyond the start of the line, it is in the + // left vornoi region. + if (dp < 0) { return LEFT_VORNOI_REGION; } + // If the point is beyond the end of the line, it is in the + // right vornoi region. + else if (dp > len2) { return RIGHT_VORNOI_REGION; } + // Otherwise, it's in the middle one. + else { return MIDDLE_VORNOI_REGION; } + } + // Constants for Vornoi regions + /** + * @const + */ + var LEFT_VORNOI_REGION = -1; + /** + * @const + */ + var MIDDLE_VORNOI_REGION = 0; + /** + * @const + */ + var RIGHT_VORNOI_REGION = 1; + + // ## Collision Tests + + // Check if two circles collide. + /** + * @param {Circle} a The first circle. + * @param {Circle} b The second circle. + * @param {Response=} response Response object (optional) that will be populated if + * the circles intersect. + * @return {boolean} true if the circles intersect, false if they don't. + */ + function testCircleCircle(a, b, response) { + // Check if the distance between the centers of the two + // circles is greater than their combined radius. + var differenceV = T_VECTORS.pop().copy(b['pos']).sub(a['pos']); + var totalRadius = a['r'] + b['r']; + var totalRadiusSq = totalRadius * totalRadius; + var distanceSq = differenceV.len2(); + // If the distance is bigger than the combined radius, they don't intersect. + if (distanceSq > totalRadiusSq) { + T_VECTORS.push(differenceV); + return false; + } + // They intersect. If we're calculating a response, calculate the overlap. + if (response) { + var dist = Math.sqrt(distanceSq); + response['a'] = a; + response['b'] = b; + response['overlap'] = totalRadius - dist; + response['overlapN'].copy(differenceV.normalize()); + response['overlapV'].copy(differenceV).scale(response['overlap']); + response['aInB']= a['r'] <= b['r'] && dist <= b['r'] - a['r']; + response['bInA'] = b['r'] <= a['r'] && dist <= a['r'] - b['r']; + } + T_VECTORS.push(differenceV); + return true; + } + SAT['testCircleCircle'] = testCircleCircle; + + // Check if a polygon and a circle collide. + /** + * @param {Polygon} polygon The polygon. + * @param {Circle} circle The circle. + * @param {Response=} response Response object (optional) that will be populated if + * they interset. + * @return {boolean} true if they intersect, false if they don't. + */ + function testPolygonCircle(polygon, circle, response) { + // Get the position of the circle relative to the polygon. + var circlePos = T_VECTORS.pop().copy(circle['pos']).sub(polygon['pos']); + var radius = circle['r']; + var radius2 = radius * radius; + var points = polygon['points']; + var len = points.length; + var edge = T_VECTORS.pop(); + var point = T_VECTORS.pop(); + + // For each edge in the polygon: + for (var i = 0; i < len; i++) { + var next = i === len - 1 ? 0 : i + 1; + var prev = i === 0 ? len - 1 : i - 1; + var overlap = 0; + var overlapN = null; + + // Get the edge. + edge.copy(polygon['edges'][i]); + // Calculate the center of the circle relative to the starting point of the edge. + point.copy(circlePos).sub(points[i]); + + // If the distance between the center of the circle and the point + // is bigger than the radius, the polygon is definitely not fully in + // the circle. + if (response && point.len2() > radius2) { + response['aInB'] = false; + } + + // Calculate which Vornoi region the center of the circle is in. + var region = vornoiRegion(edge, point); + // If it's the left region: + if (region === LEFT_VORNOI_REGION) { + // We need to make sure we're in the RIGHT_VORNOI_REGION of the previous edge. + edge.copy(polygon['edges'][prev]); + // Calculate the center of the circle relative the starting point of the previous edge + var point2 = T_VECTORS.pop().copy(circlePos).sub(points[prev]); + region = vornoiRegion(edge, point2); + if (region === RIGHT_VORNOI_REGION) { + // It's in the region we want. Check if the circle intersects the point. + var dist = point.len(); + if (dist > radius) { + // No intersection + T_VECTORS.push(circlePos); + T_VECTORS.push(edge); + T_VECTORS.push(point); + T_VECTORS.push(point2); + return false; + } else if (response) { + // It intersects, calculate the overlap. + response['bInA'] = false; + overlapN = point.normalize(); + overlap = radius - dist; + } + } + T_VECTORS.push(point2); + // If it's the right region: + } else if (region === RIGHT_VORNOI_REGION) { + // We need to make sure we're in the left region on the next edge + edge.copy(polygon['edges'][next]); + // Calculate the center of the circle relative to the starting point of the next edge. + point.copy(circlePos).sub(points[next]); + region = vornoiRegion(edge, point); + if (region === LEFT_VORNOI_REGION) { + // It's in the region we want. Check if the circle intersects the point. + var dist = point.len(); + if (dist > radius) { + // No intersection + T_VECTORS.push(circlePos); + T_VECTORS.push(edge); + T_VECTORS.push(point); + return false; + } else if (response) { + // It intersects, calculate the overlap. + response['bInA'] = false; + overlapN = point.normalize(); + overlap = radius - dist; + } + } + // Otherwise, it's the middle region: + } else { + // Need to check if the circle is intersecting the edge, + // Change the edge into its "edge normal". + var normal = edge.perp().normalize(); + // Find the perpendicular distance between the center of the + // circle and the edge. + var dist = point.dot(normal); + var distAbs = Math.abs(dist); + // If the circle is on the outside of the edge, there is no intersection. + if (dist > 0 && distAbs > radius) { + // No intersection + T_VECTORS.push(circlePos); + T_VECTORS.push(normal); + T_VECTORS.push(point); + return false; + } else if (response) { + // It intersects, calculate the overlap. + overlapN = normal; + overlap = radius - dist; + // If the center of the circle is on the outside of the edge, or part of the + // circle is on the outside, the circle is not fully inside the polygon. + if (dist >= 0 || overlap < 2 * radius) { + response['bInA'] = false; + } + } + } + + // If this is the smallest overlap we've seen, keep it. + // (overlapN may be null if the circle was in the wrong Vornoi region). + if (overlapN && response && Math.abs(overlap) < Math.abs(response['overlap'])) { + response['overlap'] = overlap; + response['overlapN'].copy(overlapN); + } + } + + // Calculate the final overlap vector - based on the smallest overlap. + if (response) { + response['a'] = polygon; + response['b'] = circle; + response['overlapV'].copy(response['overlapN']).scale(response['overlap']); + } + T_VECTORS.push(circlePos); + T_VECTORS.push(edge); + T_VECTORS.push(point); + return true; + } + SAT['testPolygonCircle'] = testPolygonCircle; + + // Check if a circle and a polygon collide. + // + // **NOTE:** This is slightly less efficient than polygonCircle as it just + // runs polygonCircle and reverses everything at the end. + /** + * @param {Circle} circle The circle. + * @param {Polygon} polygon The polygon. + * @param {Response=} response Response object (optional) that will be populated if + * they interset. + * @return {boolean} true if they intersect, false if they don't. + */ + function testCirclePolygon(circle, polygon, response) { + // Test the polygon against the circle. + var result = testPolygonCircle(polygon, circle, response); + if (result && response) { + // Swap A and B in the response. + var a = response['a']; + var aInB = response['aInB']; + response['overlapN'].reverse(); + response['overlapV'].reverse(); + response['a'] = response['b']; + response['b'] = a; + response['aInB'] = response['bInA']; + response['bInA'] = aInB; + } + return result; + } + SAT['testCirclePolygon'] = testCirclePolygon; + + // Checks whether polygons collide. + /** + * @param {Polygon} a The first polygon. + * @param {Polygon} b The second polygon. + * @param {Response=} response Response object (optional) that will be populated if + * they interset. + * @return {boolean} true if they intersect, false if they don't. + */ + function testPolygonPolygon(a, b, response) { + var aPoints = a['points']; + var aLen = aPoints.length; + var bPoints = b['points']; + var bLen = bPoints.length; + // If any of the edge normals of A is a separating axis, no intersection. + for (var i = 0; i < aLen; i++) { + if (isSeparatingAxis(a['pos'], b['pos'], aPoints, bPoints, a['normals'][i], response)) { + return false; + } + } + // If any of the edge normals of B is a separating axis, no intersection. + for (var i = 0;i < bLen; i++) { + if (isSeparatingAxis(a['pos'], b['pos'], aPoints, bPoints, b['normals'][i], response)) { + return false; + } + } + // Since none of the edge normals of A or B are a separating axis, there is an intersection + // and we've already calculated the smallest overlap (in isSeparatingAxis). Calculate the + // final overlap vector. + if (response) { + response['a'] = a; + response['b'] = b; + response['overlapV'].copy(response['overlapN']).scale(response['overlap']); + } + return true; + } + SAT['testPolygonPolygon'] = testPolygonPolygon; + + return SAT; +})); /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -34881,9 +38841,34 @@ Phaser.Physics.Arcade = function (game) { this.gravity = new Phaser.Point(); /** - * @property {Phaser.Rectangle} bounds - The bounds inside of which the physics world exists. Defaults to match the world bounds. + * @property {SAT.Box} worldLeft - The left hand side of the physics bounds. */ - this.bounds = new Phaser.Rectangle(0, 0, game.world.width, game.world.height); + this.worldLeft = null; + + /** + * @property {SAT.Box} worldRight - The right hand side of the physics bounds. + */ + this.worldRight = null; + + /** + * @property {SAT.Box} worldTop - The top side of the physics bounds. + */ + this.worldTop = null; + + /** + * @property {SAT.Box} worldBottom - The bottom of the physics bounds. + */ + this.worldBottom = null; + + /** + * @property {array} worldPolys - An array of the polygon data from the physics bounds. + */ + this.worldPolys = [ null, null, null, null ]; + + /** + * @property {Phaser.QuadTree} quadTree - The world QuadTree. + */ + this.quadTree = new Phaser.QuadTree(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels); /** * @property {number} maxObjects - Used by the QuadTree to set the maximum number of objects per quad. @@ -34895,77 +38880,6 @@ Phaser.Physics.Arcade = function (game) { */ this.maxLevels = 4; - /** - * @property {number} OVERLAP_BIAS - A value added to the delta values during collision checks. - */ - this.OVERLAP_BIAS = 4; - - /** - * @property {Phaser.QuadTree} quadTree - The world QuadTree. - */ - this.quadTree = new Phaser.QuadTree(this, this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels); - - /** - * @property {number} quadTreeID - The QuadTree ID. - */ - this.quadTreeID = 0; - - // Avoid gc spikes by caching these values for re-use - - /** - * @property {Phaser.Rectangle} _bounds1 - Internal cache var. - * @private - */ - this._bounds1 = new Phaser.Rectangle(); - - /** - * @property {Phaser.Rectangle} _bounds2 - Internal cache var. - * @private - */ - this._bounds2 = new Phaser.Rectangle(); - - /** - * @property {number} _overlap - Internal cache var. - * @private - */ - this._overlap = 0; - - /** - * @property {number} _maxOverlap - Internal cache var. - * @private - */ - this._maxOverlap = 0; - - /** - * @property {number} _velocity1 - Internal cache var. - * @private - */ - this._velocity1 = 0; - - /** - * @property {number} _velocity2 - Internal cache var. - * @private - */ - this._velocity2 = 0; - - /** - * @property {number} _newVelocity1 - Internal cache var. - * @private - */ - this._newVelocity1 = 0; - - /** - * @property {number} _newVelocity2 - Internal cache var. - * @private - */ - this._newVelocity2 = 0; - - /** - * @property {number} _average - Internal cache var. - * @private - */ - this._average = 0; - /** * @property {Array} _mapData - Internal cache var. * @private @@ -34996,6 +38910,12 @@ Phaser.Physics.Arcade = function (game) { */ this._angle = 0; + /** + * @property {number} _drag - Internal cache var. + * @private + */ + this._drag = 0; + /** * @property {number} _dx - Internal cache var. * @private @@ -35008,10 +38928,212 @@ Phaser.Physics.Arcade = function (game) { */ this._dy = 0; + /** + * @property {Phaser.Point} _p - Internal cache var. + * @private + */ + this._p = new Phaser.Point(0, 0); + + /** + * @property {number} _intersection - Internal cache var. + * @private + */ + this._intersection = [0,0,0,0]; + + /** + * @property {number} _gravityX - Internal cache var. + * @private + */ + this._gravityX = 0; + + /** + * @property {number} _gravityY - Internal cache var. + * @private + */ + this._gravityY = 0; + + /** + * @property {SAT.Response} _response - Internal cache var. + * @private + */ + this._response = new SAT.Response(); + + // Set the bounds to the world as default + this.setBoundsToWorld(true, true, true, true); + }; +/** +* @constant +* @type {number} +*/ +Phaser.Physics.Arcade.RECT = 0; + +/** +* @constant +* @type {number} +*/ +Phaser.Physics.Arcade.CIRCLE = 1; + +/** +* @constant +* @type {number} +*/ +Phaser.Physics.Arcade.POLYGON = 2; + Phaser.Physics.Arcade.prototype = { + /** + * Checks the given Physics.Body against the Physics Bounds, if any are set, and separates them, setting the blocked flags on the Body as it does so. + * + * @method Phaser.Physics.Arcade#checkBounds + * @param {Phaser.Physics.Arcade.Body} The Body object to be checked. + * @return {boolean} True if the body hit the bounds, otherwise false. + */ + checkBounds: function (body) { + + if (!body.collideWorldBounds || (!this.worldLeft && !this.worldRight && !this.worldTop && !this.worldBottom)) + { + return false; + } + + this._response.clear(); + + var test = SAT.testPolygonPolygon; + var part = body.polygon; + var rebounded = false; + + if (body.type === Phaser.Physics.Arcade.CIRCLE) + { + test = SAT.testPolygonCircle; + part = body.shape; + } + + if (this.worldLeft && test(this.worldPolys[0], part, this._response)) + { + body.blocked.left = true; + part.pos.add(this._response.overlapV); + body.blocked.x = Math.floor(body.x); + body.blocked.y = Math.floor(body.y); + rebounded = true; + } + else if (this.worldRight && test(this.worldPolys[1], part, this._response)) + { + body.blocked.right = true; + part.pos.add(this._response.overlapV); + body.blocked.x = Math.floor(body.x); + body.blocked.y = Math.floor(body.y); + rebounded = true; + } + + this._response.clear(); + + if (this.worldTop && test(this.worldPolys[2], part, this._response)) + { + body.blocked.up = true; + part.pos.add(this._response.overlapV); + body.blocked.x = Math.floor(body.x); + body.blocked.y = Math.floor(body.y); + rebounded = true; + } + else if (this.worldBottom && test(this.worldPolys[3], part, this._response)) + { + body.blocked.down = true; + part.pos.add(this._response.overlapV); + body.blocked.x = Math.floor(body.x); + body.blocked.y = Math.floor(body.y); + rebounded = true; + } + + return rebounded; + + }, + + /** + * Sets the bounds of the Physics world to match the Game.World. + * You can optionally set which 'walls' to create: left, right, top or bottom. + * + * @method Phaser.Physics.Arcade#setBoundsToWorld + * @param {boolean} [left=true] - If true will create the left bounds wall. + * @param {boolean} [right=true] - If true will create the right bounds wall. + * @param {boolean} [top=true] - If true will create the top bounds wall. + * @param {boolean} [bottom=true] - If true will create the bottom bounds wall. + */ + setBoundsToWorld: function (left, right, top, bottom) { + + this.setBounds(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, left, right, top, bottom); + + }, + + /** + * Sets the bounds of the Physics world to match the given world pixel dimensions. + * You can optionally set which 'walls' to create: left, right, top or bottom. + * + * @method Phaser.Physics.Arcade#setBounds + * @param {number} x - The x coordinate of the top-left corner of the bounds. + * @param {number} y - The y coordinate of the top-left corner of the bounds. + * @param {number} width - The width of the bounds. + * @param {number} height - The height of the bounds. + * @param {boolean} [left=true] - If true will create the left bounds wall. + * @param {boolean} [right=true] - If true will create the right bounds wall. + * @param {boolean} [top=true] - If true will create the top bounds wall. + * @param {boolean} [bottom=true] - If true will create the bottom bounds wall. + */ + setBounds: function (x, y, width, height, left, right, top, bottom) { + + if (typeof left === 'undefined') { left = true; } + if (typeof right === 'undefined') { right = true; } + if (typeof top === 'undefined') { top = true; } + if (typeof bottom === 'undefined') { bottom = true; } + + var thickness = 100; + + if (left) + { + this.worldLeft = new SAT.Box(new SAT.Vector(x - thickness, y), thickness, height); + this.worldPolys[0] = this.worldLeft.toPolygon(); + } + else + { + this.worldLeft = null; + this.worldPolys[0] = null; + } + + if (right) + { + this.worldRight = new SAT.Box(new SAT.Vector(x + width, y), thickness, height); + this.worldPolys[1] = this.worldRight.toPolygon(); + } + else + { + this.worldRight = null; + this.worldPolys[1] = null; + } + + if (top) + { + this.worldTop = new SAT.Box(new SAT.Vector(x, y - thickness), width, thickness); + this.worldPolys[2] = this.worldTop.toPolygon(); + } + else + { + this.worldTop = null; + this.worldPolys[2] = null; + } + + if (bottom) + { + this.worldBottom = new SAT.Box(new SAT.Vector(x, y + height), width, thickness); + this.worldPolys[3] = this.worldBottom.toPolygon(); + } + else + { + this.worldBottom = null; + this.worldPolys[3] = null; + } + + }, + /** * Called automatically by a Physics body, it updates all motion related values on the Body. * @@ -35022,113 +39144,68 @@ Phaser.Physics.Arcade.prototype = { // If you're wondering why the velocity is halved and applied twice, read this: http://www.niksula.hut.fi/~hkankaan/Homepages/gravity.html + // World gravity is allowed + if (body.allowGravity) + { + this._gravityX = this.gravity.x + body.gravity.x; + this._gravityY = this.gravity.y + body.gravity.y; + } + else + { + this._gravityX = body.gravity.x; + this._gravityY = body.gravity.y; + } + + // Don't apply gravity to any body that is blocked + if ((this._gravityX < 0 && body.blocked.left) || (this._gravityX > 0 && body.blocked.right)) + { + this._gravityX = 0; + } + + if ((this._gravityY < 0 && body.blocked.up) || (this._gravityY > 0 && body.blocked.down)) + { + this._gravityY = 0; + } + // Rotation - this._velocityDelta = (this.computeVelocity(0, body, body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) * this.game.time.physicsElapsed * 0.5 * 60; - body.angularVelocity += this._velocityDelta; - body.rotation += (body.angularVelocity * this.game.time.physicsElapsed); - body.angularVelocity += this._velocityDelta; - - // Horizontal - this._velocityDelta = (this.computeVelocity(1, body, body.velocity.x, body.acceleration.x, body.drag.x, body.maxVelocity.x) - body.velocity.x) * this.game.time.physicsElapsed * 0.5 * 60; - body.velocity.x += this._velocityDelta; - body.x += (body.velocity.x * this.game.time.physicsElapsed); - body.velocity.x += this._velocityDelta; - - // Vertical - this._velocityDelta = (this.computeVelocity(2, body, body.velocity.y, body.acceleration.y, body.drag.y, body.maxVelocity.y) - body.velocity.y) * this.game.time.physicsElapsed * 0.5 * 60; - body.velocity.y += this._velocityDelta; - body.y += (body.velocity.y * this.game.time.physicsElapsed); - body.velocity.y += this._velocityDelta; - - }, - - /** - * A tween-like function that takes a starting velocity and some other factors and returns an altered velocity. - * - * @method Phaser.Physics.Arcade#computeVelocity - * @param {number} axis - 1 for horizontal, 2 for vertical. - * @param {Phaser.Physics.Arcade.Body} body - The Body object to be updated. - * @param {number} velocity - Any component of velocity (e.g. 20). - * @param {number} acceleration - Rate at which the velocity is changing. - * @param {number} drag - Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set. - * @param {number} mMax - An absolute value cap for the velocity. - * @return {number} The altered Velocity value. - */ - computeVelocity: function (axis, body, velocity, acceleration, drag, max) { - - max = max || 10000; - - if (axis == 1 && body.allowGravity) + if (body.allowRotation) { - velocity += this.gravity.x + body.gravity.x; - } - else if (axis == 2 && body.allowGravity) - { - velocity += this.gravity.y + body.gravity.y; - } + this._velocityDelta = body.angularAcceleration * this.game.time.physicsElapsed; - if (acceleration !== 0) - { - velocity += acceleration * this.game.time.physicsElapsed; - } - else if (drag !== 0) - { - this._drag = drag * this.game.time.physicsElapsed; - - if (velocity - this._drag > 0) + if (body.angularDrag !== 0 && body.angularAcceleration === 0) { - velocity -= this._drag; + this._drag = body.angularDrag * this.game.time.physicsElapsed; + + if (body.angularVelocity > 0) + { + body.angularVelocity -= this._drag; + } + else if (body.angularVelocity < 0) + { + body.angularVelocity += this._drag; + } } - else if (velocity + this._drag < 0) + + body.rotation += this.game.time.physicsElapsed * (body.angularVelocity + this._velocityDelta / 2); + body.angularVelocity += this._velocityDelta; + + if (body.angularVelocity > body.maxAngular) { - velocity += this._drag; + body.angularVelocity = body.maxAngular; } - else + else if (body.angularVelocity < -body.maxAngular) { - velocity = 0; + body.angularVelocity = -body.maxAngular; } } - if (velocity > max) - { - velocity = max; - } - else if (velocity < -max) - { - velocity = -max; - } + // temp = acc*dt + // pos = pos + dt*(vel + temp/2) + // vel = vel + temp - return velocity; + this._p.setTo((body.acceleration.x + this._gravityX) * this.game.time.physicsElapsed, (body.acceleration.y + this._gravityY) * this.game.time.physicsElapsed); - }, - - /** - * Called automatically by the core game loop. - * - * @method Phaser.Physics.Arcade#preUpdate - * @protected - */ - preUpdate: function () { - - // Clear the tree - this.quadTree.clear(); - - // Create our tree which all of the Physics bodies will add themselves to - this.quadTreeID = 0; - this.quadTree = new Phaser.QuadTree(this, this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels); - - }, - - /** - * Called automatically by the core game loop. - * - * @method Phaser.Physics.Arcade#postUpdate - * @protected - */ - postUpdate: function () { - - // Clear the tree ready for the next update - this.quadTree.clear(); + return this._p; }, @@ -35136,10 +39213,11 @@ Phaser.Physics.Arcade.prototype = { * Checks for overlaps between two game objects. The objects can be Sprites, Groups or Emitters. * You can perform Sprite vs. Sprite, Sprite vs. Group and Group vs. Group overlap checks. * Unlike collide the objects are NOT automatically separated or have any physics applied, they merely test for overlap results. + * The second parameter can be an array of objects, of differing types. * * @method Phaser.Physics.Arcade#overlap * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter. - * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter. + * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|array} object2 - The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter. * @param {function} [overlapCallback=null] - An optional callback function that is called if the objects overlap. The two objects will be passed to this function in the same order in which you specified them. * @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then overlapCallback will only be called if processCallback returns true. * @param {object} [callbackContext] - The context in which to run the callbacks. @@ -35154,83 +39232,144 @@ Phaser.Physics.Arcade.prototype = { this._result = false; this._total = 0; - // Only test valid objects - if (object1 && object2 && object1.exists && object2.exists) + if (Array.isArray(object2)) { - // SPRITES - if (object1.type == Phaser.SPRITE) + for (var i = 0, len = object2.length; i < len; i++) { - if (object2.type == Phaser.SPRITE) - { - this.overlapSpriteVsSprite(object1, object2, overlapCallback, processCallback, callbackContext); - } - else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) - { - this.overlapSpriteVsGroup(object1, object2, overlapCallback, processCallback, callbackContext); - } - } - // GROUPS - else if (object1.type == Phaser.GROUP) - { - if (object2.type == Phaser.SPRITE) - { - this.overlapSpriteVsGroup(object2, object1, overlapCallback, processCallback, callbackContext); - } - else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) - { - this.overlapGroupVsGroup(object1, object2, overlapCallback, processCallback, callbackContext); - } - } - // EMITTER - else if (object1.type == Phaser.EMITTER) - { - if (object2.type == Phaser.SPRITE) - { - this.overlapSpriteVsGroup(object2, object1, overlapCallback, processCallback, callbackContext); - } - else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) - { - this.overlapGroupVsGroup(object1, object2, overlapCallback, processCallback, callbackContext); - } + this.collideHandler(object1, object2[i], overlapCallback, processCallback, callbackContext, true); } } + else + { + this.collideHandler(object1, object2, overlapCallback, processCallback, callbackContext, true); + } return (this._total > 0); }, /** - * An internal function. Use Phaser.Physics.Arcade.overlap instead. + * Checks for collision between two game objects. You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions. + * The second parameter can be an array of objects, of differing types. + * The objects are also automatically separated. If you don't require separation then use ArcadePhysics.overlap instead. + * An optional processCallback can be provided. If given this function will be called when two sprites are found to be colliding. It is called before any separation takes place, + * giving you the chance to perform additional checks. If the function returns true then the collision and separation is carried out. If it returns false it is skipped. + * The collideCallback is an optional function that is only called if two sprites collide. If a processCallback has been set then it needs to return true for collideCallback to be called. * - * @method Phaser.Physics.Arcade#overlapSpriteVsSprite - * @private + * @method Phaser.Physics.Arcade#collide + * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap. + * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap|array} object2 - The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap. + * @param {function} [collideCallback=null] - An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them. + * @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them. + * @param {object} [callbackContext] - The context in which to run the callbacks. + * @returns {boolean} True if a collision occured otherwise false. */ - overlapSpriteVsSprite: function (sprite1, sprite2, overlapCallback, processCallback, callbackContext) { + collide: function (object1, object2, collideCallback, processCallback, callbackContext) { - this._result = Phaser.Rectangle.intersects(sprite1.body, sprite2.body); + collideCallback = collideCallback || null; + processCallback = processCallback || null; + callbackContext = callbackContext || collideCallback; - if (this._result) + this._result = false; + this._total = 0; + + if (Array.isArray(object2)) { - // They collided, is there a custom process callback? - if (processCallback) + for (var i = 0, len = object2.length; i < len; i++) { - if (processCallback.call(callbackContext, sprite1, sprite2)) - { - this._total++; + this.collideHandler(object1, object2[i], collideCallback, processCallback, callbackContext, false); + } + } + else + { + this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, false); + } - if (overlapCallback) - { - overlapCallback.call(callbackContext, sprite1, sprite2); - } + return (this._total > 0); + + }, + + /** + * Internal collision handler. + * + * @method Phaser.Physics.Arcade#collideHandler + * @private + * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap. + * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap. Can also be an array of objects to check. + * @param {function} collideCallback - An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them. + * @param {function} processCallback - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them. + * @param {object} callbackContext - The context in which to run the callbacks. + * @param {boolean} overlapOnly - Just run an overlap or a full collision. + */ + collideHandler: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) { + + // Only collide valid objects + if (typeof object2 === 'undefined' && (object1.type === Phaser.GROUP || object1.type === Phaser.EMITTER)) + { + this.collideGroupVsSelf(object1, collideCallback, processCallback, callbackContext, overlapOnly); + return; + } + + if (object1 && object2 && object1.exists && object2.exists) + { + // SPRITES + if (object1.type == Phaser.SPRITE || object1.type == Phaser.TILESPRITE) + { + if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE) + { + this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) + { + this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.type == Phaser.TILEMAPLAYER) + { + this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); } } - else + // GROUPS + else if (object1.type == Phaser.GROUP) { - this._total++; - - if (overlapCallback) + if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE) { - overlapCallback.call(callbackContext, sprite1, sprite2); + this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) + { + this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.type == Phaser.TILEMAPLAYER) + { + this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); + } + } + // TILEMAP LAYERS + else if (object1.type == Phaser.TILEMAPLAYER) + { + if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE) + { + this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext); + } + else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) + { + this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext); + } + } + // EMITTER + else if (object1.type == Phaser.EMITTER) + { + if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE) + { + this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) + { + this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly); + } + else if (object2.type == Phaser.TILEMAPLAYER) + { + this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); } } } @@ -35238,12 +39377,32 @@ Phaser.Physics.Arcade.prototype = { }, /** - * An internal function. Use Phaser.Physics.Arcade.overlap instead. + * An internal function. Use Phaser.Physics.Arcade.collide instead. * - * @method Phaser.Physics.Arcade#overlapSpriteVsGroup + * @method Phaser.Physics.Arcade#collideSpriteVsSprite * @private */ - overlapSpriteVsGroup: function (sprite, group, overlapCallback, processCallback, callbackContext) { + collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext, overlapOnly) { + + if (this.separate(sprite1.body, sprite2.body, processCallback, callbackContext, overlapOnly)) + { + if (collideCallback) + { + collideCallback.call(callbackContext, sprite1, sprite2); + } + + this._total++; + } + + }, + + /** + * An internal function. Use Phaser.Physics.Arcade.collide instead. + * + * @method Phaser.Physics.Arcade#collideSpriteVsGroup + * @private + */ + collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext, overlapOnly) { if (group.length === 0) { @@ -35251,28 +39410,52 @@ Phaser.Physics.Arcade.prototype = { } // What is the sprite colliding with in the quadtree? + this.quadTree.clear(); + + this.quadTree = new Phaser.QuadTree(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels); + + this.quadTree.populate(group); + this._potentials = this.quadTree.retrieve(sprite); for (var i = 0, len = this._potentials.length; i < len; i++) { // We have our potential suspects, are they in this group? - if (this._potentials[i].sprite.group == group) + if (this.separate(sprite.body, this._potentials[i], processCallback, callbackContext, overlapOnly)) { - this._result = Phaser.Rectangle.intersects(sprite.body, this._potentials[i]); - - if (this._result && processCallback) + if (collideCallback) { - this._result = processCallback.call(callbackContext, sprite, this._potentials[i].sprite); + collideCallback.call(callbackContext, sprite, this._potentials[i].sprite); } - if (this._result) - { - this._total++; + this._total++; + } + } - if (overlapCallback) - { - overlapCallback.call(callbackContext, sprite, this._potentials[i].sprite); - } + }, + + /** + * An internal function. Use Phaser.Physics.Arcade.collide instead. + * + * @method Phaser.Physics.Arcade#collideGroupVsSelf + * @private + */ + collideGroupVsSelf: function (group, collideCallback, processCallback, callbackContext, overlapOnly) { + + if (group.length === 0) + { + return; + } + + var len = group._container.children.length; + + for (var i = 0; i < len; i++) + { + for (var j = i + 1; j <= len; j++) + { + if (group._container.children[i] && group._container.children[j] && group._container.children[i].exists && group._container.children[j].exists) + { + this.collideSpriteVsSprite(group._container.children[i], group._container.children[j], collideCallback, processCallback, callbackContext, overlapOnly); } } } @@ -35280,12 +39463,12 @@ Phaser.Physics.Arcade.prototype = { }, /** - * An internal function. Use Phaser.Physics.Arcade.overlap instead. + * An internal function. Use Phaser.Physics.Arcade.collide instead. * - * @method Phaser.Physics.Arcade#overlapGroupVsGroup + * @method Phaser.Physics.Arcade#collideGroupVsGroup * @private */ - overlapGroupVsGroup: function (group1, group2, overlapCallback, processCallback, callbackContext) { + collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext, overlapOnly) { if (group1.length === 0 || group2.length === 0) { @@ -35300,7 +39483,7 @@ Phaser.Physics.Arcade.prototype = { { if (currentNode.exists) { - this.overlapSpriteVsGroup(currentNode, group2, overlapCallback, processCallback, callbackContext); + this.collideSpriteVsGroup(currentNode, group2, collideCallback, processCallback, callbackContext, overlapOnly); } currentNode = currentNode._iNext; } @@ -35309,99 +39492,6 @@ Phaser.Physics.Arcade.prototype = { }, - /** - * Checks for collision between two game objects. The objects can be Sprites, Groups, Emitters or Tilemap Layers. - * You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions. - * The objects are also automatically separated. - * - * @method Phaser.Physics.Arcade#collide - * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap - * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap - * @param {function} [collideCallback=null] - An optional callback function that is called if the objects overlap. The two objects will be passed to this function in the same order in which you specified them. - * @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collideCallback will only be called if processCallback returns true. - * @param {object} [callbackContext] - The context in which to run the callbacks. - * @returns {boolean} True if a collision occured otherwise false. - */ - collide: function (object1, object2, collideCallback, processCallback, callbackContext) { - - collideCallback = collideCallback || null; - processCallback = processCallback || null; - callbackContext = callbackContext || collideCallback; - - this._result = false; - this._total = 0; - - // Only collide valid objects - if (object1 && object2 && object1.exists && object2.exists) - { - // Can expand to support Buttons, Text, etc at a later date. For now these are the essentials. - - // SPRITES - if (object1.type == Phaser.SPRITE) - { - if (object2.type == Phaser.SPRITE) - { - this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext); - } - else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) - { - this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext); - } - else if (object2.type == Phaser.TILEMAPLAYER) - { - this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); - } - } - // GROUPS - else if (object1.type == Phaser.GROUP) - { - if (object2.type == Phaser.SPRITE) - { - this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext); - } - else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) - { - this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext); - } - else if (object2.type == Phaser.TILEMAPLAYER) - { - this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); - } - } - // TILEMAP LAYERS - else if (object1.type == Phaser.TILEMAPLAYER) - { - if (object2.type == Phaser.SPRITE) - { - this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext); - } - else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) - { - this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext); - } - } - // EMITTER - else if (object1.type == Phaser.EMITTER) - { - if (object2.type == Phaser.SPRITE) - { - this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext); - } - else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER) - { - this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext); - } - else if (object2.type == Phaser.TILEMAPLAYER) - { - this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext); - } - } - } - - return (this._total > 0); - - }, - /** * An internal function. Use Phaser.Physics.Arcade.collide instead. * @@ -35410,15 +39500,21 @@ Phaser.Physics.Arcade.prototype = { */ collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) { - this._mapData = tilemapLayer.getTiles(sprite.body.x, sprite.body.y, sprite.body.width, sprite.body.height, true); + this._mapData = tilemapLayer.getTiles(sprite.body.left, sprite.body.top, sprite.body.width, sprite.body.height, true); if (this._mapData.length === 0) { return; } - for (var i = 0; i < this._mapData.length; i++) + if (this._mapData.length > 1) { + this.separateTiles(sprite.body, this._mapData); + } + else + { + var i = 0; + if (this.separateTile(sprite.body, this._mapData[i])) { // They collided, is there a custom process callback? @@ -35461,11 +39557,6 @@ Phaser.Physics.Arcade.prototype = { return; } - if (group.length === 0) - { - return; - } - if (group._container.first._iNext) { var currentNode = group._container.first._iNext; @@ -35483,232 +39574,39 @@ Phaser.Physics.Arcade.prototype = { }, - /** - * An internal function. Use Phaser.Physics.Arcade.collide instead. - * - * @method Phaser.Physics.Arcade#collideSpriteVsSprite - * @private - */ - collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext) { - - this.separate(sprite1.body, sprite2.body); - - if (this._result) - { - // They collided, is there a custom process callback? - if (processCallback) - { - if (processCallback.call(callbackContext, sprite1, sprite2)) - { - this._total++; - - if (collideCallback) - { - collideCallback.call(callbackContext, sprite1, sprite2); - } - } - } - else - { - this._total++; - - if (collideCallback) - { - collideCallback.call(callbackContext, sprite1, sprite2); - } - } - } - - }, - - /** - * An internal function. Use Phaser.Physics.Arcade.collide instead. - * - * @method Phaser.Physics.Arcade#collideSpriteVsGroup - * @private - */ - collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext) { - - if (group.length === 0) - { - return; - } - - // What is the sprite colliding with in the quadtree? - this._potentials = this.quadTree.retrieve(sprite); - - for (var i = 0, len = this._potentials.length; i < len; i++) - { - // We have our potential suspects, are they in this group? - if (this._potentials[i].sprite.group == group) - { - this.separate(sprite.body, this._potentials[i]); - - if (this._result && processCallback) - { - this._result = processCallback.call(callbackContext, sprite, this._potentials[i].sprite); - } - - if (this._result) - { - this._total++; - - if (collideCallback) - { - collideCallback.call(callbackContext, sprite, this._potentials[i].sprite); - } - } - } - } - - }, - - /** - * An internal function. Use Phaser.Physics.Arcade.collide instead. - * - * @method Phaser.Physics.Arcade#collideGroupVsGroup - * @private - */ - collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext) { - - if (group1.length === 0 || group2.length === 0) - { - return; - } - - if (group1._container.first._iNext) - { - var currentNode = group1._container.first._iNext; - - do - { - if (currentNode.exists) - { - this.collideSpriteVsGroup(currentNode, group2, collideCallback, processCallback, callbackContext); - } - currentNode = currentNode._iNext; - } - while (currentNode != group1._container.last._iNext); - } - - }, - /** * The core separation function to separate two physics bodies. * @method Phaser.Physics.Arcade#separate * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate. * @param {Phaser.Physics.Arcade.Body} body2 - The Body object to separate. - * @returns {boolean} Returns true if the bodies were separated, otherwise false. + * @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this function is set then the sprites will only be collided if it returns true. + * @param {object} [callbackContext] - The context in which to run the process callback. + * @returns {boolean} Returns true if the bodies collided, otherwise false. */ - separate: function (body1, body2) { + separate: function (body1, body2, processCallback, callbackContext, overlapOnly) { - this._result = (this.separateX(body1, body2) || this.separateY(body1, body2)); - - }, - - /** - * The core separation function to separate two physics bodies on the x axis. - * @method Phaser.Physics.Arcade#separateX - * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate. - * @param {Phaser.Physics.Arcade.Body} body2 - The Body object to separate. - * @returns {boolean} Returns true if the bodies were separated, otherwise false. - */ - separateX: function (body1, body2) { - - // Can't separate two immovable bodies - if (body1.immovable && body2.immovable) + if (body1 === body2 || this.intersects(body1, body2) === false) { return false; } - this._overlap = 0; - - // Check if the hulls actually overlap - if (Phaser.Rectangle.intersects(body1, body2)) + // They overlap. Is there a custom process callback? If it returns true then we can carry on, otherwise we should abort. + if (processCallback && processCallback.call(callbackContext, body1.sprite, body2.sprite) === false) { - this._maxOverlap = body1.deltaAbsX() + body2.deltaAbsX() + this.OVERLAP_BIAS; + return false; + } - if (body1.deltaX() === 0 && body2.deltaX() === 0) + this._response.clear(); + + if (overlapOnly) + { + return body1.overlap(body2, this._response); + } + else + { + if (body1.overlap(body2, this._response)) { - // They overlap but neither of them are moving - body1.embedded = true; - body2.embedded = true; - } - else if (body1.deltaX() > body2.deltaX()) - { - // Body1 is moving right and/or Body2 is moving left - this._overlap = body1.x + body1.width - body2.x; - - if ((this._overlap > this._maxOverlap) || body1.allowCollision.right === false || body2.allowCollision.left === false) - { - this._overlap = 0; - } - else - { - body1.touching.right = true; - body2.touching.left = true; - } - } - else if (body1.deltaX() < body2.deltaX()) - { - // Body1 is moving left and/or Body2 is moving right - this._overlap = body1.x - body2.width - body2.x; - - if ((-this._overlap > this._maxOverlap) || body1.allowCollision.left === false || body2.allowCollision.right === false) - { - this._overlap = 0; - } - else - { - body1.touching.left = true; - body2.touching.right = true; - } - } - - // Then adjust their positions and velocities accordingly (if there was any overlap) - if (this._overlap !== 0) - { - body1.overlapX = this._overlap; - body2.overlapX = this._overlap; - - if (body1.customSeparateX || body2.customSeparateX) - { - return true; - } - - this._velocity1 = body1.velocity.x; - this._velocity2 = body2.velocity.x; - - if (!body1.immovable && !body2.immovable) - { - this._overlap *= 0.5; - - body1.x = body1.x - this._overlap; - body2.x += this._overlap; - - this._newVelocity1 = Math.sqrt((this._velocity2 * this._velocity2 * body2.mass) / body1.mass) * ((this._velocity2 > 0) ? 1 : -1); - this._newVelocity2 = Math.sqrt((this._velocity1 * this._velocity1 * body1.mass) / body2.mass) * ((this._velocity1 > 0) ? 1 : -1); - this._average = (this._newVelocity1 + this._newVelocity2) * 0.5; - this._newVelocity1 -= this._average; - this._newVelocity2 -= this._average; - - body1.velocity.x = this._average + this._newVelocity1 * body1.bounce.x; - body2.velocity.x = this._average + this._newVelocity2 * body2.bounce.x; - } - else if (!body1.immovable) - { - body1.x = body1.x - this._overlap; - body1.velocity.x = this._velocity2 - this._velocity1 * body1.bounce.x; - } - else if (!body2.immovable) - { - body2.x += this._overlap; - body2.velocity.x = this._velocity1 - this._velocity2 * body2.bounce.x; - } - body1.updateHulls(); - body2.updateHulls(); - - return true; + return body1.separate(body2, this._response); } } @@ -35717,221 +39615,203 @@ Phaser.Physics.Arcade.prototype = { }, /** - * The core separation function to separate two physics bodies on the y axis. - * @method Phaser.Physics.Arcade#separateY - * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate. - * @param {Phaser.Physics.Arcade.Body} body2 - The Body object to separate. - * @returns {boolean} Returns true if the bodies were separated, otherwise false. + * Performs a rect intersection test against the two objects. + * Objects must expose properties: width, height, left, right, top, bottom. + * @method Phaser.Physics.Arcade#intersects + * @param {object} a - The first object to test. + * @param {object} b - The second object to test. + * @returns {boolean} Returns true if the objects intersect, otherwise false. */ - separateY: function (body1, body2) { + intersects: function (a, b) { - // Can't separate two immovable or non-existing bodys - if (body1.immovable && body2.immovable) + var result = false; + + if (a.width <= 0 || a.height <= 0 || b.width <= 0 || b.height <= 0) { - return false; + result = false; } - this._overlap = 0; + result = !(a.right < b.left || a.bottom < b.top || a.left > b.right || a.top > b.bottom); - // Check if the hulls actually overlap - if (Phaser.Rectangle.intersects(body1, body2)) + if (!result && a.inContact(b)) { - this._maxOverlap = body1.deltaAbsY() + body2.deltaAbsY() + this.OVERLAP_BIAS; - - if (body1.deltaY() === 0 && body2.deltaY() === 0) - { - // They overlap but neither of them are moving - body1.embedded = true; - body2.embedded = true; - } - else if (body1.deltaY() > body2.deltaY()) - { - // Body1 is moving down and/or Body2 is moving up - this._overlap = body1.y + body1.height - body2.y; - - if ((this._overlap > this._maxOverlap) || body1.allowCollision.down === false || body2.allowCollision.up === false) - { - this._overlap = 0; - } - else - { - body1.touching.down = true; - body2.touching.up = true; - } - } - else if (body1.deltaY() < body2.deltaY()) - { - // Body1 is moving up and/or Body2 is moving down - this._overlap = body1.y - body2.height - body2.y; - - if ((-this._overlap > this._maxOverlap) || body1.allowCollision.up === false || body2.allowCollision.down === false) - { - this._overlap = 0; - } - else - { - body1.touching.up = true; - body2.touching.down = true; - } - } - - // Then adjust their positions and velocities accordingly (if there was any overlap) - if (this._overlap !== 0) - { - body1.overlapY = this._overlap; - body2.overlapY = this._overlap; - - if (body1.customSeparateY || body2.customSeparateY) - { - return true; - } - - this._velocity1 = body1.velocity.y; - this._velocity2 = body2.velocity.y; - - if (!body1.immovable && !body2.immovable) - { - this._overlap *= 0.5; - - body1.y = body1.y - this._overlap; - body2.y += this._overlap; - - this._newVelocity1 = Math.sqrt((this._velocity2 * this._velocity2 * body2.mass) / body1.mass) * ((this._velocity2 > 0) ? 1 : -1); - this._newVelocity2 = Math.sqrt((this._velocity1 * this._velocity1 * body1.mass) / body2.mass) * ((this._velocity1 > 0) ? 1 : -1); - this._average = (this._newVelocity1 + this._newVelocity2) * 0.5; - this._newVelocity1 -= this._average; - this._newVelocity2 -= this._average; - - body1.velocity.y = this._average + this._newVelocity1 * body1.bounce.y; - body2.velocity.y = this._average + this._newVelocity2 * body2.bounce.y; - } - else if (!body1.immovable) - { - body1.y = body1.y - this._overlap; - body1.velocity.y = this._velocity2 - this._velocity1 * body1.bounce.y; - - // This is special case code that handles things like horizontal moving platforms you can ride - if (body2.active && body2.moves && (body1.deltaY() > body2.deltaY())) - { - body1.x += body2.x - body2.lastX; - } - } - else if (!body2.immovable) - { - body2.y += this._overlap; - body2.velocity.y = this._velocity1 - this._velocity2 * body2.bounce.y; - - // This is special case code that handles things like horizontal moving platforms you can ride - if (body1.sprite.active && body1.moves && (body1.deltaY() < body2.deltaY())) - { - body2.x += body1.x - body1.lastX; - } - } - body1.updateHulls(); - body2.updateHulls(); - - return true; - } - + a.removeContact(b); } - return false; + }, + + /** + * Performs a rect intersection test against the two objects. + * Objects must expose properties: width, height, left, right, top, bottom. + * @method Phaser.Physics.Arcade#tileIntersects + * @param {object} body - The Body to test. + * @param {object} tile - The Tile to test. + * @returns {boolean} Returns true if the objects intersect, otherwise false. + */ + tileIntersects: function (body, tile) { + + if (body.width <= 0 || body.height <= 0 || tile.width <= 0 || tile.height <= 0) + { + this._intersection[4] = 0; + return this._intersection; + } + + if (!(body.right < tile.x || body.bottom < tile.y || body.left > tile.right || body.top > tile.bottom)) + { + this._intersection[0] = Math.max(body.left, tile.x); // x + this._intersection[1] = Math.max(body.top, tile.y); // y + this._intersection[2] = Math.min(body.right, tile.right) - this._intersection[0]; // width + this._intersection[3] = Math.min(body.bottom, tile.bottom) - this._intersection[1]; // height + this._intersection[4] = 1; + + return this._intersection; + } + + this._intersection[4] = 0; + + return this._intersection; + + }, + + /** + * The core separation function to separate a physics body and an array of tiles. + * @method Phaser.Physics.Arcade#separateTiles + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. + * @param {array} tiles - The array of tiles to collide against. + * @returns {boolean} Returns true if the body was separated, otherwise false. + */ + separateTiles: function (body, tiles) { + + var tile; + var result = false; + + for (var i = 0; i < tiles.length; i++) + { + tile = tiles[i]; + + if (this.separateTile(body, tile)) + { + result = true; + } + } + + return result; }, /** * The core separation function to separate a physics body and a tile. * @method Phaser.Physics.Arcade#separateTile - * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate. + * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate. * @param {Phaser.Tile} tile - The tile to collide against. - * @returns {boolean} Returns true if the bodies were separated, otherwise false. + * @returns {boolean} Returns true if the body was separated, otherwise false. */ separateTile: function (body, tile) { - this._result = (this.separateTileX(body, tile, true) || this.separateTileY(body, tile, true)); + this._intersection = this.tileIntersects(body, tile); - return this._result; - - }, - - /** - * The core separation function to separate a physics body and a tile on the x axis. - * @method Phaser.Physics.Arcade#separateTileX - * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate. - * @param {Phaser.Tile} tile - The tile to collide against. - * @returns {boolean} Returns true if the bodies were separated, otherwise false. - */ - separateTileX: function (body, tile, separate) { - - // Can't separate two immovable objects (tiles are always immovable) - if (body.immovable || body.deltaX() === 0 || Phaser.Rectangle.intersects(body.hullX, tile) === false) + // If the intersection area is either entirely null, or has a width/height of zero, we bail out now + if (this._intersection[4] === 0 || this._intersection[2] === 0 || this._intersection[3] === 0) { return false; } - this._overlap = 0; - - // The hulls overlap, let's process it - // this._maxOverlap = body.deltaAbsX() + this.OVERLAP_BIAS; - - if (body.deltaX() < 0) + // They overlap. Any custom callbacks? + if (tile.tile.callback || tile.layer.callbacks[tile.tile.index]) { - // Moving left - this._overlap = tile.right - body.hullX.x; - - // if ((this._overlap > this._maxOverlap) || body.allowCollision.left === false || tile.tile.collideRight === false) - if (body.allowCollision.left === false || tile.tile.collideRight === false) + // A local callback takes priority over a global callback. + if (tile.tile.callback && tile.tile.callback.call(tile.tile.callbackContext, body.sprite, tile) === false) { - this._overlap = 0; + // Is there a tile specific collision callback? If it returns true then we can carry on, otherwise we should abort. + return false; } - else + else if (tile.layer.callbacks[tile.tile.index] && tile.layer.callbacks[tile.tile.index].callback.call(tile.layer.callbacks[tile.tile.index].callbackContext, body.sprite, tile) === false) { - body.touching.left = true; - } - } - else - { - // Moving right - this._overlap = body.hullX.right - tile.x; - - // if ((this._overlap > this._maxOverlap) || body.allowCollision.right === false || tile.tile.collideLeft === false) - if (body.allowCollision.right === false || tile.tile.collideLeft === false) - { - this._overlap = 0; - } - else - { - body.touching.right = true; + // Is there a tile index collision callback? If it returns true then we can carry on, otherwise we should abort. + return false; } } - // Then adjust their positions and velocities accordingly (if there was any overlap) - if (this._overlap !== 0) + body.overlapX = 0; + body.overlapY = 0; + + var process = false; + + if (body.deltaX() < 0 && body.checkCollision.left && tile.tile.faceRight && !body.blocked.left) { - if (separate) + // LEFT + body.overlapX = body.left - tile.right; + + if (body.overlapX < 0) { - if (body.deltaX() < 0) - { - body.x = body.x + this._overlap; - } - else - { - body.x = body.x - this._overlap; - } - - if (body.bounce.x === 0) - { - body.velocity.x = 0; - } - else - { - body.velocity.x = -body.velocity.x * body.bounce.x; - } - - body.updateHulls(); + process = true; } + else + { + body.overlapX = 0; + } + } + else if (body.deltaX() > 0 && body.checkCollision.right && tile.tile.faceLeft && !body.blocked.right) + { + // RIGHT + body.overlapX = body.right - tile.x; - return true; + if (body.overlapX > 0) + { + process = true; + } + else + { + body.overlapX = 0; + } + } + + if (body.deltaY() < 0 && body.checkCollision.up && tile.tile.faceBottom && !body.blocked.up) + { + // UP + body.overlapY = body.top - tile.bottom; + + if (body.overlapY < 0) + { + process = true; + } + else + { + body.overlapY = 0; + } + } + else if (body.deltaY() > 0 && body.checkCollision.down && tile.tile.faceTop && !body.blocked.down) + { + // DOWN + body.overlapY = body.bottom - tile.y; + + if (body.overlapY > 0) + { + process = true; + } + else + { + body.overlapY = 0; + } + } + + // Only separate on the smallest of the two values if it's a single tile + if (body.overlapX !== 0 && body.overlapY !== 0) + { + if (Math.abs(body.overlapX) > Math.abs(body.overlapY)) + { + body.overlapX = 0; + } + else + { + body.overlapY = 0; + } + } + + // Separate in a single sweep + if (process) + { + return this.processTileSeparation(body); } else { @@ -35941,88 +39821,55 @@ Phaser.Physics.Arcade.prototype = { }, /** - * The core separation function to separate a physics body and a tile on the x axis. - * @method Phaser.Physics.Arcade#separateTileY + * Internal function to process the separation of a physics body from a tile. + * @method Phaser.Physics.Arcade#processTileSeparation + * @protected * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate. - * @param {Phaser.Tile} tile - The tile to collide against. - * @returns {boolean} Returns true if the bodies were separated, otherwise false. + * @returns {boolean} Returns true if separated, false if not. */ - separateTileY: function (body, tile, separate) { + processTileSeparation: function (body) { - // Can't separate two immovable objects (tiles are always immovable) - if (body.immovable || body.deltaY() === 0 || Phaser.Rectangle.intersects(body.hullY, tile) === false) + if (body.overlapX < 0) { - return false; + body.x -= body.overlapX; + body.left -= body.overlapX; + body.right -= body.overlapX; + body.blocked.x = Math.floor(body.x); + body.blocked.y = Math.floor(body.y); + body.blocked.left = true; + } + else if (body.overlapX > 0) + { + body.x -= body.overlapX; + body.left -= body.overlapX; + body.right -= body.overlapX; + body.blocked.x = Math.floor(body.x); + body.blocked.y = Math.floor(body.y); + body.blocked.right = true; } - this._overlap = 0; - - // The hulls overlap, let's process it - // this._maxOverlap = body.deltaAbsY() + this.OVERLAP_BIAS; - - if (body.deltaY() < 0) + if (body.overlapY < 0) { - // Moving up - this._overlap = tile.bottom - body.hullY.y; - - // if ((this._overlap > this._maxOverlap) || body.allowCollision.up === false || tile.tile.collideDown === false) - if (body.allowCollision.up === false || tile.tile.collideDown === false) - { - this._overlap = 0; - } - else - { - body.touching.up = true; - } + body.y -= body.overlapY; + body.top -= body.overlapY; + body.bottom -= body.overlapY; + body.blocked.x = Math.floor(body.x); + body.blocked.y = Math.floor(body.y); + body.blocked.up = true; } - else + else if (body.overlapY > 0) { - // Moving down - this._overlap = body.hullY.bottom - tile.y; - - // if ((this._overlap > this._maxOverlap) || body.allowCollision.down === false || tile.tile.collideUp === false) - if (body.allowCollision.down === false || tile.tile.collideUp === false) - { - this._overlap = 0; - } - else - { - body.touching.down = true; - } + body.y -= body.overlapY; + body.top -= body.overlapY; + body.bottom -= body.overlapY; + body.blocked.x = Math.floor(body.x); + body.blocked.y = Math.floor(body.y); + body.blocked.down = true; } - // Then adjust their positions and velocities accordingly (if there was any overlap) - if (this._overlap !== 0) - { - if (separate) - { - if (body.deltaY() < 0) - { - body.y = body.y + this._overlap; - } - else - { - body.y = body.y - this._overlap; - } + body.reboundCheck(body.overlapX, body.overlapY, true); - if (body.bounce.y === 0) - { - body.velocity.y = 0; - } - else - { - body.velocity.y = -body.velocity.y * body.bounce.y; - } - - body.updateHulls(); - } - - return true; - } - else - { - return false; - } + return true; }, @@ -36172,7 +40019,7 @@ Phaser.Physics.Arcade.prototype = { /** * Given the rotation (in radians) and speed calculate the acceleration and return it as a Point object, or set it to the given point object. - * One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) which will set the values directly to the sprites velocity and not create a new Point object. + * One way to use this is: accelerationFromRotation(rotation, 200, sprite.acceleration) which will set the values directly to the sprites acceleration and not create a new Point object. * * @method Phaser.Physics.Arcade#accelerationFromRotation * @param {number} rotation - The angle in radians. @@ -36392,15 +40239,18 @@ Phaser.Physics.Arcade.prototype = { }; +Phaser.Physics.Arcade.prototype.constructor = Phaser.Physics.Arcade; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** -* The Physics Body is linked to a single Sprite. All physics operations should be performed against the body rather than -* the Sprite itself. For example you can set the velocity, acceleration, bounce values etc all on the Body. +* The Physics Body is linked to a single Sprite and defines properties that determine how the physics body is simulated. +* These properties affect how the body reacts to forces, what forces it generates on itself (to simulate friction), and how it reacts to collisions in the scene. In most cases, the properties are used to simulate physical effects. +* Each body also has its own property values that determine exactly how it reacts to forces and collisions in the scene. * * @class Phaser.Physics.Arcade.Body * @classdesc Arcade Physics Body Constructor @@ -36424,29 +40274,17 @@ Phaser.Physics.Arcade.Body = function (sprite) { */ this.offset = new Phaser.Point(); - /** - * @property {number} x - The x position of the physics body. - * @readonly - */ - this.x = sprite.x; - - /** - * @property {number} y - The y position of the physics body. - * @readonly - */ - this.y = sprite.y; - /** * @property {number} preX - The previous x position of the physics body. * @readonly */ - this.preX = sprite.x; + this.preX = sprite.world.x; /** * @property {number} preY - The previous y position of the physics body. * @readonly */ - this.preY = sprite.y; + this.preY = sprite.world.y; /** * @property {number} preRotation - The previous rotation of the physics body. @@ -36455,53 +40293,262 @@ Phaser.Physics.Arcade.Body = function (sprite) { this.preRotation = sprite.angle; /** - * @property {number} screenX - The x position of the physics body translated to screen space. + * @property {Phaser.Point} velocity - The velocity of the Body. + */ + this.velocity = new Phaser.Point(); + + /** + * @property {Phaser.Point} acceleration - The acceleration in pixels per second sq. of the Body. + */ + this.acceleration = new Phaser.Point(); + + /** + * @property {number} speed - The speed in pixels per second sq. of the Body. + */ + this.speed = 0; + + /** + * @property {number} angle - The angle of the Body based on its velocity in radians. + */ + this.angle = 0; + + /** + * @property {Phaser.Point} gravity - The gravity applied to the motion of the Body. This works in addition to any gravity set on the world. + */ + this.gravity = new Phaser.Point(); + + /** + * @property {Phaser.Point} bounce - The elasticitiy of the Body when colliding. This property determines how much energy a body maintains during a collision, i.e. its bounciness. + */ + this.bounce = new Phaser.Point(); + + /** + * @property {Phaser.Point} minVelocity - When a body rebounds off another body or a wall the minVelocity is checked. If the new velocity is lower than minVelocity the body is stopped. + * @default + */ + this.minVelocity = new Phaser.Point(); + + /** + * @property {Phaser.Point} maxVelocity - The maximum velocity that the Body can reach. + * @default + */ + this.maxVelocity = new Phaser.Point(1000, 1000); + + /** + * @property {number} angularVelocity - The angular velocity of the Body. + * @default + */ + this.angularVelocity = 0; + + /** + * @property {number} angularAcceleration - The angular acceleration of the Body. + * @default + */ + this.angularAcceleration = 0; + + /** + * @property {number} angularDrag - angularDrag is used to calculate friction on the body as it rotates. + * @default + */ + this.angularDrag = 0; + + /** + * @property {number} maxAngular - The maximum angular velocity that the Body can reach. + * @default + */ + this.maxAngular = 1000; + + /** + * @property {number} mass - The mass property determines how forces affect the body, as well as how much momentum the body has when it is involved in a collision. + * @default + */ + this.mass = 1; + + /** + * @property {number} linearDamping - linearDamping is used to calculate friction on the body as it moves through the world. For example, this might be used to simulate air or water friction. + * @default + */ + this.linearDamping = 0.0; + + /** + * Set the checkCollision properties to control which directions collision is processed for this Body. + * For example checkCollision.up = false means it won't collide when the collision happened while moving up. + * @property {object} checkCollision - An object containing allowed collision. + */ + this.checkCollision = { none: false, any: true, up: true, down: true, left: true, right: true }; + + /** + * This object is populated with boolean values when the Body collides with another. + * touching.up = true means the collision happened to the top of this Body for example. + * @property {object} touching - An object containing touching results. + */ + this.touching = { none: true, up: false, down: false, left: false, right: false }; + + /** + * This object is populated with boolean values when the Body collides with the World bounds or a Tile. + * For example if blocked.up is true then the Body cannot move up. + * @property {object} blocked - An object containing on which faces this Body is blocked from moving, if any. + */ + this.blocked = { x: 0, y: 0, up: false, down: false, left: false, right: false }; + + /** + * @property {number} facing - A const reference to the direction the Body is traveling or facing. + * @default + */ + this.facing = Phaser.NONE; + + /** + * @property {boolean} rebound - A Body set to rebound will exchange velocity with another Body during collision. Set to false to allow this body to be 'pushed' rather than exchange velocity. + * @default + */ + this.rebound = true; + + /** + * @property {boolean} immovable - An immovable Body will not receive any impacts or exchanges of velocity from other bodies. + * @default + */ + this.immovable = false; + + /** + * @property {boolean} moves - Set to true to allow the Physics system (such as velocity) to move this Body, or false to move it manually. + * @default + */ + this.moves = true; + + /** + * @property {number} rotation - The amount the parent Sprite is rotated. + * @default + */ + this.rotation = 0; + + /** + * @property {boolean} allowRotation - Allow angular rotation? This will cause the Sprite to be rotated via angularVelocity, etc. + * @default + */ + this.allowRotation = true; + + /** + * @property {boolean} allowGravity - Allow this Body to be influenced by the global Gravity value? Note: It will always be influenced by the local gravity if set. + * @default + */ + this.allowGravity = true; + + /** + * @property {function} customSeparateCallback - If set this callback will be used for Body separation instead of the built-in one. Callback should return true if separated, otherwise false. + * @default + */ + this.customSeparateCallback = null; + + /** + * @property {object} customSeparateContext - The context in which the customSeparateCallback is called. + * @default + */ + this.customSeparateContext = null; + + /** + * @property {function} collideCallback - If set this callback will be fired whenever this Body is hit (on any face). It will send three parameters, the face it hit on, this Body and the Body that hit it. + * @default + */ + this.collideCallback = null; + + /** + * @property {object} collideCallbackContext - The context in which the collideCallback is called. + * @default + */ + this.collideCallbackContext = null; + + /** + * A Body can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World. + * @property {boolean} collideWorldBounds - Should the Body collide with the World bounds? + */ + this.collideWorldBounds = false; + + /** + * @property {Phaser.Physics.Arcade.RECT|Phaser.Physics.Arcade.CIRCLE} type - The type of SAT Shape. + */ + this.type = Phaser.Physics.Arcade.RECT; + + /** + * @property {SAT.Box|SAT.Circle|SAT.Polygon} shape - The SAT Collision shape. + */ + this.shape = null; + + /** + * @property {SAT.Polygon} polygon - The SAT Polygons, as derived from the Shape. + */ + this.polygon = null; + + /** + * @property {number} left - The left-most point of this Body. * @readonly */ - this.screenX = sprite.x; + this.left = 0; /** - * @property {number} screenY - The y position of the physics body translated to screen space. + * @property {number} right - The right-most point of this Body. * @readonly */ - this.screenY = sprite.y; + this.right = 0; /** - * @property {number} sourceWidth - The un-scaled original size. + * @property {number} top - The top-most point of this Body. * @readonly */ - this.sourceWidth = sprite.currentFrame.sourceSizeW; + this.top = 0; /** - * @property {number} sourceHeight - The un-scaled original size. + * @property {number} bottom - The bottom-most point of this Body. * @readonly */ - this.sourceHeight = sprite.currentFrame.sourceSizeH; + this.bottom = 0; /** - * @property {number} width - The calculated width of the physics body. + * @property {number} width - The current width of the Body, taking into account the point rotation. + * @readonly */ - this.width = sprite.currentFrame.sourceSizeW; + this.width = 0; /** - * @property .numInternal ID cache + * @property {number} height - The current height of the Body, taking into account the point rotation. + * @readonly */ - this.height = sprite.currentFrame.sourceSizeH; + this.height = 0; /** - * @property {number} halfWidth - The calculated width / 2 of the physics body. + * @property {array} contacts - Used to store references to bodies this Body is in contact with. + * @protected */ - this.halfWidth = Math.floor(sprite.currentFrame.sourceSizeW / 2); + this.contacts = []; /** - * @property {number} halfHeight - The calculated height / 2 of the physics body. + * @property {number} overlapX - Mostly used internally to store the overlap values from Tile seperation. + * @protected */ - this.halfHeight = Math.floor(sprite.currentFrame.sourceSizeH / 2); + this.overlapX = 0; /** - * @property {Phaser.Point} center - The center coordinate of the Physics Body. + * @property {number} overlapY - Mostly used internally to store the overlap values from Tile seperation. + * @protected */ - this.center = new Phaser.Point(this.x + this.halfWidth, this.y + this.halfHeight); + this.overlapY = 0; + + /** + * @property {Phaser.Point} _temp - Internal cache var. + * @private + */ + this._temp = null; + + /** + * @property {number} _dx - Internal cache var. + * @private + */ + this._dx = 0; + + /** + * @property {number} _dy - Internal cache var. + * @private + */ + this._dy = 0; /** * @property {number} _sx - Internal cache var. @@ -36516,231 +40563,80 @@ Phaser.Physics.Arcade.Body = function (sprite) { this._sy = sprite.scale.y; /** - * @property {Phaser.Point} velocity - The velocity in pixels per second sq. of the Body. + * @property {array} _distances - Internal cache var. + * @private */ - this.velocity = new Phaser.Point(); + this._distances = [0, 0, 0, 0]; /** - * @property {Phaser.Point} acceleration - The velocity in pixels per second sq. of the Body. + * @property {number} _vx - Internal cache var. + * @private */ - this.acceleration = new Phaser.Point(); + this._vx = 0; /** - * @property {Phaser.Point} drag - The drag applied to the motion of the Body. + * @property {number} _vy - Internal cache var. + * @private */ - this.drag = new Phaser.Point(); + this._vy = 0; - /** - * @property {Phaser.Point} gravity - A private Gravity setting for the Body. - */ - this.gravity = new Phaser.Point(); + // Set-up the default shape + this.setRectangle(sprite.width, sprite.height, 0, 0); - /** - * @property {Phaser.Point} bounce - The elasticitiy of the Body when colliding. bounce.x/y = 1 means full rebound, bounce.x/y = 0.5 means 50% rebound velocity. - */ - this.bounce = new Phaser.Point(); - - /** - * @property {Phaser.Point} maxVelocity - The maximum velocity in pixels per second sq. that the Body can reach. - * @default - */ - this.maxVelocity = new Phaser.Point(10000, 10000); - - /** - * @property {number} angularVelocity - The angular velocity in pixels per second sq. of the Body. - * @default - */ - this.angularVelocity = 0; - - /** - * @property {number} angularAcceleration - The angular acceleration in pixels per second sq. of the Body. - * @default - */ - this.angularAcceleration = 0; - - /** - * @property {number} angularDrag - The angular drag applied to the rotation of the Body. - * @default - */ - this.angularDrag = 0; - - /** - * @property {number} maxAngular - The maximum angular velocity in pixels per second sq. that the Body can reach. - * @default - */ - this.maxAngular = 1000; - - /** - * @property {number} mass - The mass of the Body. - * @default - */ - this.mass = 1; - - /** - * @property {boolean} skipQuadTree - If the Body is an irregular shape you can set this to true to avoid it being added to the World quad tree. - * @default - */ - this.skipQuadTree = false; - - /** - * @property {Array} quadTreeIDs - Internal ID cache. - * @protected - */ - this.quadTreeIDs = []; - - /** - * @property {number} quadTreeIndex - Internal ID cache. - * @protected - */ - this.quadTreeIndex = -1; - - // Allow collision - - /** - * Set the allowCollision properties to control which directions collision is processed for this Body. - * For example allowCollision.up = false means it won't collide when the collision happened while moving up. - * @property {object} allowCollision - An object containing allowed collision. - */ - this.allowCollision = { none: false, any: true, up: true, down: true, left: true, right: true }; - - /** - * This object is populated with boolean values when the Body collides with another. - * touching.up = true means the collision happened to the top of this Body for example. - * @property {object} touching - An object containing touching results. - */ - this.touching = { none: true, up: false, down: false, left: false, right: false }; - - /** - * This object is populated with previous touching values from the bodies previous collision. - * @property {object} wasTouching - An object containing previous touching results. - */ - this.wasTouching = { none: true, up: false, down: false, left: false, right: false }; - - /** - * @property {number} facing - A const reference to the direction the Body is traveling or facing. - * @default - */ - this.facing = Phaser.NONE; - - /** - * @property {boolean} immovable - An immovable Body will not receive any impacts from other bodies. - * @default - */ - this.immovable = false; - - /** - * @property {boolean} moves - Set to true to allow the Physics system to move this Body, other false to move it manually. - * @default - */ - this.moves = true; - - /** - * @property {number} rotation - The amount the Body is rotated. - * @default - */ - this.rotation = 0; - - /** - * @property {boolean} allowRotation - Allow this Body to be rotated? (via angularVelocity, etc) - * @default - */ - this.allowRotation = true; - - /** - * @property {boolean} allowGravity - Allow this Body to be influenced by the global Gravity? - * @default - */ - this.allowGravity = true; - - /** - * This flag allows you to disable the custom x separation that takes place by Physics.Arcade.separate. - * Used in combination with your own collision processHandler you can create whatever type of collision response you need. - * @property {boolean} customSeparateX - Use a custom separation system or the built-in one? - * @default - */ - this.customSeparateX = false; - - /** - * This flag allows you to disable the custom y separation that takes place by Physics.Arcade.separate. - * Used in combination with your own collision processHandler you can create whatever type of collision response you need. - * @property {boolean} customSeparateY - Use a custom separation system or the built-in one? - * @default - */ - this.customSeparateY = false; - - /** - * When this body collides with another, the amount of overlap is stored here. - * @property {number} overlapX - The amount of horizontal overlap during the collision. - */ - this.overlapX = 0; - - /** - * When this body collides with another, the amount of overlap is stored here. - * @property {number} overlapY - The amount of vertical overlap during the collision. - */ - this.overlapY = 0; - - /** - * @property {Phaser.Rectangle} hullX - The dynamically calculated hull used during collision. - */ - this.hullX = new Phaser.Rectangle(); - - /** - * @property {Phaser.Rectangle} hullY - The dynamically calculated hull used during collision. - */ - this.hullY = new Phaser.Rectangle(); - - /** - * If a body is overlapping with another body, but neither of them are moving (maybe they spawned on-top of each other?) this is set to true. - * @property {boolean} embedded - Body embed value. - */ - this.embedded = false; - - /** - * A Body can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World. - * @property {boolean} collideWorldBounds - Should the Body collide with the World bounds? - */ - this.collideWorldBounds = false; + // Set-up contact events + this.sprite.events.onBeginContact = new Phaser.Signal(); + this.sprite.events.onEndContact = new Phaser.Signal(); }; Phaser.Physics.Arcade.Body.prototype = { /** - * Internal method. + * Internal method that updates the Body scale in relation to the parent Sprite. * - * @method Phaser.Physics.Arcade#updateBounds + * @method Phaser.Physics.Arcade.Body#updateScale * @protected */ - updateBounds: function (centerX, centerY, scaleX, scaleY) { + updateScale: function () { - if (scaleX != this._sx || scaleY != this._sy) + if (this.polygon) { - this.width = this.sourceWidth * scaleX; - this.height = this.sourceHeight * scaleY; - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); - this._sx = scaleX; - this._sy = scaleY; - this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight); + this.polygon.scale(this.sprite.scale.x / this._sx, this.sprite.scale.y / this._sy); } + else + { + this.shape.r *= Math.max(this.sprite.scale.x, this.sprite.scale.y); + } + + this._sx = this.sprite.scale.x; + this._sy = this.sprite.scale.y; }, /** - * Internal method. + * Internal method that updates the Body position in relation to the parent Sprite. * - * @method Phaser.Physics.Arcade#preUpdate + * @method Phaser.Physics.Arcade.Body#preUpdate * @protected */ preUpdate: function () { - // Store and reset collision flags - this.wasTouching.none = this.touching.none; - this.wasTouching.up = this.touching.up; - this.wasTouching.down = this.touching.down; - this.wasTouching.left = this.touching.left; - this.wasTouching.right = this.touching.right; + this.x = (this.sprite.world.x - (this.sprite.anchor.x * this.sprite.width)) + this.offset.x; + this.y = (this.sprite.world.y - (this.sprite.anchor.y * this.sprite.height)) + this.offset.y; + + // This covers any motion that happens during this frame, not since the last frame + this.preX = this.x; + this.preY = this.y; + this.preRotation = this.sprite.angle; + + this.rotation = this.preRotation; + + if (this.sprite.scale.x !== this._sx || this.sprite.scale.y !== this._sy) + { + this.updateScale(); + } + + this.checkBlocked(); this.touching.none = true; this.touching.up = false; @@ -36748,290 +40644,1135 @@ Phaser.Physics.Arcade.Body.prototype = { this.touching.left = false; this.touching.right = false; - this.embedded = false; - - this.screenX = (this.sprite.worldTransform[2] - (this.sprite.anchor.x * this.width)) + this.offset.x; - this.screenY = (this.sprite.worldTransform[5] - (this.sprite.anchor.y * this.height)) + this.offset.y; - - this.preX = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x; - this.preY = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y; - - this.preRotation = this.sprite.angle; - - this.x = this.preX; - this.y = this.preY; - this.rotation = this.preRotation; - if (this.moves) { - this.game.physics.updateMotion(this); - - if (this.collideWorldBounds) + if (this._vx !== this.velocity.x || this._vy !== this.velocity.y) { - this.checkWorldBounds(); + // No need to re-calc these if they haven't changed + this._vx = this.velocity.x; + this._vy = this.velocity.y; + this.speed = Math.sqrt(this.velocity.x * this.velocity.x + this.velocity.y * this.velocity.y); + this.angle = Math.atan2(this.velocity.y, this.velocity.x); } - this.updateHulls(); - } + if (this.game.physics.checkBounds(this)) + { + this.reboundCheck(true, true, true); + } - if (this.skipQuadTree === false && this.allowCollision.none === false && this.sprite.visible && this.sprite.alive) + this.applyDamping(); + + this.integrateVelocity(); + + this.updateBounds(); + + this.checkBlocked(); + } + else { - this.quadTreeIDs = []; - this.quadTreeIndex = -1; - this.game.physics.quadTree.insert(this); + this.updateBounds(); } }, /** - * Internal method. + * Internal method that checks and potentially resets the blocked status flags. * - * @method Phaser.Physics.Arcade#postUpdate + * @method Phaser.Physics.Arcade.Body#checkBlocked + * @protected + */ + checkBlocked: function () { + + if ((this.blocked.left || this.blocked.right) && (Math.floor(this.x) !== this.blocked.x || Math.floor(this.y) !== this.blocked.y)) + { + this.blocked.left = false; + this.blocked.right = false; + } + + if ((this.blocked.up || this.blocked.down) && (Math.floor(this.x) !== this.blocked.x || Math.floor(this.y) !== this.blocked.y)) + { + this.blocked.up = false; + this.blocked.down = false; + } + + }, + + /** + * Internal method that updates the left, right, top, bottom, width and height properties. + * + * @method Phaser.Physics.Arcade.Body#updateBounds + * @protected + */ + updateBounds: function () { + + if (this.type === Phaser.Physics.Arcade.CIRCLE) + { + this.left = this.shape.pos.x - this.shape.r; + this.right = this.shape.pos.x + this.shape.r; + this.top = this.shape.pos.y - this.shape.r; + this.bottom = this.shape.pos.y + this.shape.r; + } + else + { + this.left = Phaser.Math.minProperty('x', this.polygon.points) + this.polygon.pos.x; + this.right = Phaser.Math.maxProperty('x', this.polygon.points) + this.polygon.pos.x; + this.top = Phaser.Math.minProperty('y', this.polygon.points) + this.polygon.pos.y; + this.bottom = Phaser.Math.maxProperty('y', this.polygon.points) + this.polygon.pos.y; + } + + this.width = this.right - this.left; + this.height = this.bottom - this.top; + + }, + + /** + * Internal method that checks the acceleration and applies damping if not set. + * + * @method Phaser.Physics.Arcade.Body#applyDamping + * @protected + */ + applyDamping: function () { + + if (this.linearDamping > 0 && this.acceleration.isZero()) + { + if (this.speed > this.linearDamping) + { + this.speed -= this.linearDamping; + } + else + { + this.speed = 0; + } + + // Don't bother if speed 0 + if (this.speed > 0) + { + this.velocity.x = Math.cos(this.angle) * this.speed; + this.velocity.y = Math.sin(this.angle) * this.speed; + + this.speed = Math.sqrt(this.velocity.x * this.velocity.x + this.velocity.y * this.velocity.y); + this.angle = Math.atan2(this.velocity.y, this.velocity.x); + } + } + + }, + + /** + * Check if we're below minVelocity and gravity isn't trying to drag us in the opposite direction. + * + * @method Phaser.Physics.Arcade.Body#reboundCheck + * @protected + * @param {boolean} x - Check the X axis? + * @param {boolean} y - Check the Y axis? + * @param {boolean} rebound - If true it will reverse the velocity on the given axis + */ + reboundCheck: function (x, y, rebound) { + + if (x) + { + if (rebound && this.bounce.x !== 0 && (this.blocked.left || this.blocked.right || this.touching.left || this.touching.right)) + { + // Don't rebound if they've already rebounded in this frame + if (!(this._vx <= 0 && this.velocity.x > 0) && !(this._vx >= 0 && this.velocity.x < 0)) + { + this.velocity.x *= -this.bounce.x; + this.angle = Math.atan2(this.velocity.y, this.velocity.x); + } + } + + if (this.bounce.x === 0 || Math.abs(this.velocity.x) < this.minVelocity.x) + { + var gx = this.getUpwardForce(); + + if (((this.blocked.left || this.touching.left) && (gx < 0 || this.velocity.x < 0)) || ((this.blocked.right || this.touching.right) && (gx > 0 || this.velocity.x > 0))) + { + this.velocity.x = 0; + } + } + } + + if (y) + { + if (rebound && this.bounce.y !== 0 && (this.blocked.up || this.blocked.down || this.touching.up || this.touching.down)) + { + // Don't rebound if they've already rebounded in this frame + if (!(this._vy <= 0 && this.velocity.y > 0) && !(this._vy >= 0 && this.velocity.y < 0)) + { + this.velocity.y *= -this.bounce.y; + this.angle = Math.atan2(this.velocity.y, this.velocity.x); + } + } + + if (this.bounce.y === 0 || Math.abs(this.velocity.y) < this.minVelocity.y) + { + var gy = this.getDownwardForce(); + + if (((this.blocked.up || this.touching.up) && (gy < 0 || this.velocity.y < 0)) || ((this.blocked.down || this.touching.down) && (gy > 0 || this.velocity.y > 0))) + { + this.velocity.y = 0; + } + } + } + + }, + + /** + * Gets the total force being applied on the X axis, including gravity and velocity. + * + * @method Phaser.Physics.Arcade.Body#getUpwardForce + * @return {number} The total force being applied on the X axis. + */ + getUpwardForce: function () { + + if (this.allowGravity) + { + return this.gravity.x + this.game.physics.gravity.x + this.velocity.x; + } + else + { + return this.gravity.x + this.velocity.x; + } + + }, + + /** + * Gets the total force being applied on the X axis, including gravity and velocity. + * + * @method Phaser.Physics.Arcade.Body#getDownwardForce + * @return {number} The total force being applied on the Y axis. + */ + getDownwardForce: function () { + + if (this.allowGravity) + { + return this.gravity.y + this.game.physics.gravity.y + this.velocity.y; + } + else + { + return this.gravity.y + this.velocity.y; + } + + }, + + /** + * Subtracts the given Vector from this Body. + * + * @method Phaser.Physics.Arcade.Body#sub + * @protected + * @param {SAT.Vector} v - The vector to substract from this Body. + */ + sub: function (v) { + + this.x -= v.x; + this.y -= v.y; + + }, + + /** + * Adds the given Vector to this Body. + * + * @method Phaser.Physics.Arcade.Body#add + * @protected + * @param {SAT.Vector} v - The vector to add to this Body. + */ + add: function (v) { + + this.x += v.x; + this.y += v.y; + + }, + + /** + * Separation response handler. + * + * @method Phaser.Physics.Arcade.Body#give + * @protected + * @param {Phaser.Physics.Arcade.Body} body - The Body that collided. + * @param {SAT.Response} response - The SAT Response object containing the collision data. + */ + give: function (body, response) { + + this.add(response.overlapV); + + if (this.rebound) + { + this.processRebound(body); + this.reboundCheck(true, true, false); + body.reboundCheck(true, true, false); + } + + }, + + /** + * Separation response handler. + * + * @method Phaser.Physics.Arcade.Body#take + * @protected + * @param {Phaser.Physics.Arcade.Body} body - The Body that collided. + * @param {SAT.Response} response - The SAT Response object containing the collision data. + */ + take: function (body, response) { + + this.sub(response.overlapV); + + if (this.rebound) + { + this.processRebound(body); + this.reboundCheck(true, true, false); + body.reboundCheck(true, true, false); + } + + }, + + /** + * Split the collision response evenly between the two bodies. + * + * @method Phaser.Physics.Arcade.Body#split + * @protected + * @param {Phaser.Physics.Arcade.Body} body - The Body that collided. + * @param {SAT.Response} response - The SAT Response object containing the collision data. + */ + split: function (body, response) { + + response.overlapV.scale(0.5); + this.sub(response.overlapV); + body.add(response.overlapV); + + if (this.rebound) + { + this.exchange(body); + this.reboundCheck(true, true, false); + body.reboundCheck(true, true, false); + } + + }, + + /** + * Exchange velocity with the given Body. + * + * @method Phaser.Physics.Arcade.Body#exchange + * @protected + * @param {Phaser.Physics.Arcade.Body} body - The Body that collided. + */ + exchange: function (body) { + + if (this.mass === body.mass && this.speed > 0 && body.speed > 0) + { + // A direct velocity exchange (as they are both moving and have the same mass) + this._dx = body.velocity.x; + this._dy = body.velocity.y; + + body.velocity.x = this.velocity.x * body.bounce.x; + body.velocity.y = this.velocity.y * body.bounce.x; + + this.velocity.x = this._dx * this.bounce.x; + this.velocity.y = this._dy * this.bounce.y; + } + else + { + var nv1 = Math.sqrt((body.velocity.x * body.velocity.x * body.mass) / this.mass) * ((body.velocity.x > 0) ? 1 : -1); + var nv2 = Math.sqrt((this.velocity.x * this.velocity.x * this.mass) / body.mass) * ((this.velocity.x > 0) ? 1 : -1); + var average = (nv1 + nv2) * 0.5; + nv1 -= average; + nv2 -= average; + + this.velocity.x = nv1; + body.velocity.x = nv2; + + nv1 = Math.sqrt((body.velocity.y * body.velocity.y * body.mass) / this.mass) * ((body.velocity.y > 0) ? 1 : -1); + nv2 = Math.sqrt((this.velocity.y * this.velocity.y * this.mass) / body.mass) * ((this.velocity.y > 0) ? 1 : -1); + average = (nv1 + nv2) * 0.5; + nv1 -= average; + nv2 -= average; + + this.velocity.y = nv1; + body.velocity.y = nv2; + } + + // update speed / angle? + + }, + + /** + * Rebound the velocity of this Body. + * + * @method Phaser.Physics.Arcade.Body#processRebound + * @protected + * @param {Phaser.Physics.Arcade.Body} body - The Body that collided. + */ + processRebound: function (body) { + + // Don't rebound again if they've already rebounded in this frame + if (!(this._vx <= 0 && this.velocity.x > 0) && !(this._vx >= 0 && this.velocity.x < 0)) + { + this.velocity.x = body.velocity.x - this.velocity.x * this.bounce.x; + } + + if (!(this._vy <= 0 && this.velocity.y > 0) && !(this._vy >= 0 && this.velocity.y < 0)) + { + this.velocity.y = body.velocity.y - this.velocity.y * this.bounce.y; + } + + this.angle = Math.atan2(this.velocity.y, this.velocity.x); + + this.reboundCheck(true, true, false); + + }, + + /** + * Checks for an overlap between this Body and the given Body. + * + * @method Phaser.Physics.Arcade.Body#overlap + * @param {Phaser.Physics.Arcade.Body} body - The Body that is being checked against this Body. + * @param {SAT.Response} response - SAT Response handler. + * @return {boolean} True if the two bodies overlap, otherwise false. + */ + overlap: function (body, response) { + + var result = false; + + if ((this.type === Phaser.Physics.Arcade.RECT || this.type === Phaser.Physics.Arcade.POLYGON) && (body.type === Phaser.Physics.Arcade.RECT || body.type === Phaser.Physics.Arcade.POLYGON)) + { + result = SAT.testPolygonPolygon(this.polygon, body.polygon, response); + } + else if (this.type === Phaser.Physics.Arcade.CIRCLE && body.type === Phaser.Physics.Arcade.CIRCLE) + { + result = SAT.testCircleCircle(this.shape, body.shape, response); + } + else if ((this.type === Phaser.Physics.Arcade.RECT || this.type === Phaser.Physics.Arcade.POLYGON) && body.type === Phaser.Physics.Arcade.CIRCLE) + { + result = SAT.testPolygonCircle(this.polygon, body.shape, response); + } + else if (this.type === Phaser.Physics.Arcade.CIRCLE && (body.type === Phaser.Physics.Arcade.RECT || body.type === Phaser.Physics.Arcade.POLYGON)) + { + result = SAT.testCirclePolygon(this.shape, body.polygon, response); + } + + if (!result) + { + this.removeContact(body); + } + + return result; + + }, + + /** + * Checks if this Body is already in contact with the given Body. + * + * @method Phaser.Physics.Arcade.Body#inContact + * @param {Phaser.Physics.Arcade.Body} body - The Body to be checked. + * @return {boolean} True if the given Body is already in contact with this Body. + */ + inContact: function (body) { + + return (this.contacts.indexOf(body) != -1); + + }, + + /** + * Adds the given Body to the contact list of this Body. Also adds this Body to the contact list of the given Body. + * + * @method Phaser.Physics.Arcade.Body#addContact + * @param {Phaser.Physics.Arcade.Body} body - The Body to be added. + * @return {boolean} True if the given Body was added to this contact list, false if already on it. + */ + addContact: function (body) { + + if (this.inContact(body)) + { + return false; + } + + this.contacts.push(body); + + this.sprite.events.onBeginContact.dispatch(this.sprite, body.sprite, this, body); + + body.addContact(this); + + return true; + + }, + + /** + * Removes the given Body from the contact list of this Body. Also removes this Body from the contact list of the given Body. + * + * @method Phaser.Physics.Arcade.Body#removeContact + * @param {Phaser.Physics.Arcade.Body} body - The Body to be removed. + * @return {boolean} True if the given Body was removed from this contact list, false if wasn't on it. + */ + removeContact: function (body) { + + if (!this.inContact(body)) + { + return false; + } + + this.contacts.splice(this.contacts.indexOf(body), 1); + + this.sprite.events.onEndContact.dispatch(this.sprite, body.sprite, this, body); + + body.removeContact(this); + + return true; + + }, + + /** + * This separates this Body from the given Body unless a customSeparateCallback is set. + * It assumes they have already been overlap checked and the resulting overlap is stored in the SAT response. + * + * @method Phaser.Physics.Arcade.Body#separate + * @protected + * @param {Phaser.Physics.Arcade.Body} body - The Body to be separated from this one. + * @param {SAT.Response} response - SAT Response handler. + * @return {boolean} True if the bodies were separated, false if not (for example checkCollide allows them to pass through) + */ + separate: function (body, response) { + + if (this.inContact(body)) + { + return false; + } + + this._distances[0] = body.right - this.x; // Distance of B to face on left side of A + this._distances[1] = this.right - body.x; // Distance of B to face on right side of A + this._distances[2] = body.bottom - this.y; // Distance of B to face on bottom side of A + this._distances[3] = this.bottom - body.y; // Distance of B to face on top side of A + + // If we've zero distance then check for side-slicing + if (response.overlapN.x && (this._distances[0] === 0 || this._distances[1] === 0)) + { + response.overlapN.x = false; + response.overlapN.y = true; + } + else if (response.overlapN.y && (this._distances[2] === 0 || this._distances[3] === 0)) + { + response.overlapN.x = true; + response.overlapN.y = false; + } + + if (this.customSeparateCallback) + { + return this.customSeparateCallback.call(this.customSeparateContext, this, response, this._distances); + } + + var hasSeparated = false; + + if (response.overlapN.x) + { + // Which is smaller? Left or Right? + if (this._distances[0] < this._distances[1]) + { + hasSeparated = this.hitLeft(body, response); + } + else if (this._distances[1] < this._distances[0]) + { + hasSeparated = this.hitRight(body, response); + } + } + else if (response.overlapN.y) + { + // Which is smaller? Top or Bottom? + if (this._distances[2] < this._distances[3]) + { + hasSeparated = this.hitTop(body, response); + } + else if (this._distances[3] < this._distances[2]) + { + hasSeparated = this.hitBottom(body, response); + } + } + + if (hasSeparated) + { + this.game.physics.checkBounds(this); + this.game.physics.checkBounds(body); + } + else + { + // They can only contact like this if at least one of their sides is open, otherwise it's a separation + // if (!this.checkCollision.up || !this.checkCollision.down || !this.checkCollision.left || !this.checkCollision.right || !body.checkCollision.up || !body.checkCollision.down || !body.checkCollision.left || !body.checkCollision.right) + // { + this.addContact(body); + // } + } + + return hasSeparated; + + }, + + /** + * Process a collision with the left face of this Body. + * Collision and separation can be further checked by setting a collideCallback. + * This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response. + * If the callback returns true then separation, rebounds and the touching flags will all be set. + * If it returns false this will be skipped and must be handled manually. + * + * @method Phaser.Physics.Arcade.Body#hitLeft + * @protected + * @param {Phaser.Physics.Arcade.Body} body - The Body that collided. + * @param {SAT.Response} response - The SAT Response object containing the collision data. + */ + hitLeft: function (body, response) { + + if (!this.checkCollision.left || !body.checkCollision.right) + { + return false; + } + + if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.LEFT, this, body, response)) + { + return; + } + + if (!this.moves || this.immovable || this.blocked.right || this.touching.right) + { + body.give(this, response); + } + else + { + if (body.immovable || body.blocked.left || body.touching.left) + { + // We take the full separation + this.take(body, response); + } + else + { + // Share out the separation + this.split(body, response); + } + } + + this.touching.left = true; + body.touching.right = true; + + }, + + /** + * Process a collision with the right face of this Body. + * Collision and separation can be further checked by setting a collideCallback. + * This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response. + * If the callback returns true then separation, rebounds and the touching flags will all be set. + * If it returns false this will be skipped and must be handled manually. + * + * @method Phaser.Physics.Arcade.Body#hitRight + * @protected + * @param {Phaser.Physics.Arcade.Body} body - The Body that collided. + * @param {SAT.Response} response - The SAT Response object containing the collision data. + */ + hitRight: function (body, response) { + + if (!this.checkCollision.right || !body.checkCollision.left) + { + return false; + } + + if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.RIGHT, this, body)) + { + return; + } + + if (!this.moves || this.immovable || this.blocked.left || this.touching.left) + { + body.give(this, response); + } + else + { + if (body.immovable || body.blocked.right || body.touching.right) + { + // We take the full separation + this.take(body, response); + } + else + { + // Share out the separation + this.split(body, response); + } + } + + this.touching.right = true; + body.touching.left = true; + + }, + + /** + * Process a collision with the top face of this Body. + * Collision and separation can be further checked by setting a collideCallback. + * This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response. + * If the callback returns true then separation, rebounds and the touching flags will all be set. + * If it returns false this will be skipped and must be handled manually. + * + * @method Phaser.Physics.Arcade.Body#hitTop + * @protected + * @param {Phaser.Physics.Arcade.Body} body - The Body that collided. + * @param {SAT.Response} response - The SAT Response object containing the collision data. + */ + hitTop: function (body, response) { + + if (!this.checkCollision.up || !body.checkCollision.down) + { + return false; + } + + if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.UP, this, body)) + { + return false; + } + + if (!this.moves || this.immovable || this.blocked.down || this.touching.down) + { + body.give(this, response); + } + else + { + if (body.immovable || body.blocked.up || body.touching.up) + { + // We take the full separation + this.take(body, response); + } + else + { + // Share out the separation + this.split(body, response); + } + } + + this.touching.up = true; + body.touching.down = true; + + return true; + + }, + + /** + * Process a collision with the bottom face of this Body. + * Collision and separation can be further checked by setting a collideCallback. + * This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response. + * If the callback returns true then separation, rebounds and the touching flags will all be set. + * If it returns false this will be skipped and must be handled manually. + * + * @method Phaser.Physics.Arcade.Body#hitBottom + * @protected + * @param {Phaser.Physics.Arcade.Body} body - The Body that collided. + * @param {SAT.Response} response - The SAT Response object containing the collision data. + */ + hitBottom: function (body, response) { + + if (!this.checkCollision.down || !body.checkCollision.up) + { + return false; + } + + if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.DOWN, this, body)) + { + return false; + } + + if (!this.moves || this.immovable || this.blocked.up || this.touching.up) + { + body.give(this, response); + } + else + { + if (body.immovable || body.blocked.down || body.touching.down) + { + // We take the full separation + this.take(body, response); + } + else + { + // Share out the separation + this.split(body, response); + } + } + + this.touching.down = true; + body.touching.up = true; + + return true; + + }, + + /** + * Internal method. Integrates velocity, global gravity and the delta timer. + * + * @method Phaser.Physics.Arcade.Body#integrateVelocity + * @protected + */ + integrateVelocity: function () { + + this._temp = this.game.physics.updateMotion(this); + this._dx = this.game.time.physicsElapsed * (this.velocity.x + this._temp.x / 2); + this._dy = this.game.time.physicsElapsed * (this.velocity.y + this._temp.y / 2); + + // positive = RIGHT / DOWN + // negative = LEFT / UP + + if ((this._dx < 0 && !this.blocked.left && !this.touching.left) || (this._dx > 0 && !this.blocked.right && !this.touching.right)) + { + this.x += this._dx; + this.velocity.x += this._temp.x; + } + + if ((this._dy < 0 && !this.blocked.up && !this.touching.up) || (this._dy > 0 && !this.blocked.down && !this.touching.down)) + { + this.y += this._dy; + this.velocity.y += this._temp.y; + } + + if (this.velocity.x > this.maxVelocity.x) + { + this.velocity.x = this.maxVelocity.x; + } + else if (this.velocity.x < -this.maxVelocity.x) + { + this.velocity.x = -this.maxVelocity.x; + } + + if (this.velocity.y > this.maxVelocity.y) + { + this.velocity.y = this.maxVelocity.y; + } + else if (this.velocity.y < -this.maxVelocity.y) + { + this.velocity.y = -this.maxVelocity.y; + } + + }, + + /** + * Internal method. This is called directly before the sprites are sent to the renderer and after the update function has finished. + * + * @method Phaser.Physics.Arcade.Body#postUpdate * @protected */ postUpdate: function () { - if (this.deltaX() < 0) + if (this.moves) { - this.facing = Phaser.LEFT; - } - else if (this.deltaX() > 0) - { - this.facing = Phaser.RIGHT; - } + this.game.physics.checkBounds(this); - if (this.deltaY() < 0) - { - this.facing = Phaser.UP; - } - else if (this.deltaY() > 0) - { - this.facing = Phaser.DOWN; - } + this.reboundCheck(true, true, true); - if (this.deltaX() !== 0 || this.deltaY() !== 0) - { - this.sprite.x += this.deltaX(); - this.sprite.y += this.deltaY(); - this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight); - } + this._dx = this.deltaX(); + this._dy = this.deltaY(); - if (this.allowRotation) - { - this.sprite.angle += this.deltaZ(); + if (this._dx < 0) + { + this.facing = Phaser.LEFT; + } + else if (this._dx > 0) + { + this.facing = Phaser.RIGHT; + } + + if (this._dy < 0) + { + this.facing = Phaser.UP; + } + else if (this._dy > 0) + { + this.facing = Phaser.DOWN; + } + + if (this._dx !== 0 || this._dy !== 0) + { + this.sprite.x += this._dx; + this.sprite.y += this._dy; + } + + if (this.allowRotation && this.deltaZ() !== 0) + { + this.sprite.angle += this.deltaZ(); + } + + if (this.sprite.scale.x !== this._sx || this.sprite.scale.y !== this._sy) + { + this.updateScale(); + } } }, /** - * Internal method. + * Resets the Body motion values: velocity, acceleration, angularVelocity and angularAcceleration. + * Also resets the forces to defaults: gravity, bounce, minVelocity,maxVelocity, angularDrag, maxAngular, mass, friction and checkCollision if 'full' specified. * - * @method Phaser.Physics.Arcade#updateHulls - * @protected + * @method Phaser.Physics.Arcade.Body#reset + * @param {boolean} [full=false] - A full reset clears down settings you may have set, such as gravity, bounce and drag. A non-full reset just clears motion values. */ - updateHulls: function () { + reset: function (full) { - this.hullX.setTo(this.x, this.preY, this.width, this.height); - this.hullY.setTo(this.preX, this.y, this.width, this.height); + if (typeof full === 'undefined') { full = false; } - }, - - /** - * Internal method. - * - * @method Phaser.Physics.Arcade#checkWorldBounds - * @protected - */ - checkWorldBounds: function () { - - if (this.x < this.game.world.bounds.x) + if (full) { - this.x = this.game.world.bounds.x; - this.velocity.x *= -this.bounce.x; + this.gravity.setTo(0, 0); + this.bounce.setTo(0, 0); + this.minVelocity.setTo(5, 5); + this.maxVelocity.setTo(1000, 1000); + this.angularDrag = 0; + this.maxAngular = 1000; + this.mass = 1; + this.friction = 0.0; + this.checkCollision = { none: false, any: true, up: true, down: true, left: true, right: true }; } - else if (this.right > this.game.world.bounds.right) - { - this.x = this.game.world.bounds.right - this.width; - this.velocity.x *= -this.bounce.x; - } - - if (this.y < this.game.world.bounds.y) - { - this.y = this.game.world.bounds.y; - this.velocity.y *= -this.bounce.y; - } - else if (this.bottom > this.game.world.bounds.bottom) - { - this.y = this.game.world.bounds.bottom - this.height; - this.velocity.y *= -this.bounce.y; - } - - }, - - /** - * You can modify the size of the physics Body to be any dimension you need. - * So it could be smaller or larger than the parent Sprite. You can also control the x and y offset, which - * is the position of the Body relative to the top-left of the Sprite. - * - * @method Phaser.Physics.Arcade#setSize - * @param {number} width - The width of the Body. - * @param {number} height - The height of the Body. - * @param {number} offsetX - The X offset of the Body from the Sprite position. - * @param {number} offsetY - The Y offset of the Body from the Sprite position. - */ - setSize: function (width, height, offsetX, offsetY) { - - offsetX = offsetX || this.offset.x; - offsetY = offsetY || this.offset.y; - - this.sourceWidth = width; - this.sourceHeight = height; - this.width = this.sourceWidth * this._sx; - this.height = this.sourceHeight * this._sy; - this.halfWidth = Math.floor(this.width / 2); - this.halfHeight = Math.floor(this.height / 2); - this.offset.setTo(offsetX, offsetY); - - this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight); - - }, - - /** - * Resets all Body values (velocity, acceleration, rotation, etc) - * - * @method Phaser.Physics.Arcade#reset - */ - reset: function () { this.velocity.setTo(0, 0); this.acceleration.setTo(0, 0); - this.angularVelocity = 0; this.angularAcceleration = 0; - this.preX = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x; - this.preY = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y; - this.preRotation = this.sprite.angle; + this.blocked = { x: 0, y: 0, up: false, down: false, left: false, right: false }; + this.x = (this.sprite.world.x - (this.sprite.anchor.x * this.sprite.width)) + this.offset.x; + this.y = (this.sprite.world.y - (this.sprite.anchor.y * this.sprite.height)) + this.offset.y; + this.preX = this.x; + this.preY = this.y; + this.updateBounds(); - this.x = this.preX; - this.y = this.preY; - this.rotation = this.preRotation; - - this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight); + this.contacts.length = 0; }, /** - * Returns the absolute delta x value. + * Destroys this Body and all references it holds to other objects. * - * @method Phaser.Physics.Arcade.Body#deltaAbsX - * @return {number} The absolute delta value. + * @method Phaser.Physics.Arcade.Body#destroy */ - deltaAbsX: function () { - return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX()); + destroy: function () { + + this.sprite = null; + + this.collideCallback = null; + this.collideCallbackContext = null; + + this.customSeparateCallback = null; + this.customSeparateContext = null; + + this.contacts.length = 0; + }, /** - * Returns the absolute delta y value. + * Sets this Body to use a circle of the given radius for all collision. + * The Circle will be centered on the center of the Sprite by default, but can be adjusted via the Body.offset property and the setCircle x/y parameters. * - * @method Phaser.Physics.Arcade.Body#deltaAbsY - * @return {number} The absolute delta value. + * @method Phaser.Physics.Arcade.Body#setCircle + * @param {number} radius - The radius of this circle (in pixels) + * @param {number} [offsetX=0] - The x amount the circle will be offset from the Sprites center. + * @param {number} [offsetY=0] - The y amount the circle will be offset from the Sprites center. */ - deltaAbsY: function () { - return (this.deltaY() > 0 ? this.deltaY() : -this.deltaY()); + setCircle: function (radius, offsetX, offsetY) { + + if (typeof offsetX === 'undefined') { offsetX = this.sprite._cache.halfWidth; } + if (typeof offsetY === 'undefined') { offsetY = this.sprite._cache.halfHeight; } + + this.type = Phaser.Physics.Arcade.CIRCLE; + this.shape = new SAT.Circle(new SAT.Vector(this.sprite.x, this.sprite.y), radius); + this.polygon = null; + + this.offset.setTo(offsetX, offsetY); + }, /** - * Returns the delta x value. The difference between Body.x now and in the previous step. + * Sets this Body to use a rectangle for all collision. + * If you don't specify any parameters it will be sized to match the parent Sprites current width and height (including scale factor) and centered on the sprite. + * + * @method Phaser.Physics.Arcade.Body#setRectangle + * @param {number} [width] - The width of the rectangle. If not specified it will default to the width of the parent Sprite. + * @param {number} [height] - The height of the rectangle. If not specified it will default to the height of the parent Sprite. + * @param {number} [translateX] - The x amount the rectangle will be translated from the Sprites center. + * @param {number} [translateY] - The y amount the rectangle will be translated from the Sprites center. + */ + setRectangle: function (width, height, translateX, translateY) { + + if (typeof width === 'undefined') { width = this.sprite.width; } + if (typeof height === 'undefined') { height = this.sprite.height; } + if (typeof translateX === 'undefined') { translateX = -this.sprite._cache.halfWidth; } + if (typeof translateY === 'undefined') { translateY = -this.sprite._cache.halfHeight; } + + this.type = Phaser.Physics.Arcade.RECT; + this.shape = new SAT.Box(new SAT.Vector(this.sprite.world.x, this.sprite.world.y), width, height); + this.polygon = this.shape.toPolygon(); + this.polygon.translate(translateX, translateY); + + this.offset.setTo(0, 0); + + }, + + /** + * Sets this Body to use a convex polygon for collision. + * The points are specified in a counter-clockwise direction and must create a convex polygon. + * Use Body.translate and/or Body.offset to re-position the polygon from the Sprite origin. + * + * @method Phaser.Physics.Arcade.Body#setPolygon + * @param {(SAT.Vector[]|number[]|...SAT.Vector|...number)} points - This can be an array of Vectors that form the polygon, + * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be + * all the points of the polygon e.g. `setPolygon(new SAT.Vector(), new SAT.Vector(), ...)`, or the + * arguments passed can be flat x,y values e.g. `setPolygon(x,y, x,y, x,y, ...)` where `x` and `y` are Numbers. + */ + setPolygon: function (points) { + + this.type = Phaser.Physics.Arcade.POLYGON; + this.shape = null; + + if (!Array.isArray(points)) + { + points = Array.prototype.slice.call(arguments); + } + + if (typeof points[0] === 'number') + { + var p = []; + + for (var i = 0, len = points.length; i < len; i += 2) + { + p.push(new SAT.Vector(points[i], points[i + 1])); + } + + points = p; + } + + this.polygon = new SAT.Polygon(new SAT.Vector(this.sprite.center.x, this.sprite.center.y), points); + + this.offset.setTo(0, 0); + + }, + + /** + * Used for translating rectangle and polygon bodies from the Sprite parent. Doesn't apply to Circles. + * See also the Body.offset property. + * + * @method Phaser.Physics.Arcade.Body#translate + * @param {number} x - The x amount the polygon or rectangle will be translated by from the Sprite. + * @param {number} y - The y amount the polygon or rectangle will be translated by from the Sprite. + */ + translate: function (x, y) { + + if (this.polygon) + { + this.polygon.translate(x, y); + } + + }, + + /** + * Determines if this Body is 'on the floor', which means in contact with a Tile or World bounds, or other object that has set 'down' as blocked. + * + * @method Phaser.Physics.Arcade.Body#onFloor + * @return {boolean} True if this Body is 'on the floor', which means in contact with a Tile or World bounds, or object that has set 'down' as blocked. + */ + onFloor: function () { + return this.blocked.down; + }, + + /** + * Determins if this Body is 'on a wall', which means horizontally in contact with a Tile or World bounds, or other object but not the ground. + * + * @method Phaser.Physics.Arcade.Body#onWall + * @return {boolean} True if this Body is 'on a wall', which means horizontally in contact with a Tile or World bounds, or other object but not the ground. + */ + onWall: function () { + return (!this.blocked.down && (this.blocked.left || this.blocked.right)); + }, + + /** + * Returns the delta x value. The amount the Body has moved horizontally in the current step. * * @method Phaser.Physics.Arcade.Body#deltaX - * @return {number} The delta value. + * @return {number} The delta value. Positive if the motion was to the right, negative if to the left. */ deltaX: function () { return this.x - this.preX; }, /** - * Returns the delta y value. The difference between Body.y now and in the previous step. + * Returns the delta y value. The amount the Body has moved vertically in the current step. * * @method Phaser.Physics.Arcade.Body#deltaY - * @return {number} The delta value. + * @return {number} The delta value. Positive if the motion was downwards, negative if upwards. */ deltaY: function () { return this.y - this.preY; }, + /** + * Returns the delta z value. The amount the Body has rotated in the current step. + * + * @method Phaser.Physics.Arcade.Body#deltaZ + * @return {number} The delta value. + */ deltaZ: function () { return this.rotation - this.preRotation; } }; +Phaser.Physics.Arcade.Body.prototype.constructor = Phaser.Physics.Arcade.Body; + /** -* @name Phaser.Physics.Arcade.Body#bottom -* @property {number} bottom - The bottom value of this Body (same as Body.y + Body.height) +* @name Phaser.Physics.Arcade.Body#x +* @property {number} x - The x coordinate of this Body. */ -Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "bottom", { +Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "x", { - /** - * The sum of the y and height properties. Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property. - * @method bottom - * @return {number} - */ get: function () { - return this.y + this.height; - }, - - /** - * The sum of the y and height properties. Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property. - * @method bottom - * @param {number} value - */ - set: function (value) { - - if (value <= this.y) + + if (this.type === Phaser.Physics.Arcade.CIRCLE) { - this.height = 0; + return this.shape.pos.x; } else { - this.height = (this.y - value); + return this.polygon.pos.x; } - + + }, + + set: function (value) { + + if (this.type === Phaser.Physics.Arcade.CIRCLE) + { + this.shape.pos.x = value; + } + else + { + this.polygon.pos.x = value; + } + } }); /** -* @name Phaser.Physics.Arcade.Body#right -* @property {number} right - The right value of this Body (same as Body.x + Body.width) +* @name Phaser.Physics.Arcade.Body#y +* @property {number} y - The y coordinate of this Body. */ -Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "right", { +Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "y", { - /** - * The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties. - * However it does affect the width property. - * @method right - * @return {number} - */ get: function () { - return this.x + this.width; - }, - - /** - * The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties. - * However it does affect the width property. - * @method right - * @param {number} value - */ - set: function (value) { - - if (value <= this.x) + + if (this.type === Phaser.Physics.Arcade.CIRCLE) { - this.width = 0; + return this.shape.pos.y; } else { - this.width = this.x + value; + return this.polygon.pos.y; + } + + }, + + set: function (value) { + + if (this.type === Phaser.Physics.Arcade.CIRCLE) + { + this.shape.pos.y = value; + } + else + { + this.polygon.pos.y = value; } } @@ -37040,7 +41781,7 @@ Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "right", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -37117,10 +41858,13 @@ Phaser.Particles.prototype = { } }; + +Phaser.Particles.prototype.constructor = Phaser.Particles; + Phaser.Particles.Arcade = {} /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -37142,7 +41886,6 @@ Phaser.Particles.Arcade = {} Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) { /** - * The total number of particles in this emitter. * @property {number} maxParticles - The total number of particles in this emitter.. * @default */ @@ -37156,7 +41899,8 @@ Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) { this.name = 'emitter' + this.game.particles.ID++; /** - * @property {Description} type - Description. + * @property {number} type - Internal Phaser Type value. + * @protected */ this.type = Phaser.EMITTER; @@ -37185,140 +41929,114 @@ Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) { this.height = 1; /** - * The minimum possible velocity of a particle. - * The default value is (-100,-100). - * @property {Phaser.Point} minParticleSpeed + * @property {Phaser.Point} minParticleSpeed - The minimum possible velocity of a particle. + * @default */ this.minParticleSpeed = new Phaser.Point(-100, -100); /** - * The maximum possible velocity of a particle. - * The default value is (100,100). - * @property {Phaser.Point} maxParticleSpeed + * @property {Phaser.Point} maxParticleSpeed - The maximum possible velocity of a particle. + * @default */ this.maxParticleSpeed = new Phaser.Point(100, 100); /** - * The minimum possible scale of a particle. - * The default value is 1. - * @property {number} minParticleScale + * @property {number} minParticleScale - The minimum possible scale of a particle. * @default */ this.minParticleScale = 1; /** - * The maximum possible scale of a particle. - * The default value is 1. - * @property {number} maxParticleScale + * @property {number} maxParticleScale - The maximum possible scale of a particle. * @default */ this.maxParticleScale = 1; /** - * The minimum possible angular velocity of a particle. The default value is -360. - * @property {number} minRotation + * @property {number} minRotation - The minimum possible angular velocity of a particle. * @default */ this.minRotation = -360; /** - * The maximum possible angular velocity of a particle. The default value is 360. - * @property {number} maxRotation + * @property {number} maxRotation - The maximum possible angular velocity of a particle. * @default */ this.maxRotation = 360; /** - * Sets the gravity.y of each particle to this value on launch. - * @property {number} gravity + * @property {number} gravity - Sets the `body.gravity.y` of each particle sprite to this value on launch. * @default */ - this.gravity = 2; + this.gravity = 100; /** - * Set your own particle class type here. - * @property {Description} particleClass + * @property {any} particleClass - For emitting your own particle class types. * @default */ this.particleClass = null; /** - * The X and Y drag component of particles launched from the emitter. - * @property {Phaser.Point} particleDrag + * @property {number} particleFriction - The friction component of particles launched from the emitter. + * @default */ - this.particleDrag = new Phaser.Point(); + this.particleFriction = 0; /** - * The angular drag component of particles launched from the emitter if they are rotating. - * @property {number} angularDrag + * @property {number} angularDrag - The angular drag component of particles launched from the emitter if they are rotating. * @default */ this.angularDrag = 0; /** - * How often a particle is emitted in ms (if emitter is started with Explode === false). - * @property {boolean} frequency + * @property {boolean} frequency - How often a particle is emitted in ms (if emitter is started with Explode === false). * @default */ this.frequency = 100; /** - * How long each particle lives once it is emitted in ms. Default is 2 seconds. - * Set lifespan to 'zero' for particles to live forever. - * @property {number} lifespan + * @property {number} lifespan - How long each particle lives once it is emitted in ms. Default is 2 seconds. Set lifespan to 'zero' for particles to live forever. * @default */ this.lifespan = 2000; /** - * How much each particle should bounce on each axis. 1 = full bounce, 0 = no bounce. - * @property {Phaser.Point} bounce + * @property {Phaser.Point} bounce - How much each particle should bounce on each axis. 1 = full bounce, 0 = no bounce. */ this.bounce = new Phaser.Point(); /** - * Internal helper for deciding how many particles to launch. - * @property {number} _quantity + * @property {number} _quantity - Internal helper for deciding how many particles to launch. * @private - * @default */ this._quantity = 0; /** - * Internal helper for deciding when to launch particles or kill them. - * @property {number} _timer + * @property {number} _timer - Internal helper for deciding when to launch particles or kill them. * @private - * @default */ this._timer = 0; /** - * Internal counter for figuring out how many particles to launch. - * @property {number} _counter + * @property {number} _counter - Internal counter for figuring out how many particles to launch. * @private - * @default */ this._counter = 0; /** - * Internal helper for the style of particle emission (all at once, or one at a time). - * @property {boolean} _explode + * @property {boolean} _explode - Internal helper for the style of particle emission (all at once, or one at a time). * @private - * @default */ this._explode = true; /** - * Determines whether the emitter is currently emitting particles. - * It is totally safe to directly toggle this. - * @property {boolean} on + * @property {boolean} on - Determines whether the emitter is currently emitting particles. It is totally safe to directly toggle this. * @default */ this.on = false; /** - * Determines whether the emitter is being updated by the core game loop. - * @property {boolean} exists + * @property {boolean} exists - Determines whether the emitter is being updated by the core game loop. * @default */ this.exists = true; @@ -37392,43 +42110,35 @@ Phaser.Particles.Arcade.Emitter.prototype.update = function () { * This function generates a new array of particle sprites to attach to the emitter. * * @method Phaser.Particles.Arcade.Emitter#makeParticles -* @param {Description} keys - Description. -* @param {number} frames - Description. -* @param {number} quantity - The number of particles to generate when using the "create from image" option. -* @param {number} collide - Description. -* @param {boolean} collideWorldBounds - Description. -* @return This Emitter instance (nice for chaining stuff together, if you're into that). +* @param {array|string} keys - A string or an array of strings that the particle sprites will use as their texture. If an array one is picked at random. +* @param {array|number} frames - A frame number, or array of frames that the sprite will use. If an array one is picked at random. +* @param {number} quantity - The number of particles to generate. +* @param {boolean} [collide=false] - Sets the checkCollision.none flag on the particle sprites body. +* @param {boolean} [collideWorldBounds=false] - A particle can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World. +* @return {Phaser.Particles.Arcade.Emitter} This Emitter instance. */ Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames, quantity, collide, collideWorldBounds) { - if (typeof frames == 'undefined') - { - frames = 0; - } - - quantity = quantity || this.maxParticles; - collide = collide || 0; - - if (typeof collideWorldBounds == 'undefined') - { - collideWorldBounds = false; - } + if (typeof frames === 'undefined') { frames = 0; } + if (typeof quantity === 'undefined') { quantity = this.maxParticles; } + if (typeof collide === 'undefined') { collide = false; } + if (typeof collideWorldBounds === 'undefined') { collideWorldBounds = false; } var particle; var i = 0; var rndKey = keys; - var rndFrame = 0; + var rndFrame = frames; while (i < quantity) { - if (this.particleClass == null) + if (this.particleClass === null) { - if (typeof keys == 'object') + if (typeof keys === 'object') { rndKey = this.game.rnd.pick(keys); } - if (typeof frames == 'object') + if (typeof frames === 'object') { rndFrame = this.game.rnd.pick(frames); } @@ -37440,14 +42150,14 @@ Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames // particle = new this.particleClass(this.game); // } - if (collide > 0) + if (collide) { - particle.body.allowCollision.any = true; - particle.body.allowCollision.none = false; + particle.body.checkCollision.any = true; + particle.body.checkCollision.none = false; } else { - particle.body.allowCollision.none = true; + particle.body.checkCollision.none = true; } particle.body.collideWorldBounds = collideWorldBounds; @@ -37467,9 +42177,9 @@ Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames } /** - * Call this function to turn off all the particles and the emitter. - * @method Phaser.Particles.Arcade.Emitter#kill - */ +* Call this function to turn off all the particles and the emitter. +* @method Phaser.Particles.Arcade.Emitter#kill +*/ Phaser.Particles.Arcade.Emitter.prototype.kill = function () { this.on = false; @@ -37479,10 +42189,9 @@ Phaser.Particles.Arcade.Emitter.prototype.kill = function () { } /** - * Handy for bringing game objects "back to life". Just sets alive and exists back to true. - * In practice, this is most often called by Object.reset(). - * @method Phaser.Particles.Arcade.Emitter#revive - */ +* Handy for bringing game objects "back to life". Just sets alive and exists back to true. +* @method Phaser.Particles.Arcade.Emitter#revive +*/ Phaser.Particles.Arcade.Emitter.prototype.revive = function () { this.alive = true; @@ -37491,27 +42200,19 @@ Phaser.Particles.Arcade.Emitter.prototype.revive = function () { } /** - * Call this function to start emitting particles. - * @method Phaser.Particles.Arcade.Emitter#start - * @param {boolean} explode - Whether the particles should all burst out at once. - * @param {number} lifespan - How long each particle lives once emitted. 0 = forever. - * @param {number} frequency - Ignored if Explode is set to true. Frequency is how often to emit a particle in ms. - * @param {number} quantity - How many particles to launch. 0 = "all of the particles". - */ +* Call this function to start emitting particles. +* @method Phaser.Particles.Arcade.Emitter#start +* @param {boolean} [explode=true] - Whether the particles should all burst out at once. +* @param {number} [lifespan=0] - How long each particle lives once emitted. 0 = forever. +* @param {number} [frequency=250] - Ignored if Explode is set to true. Frequency is how often to emit a particle in ms. +* @param {number} [quantity=0] - How many particles to launch. 0 = "all of the particles". +*/ Phaser.Particles.Arcade.Emitter.prototype.start = function (explode, lifespan, frequency, quantity) { - if (typeof explode !== 'boolean') - { - explode = true; - } - - lifespan = lifespan || 0; - - // How many ms between emissions? - frequency = frequency || 250; - - // Total number of particles to emit - quantity = quantity || 0; + if (typeof explode === 'undefined') { explode = true; } + if (typeof lifespan === 'undefined') { lifespan = 0; } + if (typeof frequency === 'undefined') { frequency = 250; } + if (typeof quantity === 'undefined') { quantity = 0; } this.revive(); @@ -37537,9 +42238,9 @@ Phaser.Particles.Arcade.Emitter.prototype.start = function (explode, lifespan, f } /** - * This function can be used both internally and externally to emit the next particle. - * @method Phaser.Particles.Arcade.Emitter#emitParticle - */ +* This function can be used both internally and externally to emit the next particle. +* @method Phaser.Particles.Arcade.Emitter#emitParticle +*/ Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () { var particle = this.getFirstExists(false); @@ -37597,8 +42298,7 @@ Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () { particle.scale.setTo(scale, scale); } - particle.body.drag.x = this.particleDrag.x; - particle.body.drag.y = this.particleDrag.y; + particle.body.friction = this.particleFriction; particle.body.angularDrag = this.angularDrag; } @@ -37606,8 +42306,8 @@ Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () { /** * A more compact way of setting the width and height of the emitter. * @method Phaser.Particles.Arcade.Emitter#setSize -* @param {number} width - The desired width of the emitter (particles are spawned randomly within these dimensions). -* @param {number} height - The desired height of the emitter. +* @param {number} width - The desired width of the emitter (particles are spawned randomly within these dimensions). +* @param {number} height - The desired height of the emitter. */ Phaser.Particles.Arcade.Emitter.prototype.setSize = function (width, height) { @@ -37619,8 +42319,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setSize = function (width, height) { /** * A more compact way of setting the X velocity range of the emitter. * @method Phaser.Particles.Arcade.Emitter#setXSpeed -* @param {number} min - The minimum value for this range. -* @param {number} max - The maximum value for this range. +* @param {number} [min=0] - The minimum value for this range. +* @param {number} [max=0] - The maximum value for this range. */ Phaser.Particles.Arcade.Emitter.prototype.setXSpeed = function (min, max) { @@ -37635,8 +42335,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setXSpeed = function (min, max) { /** * A more compact way of setting the Y velocity range of the emitter. * @method Phaser.Particles.Arcade.Emitter#setYSpeed -* @param {number} min - The minimum value for this range. -* @param {number} max - The maximum value for this range. +* @param {number} [min=0] - The minimum value for this range. +* @param {number} [max=0] - The maximum value for this range. */ Phaser.Particles.Arcade.Emitter.prototype.setYSpeed = function (min, max) { @@ -37651,8 +42351,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setYSpeed = function (min, max) { /** * A more compact way of setting the angular velocity constraints of the emitter. * @method Phaser.Particles.Arcade.Emitter#setRotation -* @param {number} min - The minimum value for this range. -* @param {number} max - The maximum value for this range. +* @param {number} [min=0] - The minimum value for this range. +* @param {number} [max=0] - The maximum value for this range. */ Phaser.Particles.Arcade.Emitter.prototype.setRotation = function (min, max) { @@ -37665,14 +42365,17 @@ Phaser.Particles.Arcade.Emitter.prototype.setRotation = function (min, max) { } /** -* Change the emitter's midpoint to match the midpoint of a Object. +* Change the emitters center to match the center of any object with a `center` property, such as a Sprite. * @method Phaser.Particles.Arcade.Emitter#at -* @param {object} object - The Object that you want to sync up with. +* @param {object|Phaser.Sprite} object - The object that you wish to match the center with. */ Phaser.Particles.Arcade.Emitter.prototype.at = function (object) { - this.emitX = object.center.x; - this.emitY = object.center.y; + if (object.center) + { + this.emitX = object.center.x; + this.emitY = object.center.y; + } } @@ -37796,35 +42499,45 @@ Object.defineProperty(Phaser.Particles.Arcade.Emitter.prototype, "bottom", { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** -* Create a new `Tile` object. Tiles live inside of Tilesets and are rendered via TilemapLayers. +* Create a new `Tile` object. * * @class Phaser.Tile -* @classdesc A Tile is a single representation of a tile within a Tilemap. +* @classdesc A Tile is a representation of a single tile within the Tilemap. * @constructor -* @param {Phaser.Tileset} tileset - The tileset this tile belongs to. +* @param {object} layer - The layer in the Tilemap data that this tile belongs to. * @param {number} index - The index of this tile type in the core map data. * @param {number} x - The x coordinate of this tile. * @param {number} y - The y coordinate of this tile. * @param {number} width - Width of the tile. * @param {number} height - Height of the tile. */ -Phaser.Tile = function (tileset, index, x, y, width, height) { +Phaser.Tile = function (layer, index, x, y, width, height) { /** - * @property {Phaser.Tileset} tileset - The tileset this tile belongs to. + * @property {object} layer - The layer in the Tilemap data that this tile belongs to. */ - this.tileset = tileset; - + this.layer = layer; + /** - * @property {number} index - The index of this tile within the tileset. + * @property {number} index - The index of this tile within the map data corresponding to the tileset. */ this.index = index; + /** + * @property {number} x - The x map coordinate of this tile. + */ + this.x = x; + + /** + * @property {number} y - The y map coordinate of this tile. + */ + this.y = y; + /** * @property {number} width - The width of the tile in pixels. */ @@ -37836,22 +42549,44 @@ Phaser.Tile = function (tileset, index, x, y, width, height) { this.height = height; /** - * @property {number} x - The top-left corner of the tile within the tileset. + * @property {number} alpha - The alpha value at which this tile is drawn to the canvas. */ - this.x = x; - - /** - * @property {number} y - The top-left corner of the tile within the tileset. - */ - this.y = y; - - // Any extra meta data info we need here + this.alpha = 1; /** - * @property {number} mass - The virtual mass of the tile. - * @default + * @property {object} properties - Tile specific properties. */ - this.mass = 1.0; + this.properties = {}; + + /** + * @property {boolean} scanned - Has this tile been walked / turned into a poly? + */ + this.scanned = false; + + /** + * @property {boolean} faceTop - Is the top of this tile an interesting edge? + */ + this.faceTop = false; + + /** + * @property {boolean} faceBottom - Is the bottom of this tile an interesting edge? + */ + this.faceBottom = false; + + /** + * @property {boolean} faceLeft - Is the left of this tile an interesting edge? + */ + this.faceLeft = false; + + /** + * @property {boolean} faceRight - Is the right of this tile an interesting edge? + */ + this.faceRight = false; + + /** + * @property {boolean} collides - Does this tile collide at all? + */ + this.collides = false; /** * @property {boolean} collideNone - Indicating this Tile doesn't collide at all. @@ -37884,38 +42619,27 @@ Phaser.Tile = function (tileset, index, x, y, width, height) { this.collideDown = false; /** - * @property {boolean} separateX - Enable separation at x-axis. + * @property {function} callback - Tile collision callback. * @default */ - this.separateX = true; + this.callback = null; /** - * @property {boolean} separateY - Enable separation at y-axis. + * @property {object} callbackContext - The context in which the collision callback will be called. * @default */ - this.separateY = true; - - /** - * @property {boolean} collisionCallback - Tilemap collision callback. - * @default - */ - this.collisionCallback = null; - - /** - * @property {boolean} collisionCallback - Tilemap collision callback. - * @default - */ - this.collisionCallbackContext = this; + this.callbackContext = this; }; Phaser.Tile.prototype = { /** - * Set callback to be called when this tilemap collides. + * Set a callback to be called when this tile is hit by an object. + * The callback must true true for collision processing to take place. * * @method Phaser.Tile#setCollisionCallback - * @param {Function} callback - Callback function. + * @param {function} callback - Callback function. * @param {object} context - Callback will be called with this context. */ setCollisionCallback: function (callback, context) { @@ -37931,7 +42655,9 @@ Phaser.Tile.prototype = { */ destroy: function () { - this.tileset = null; + this.collisionCallback = null; + this.collisionCallbackContext = null; + this.properties = null; }, @@ -37973,19 +42699,55 @@ Phaser.Tile.prototype = { this.collideUp = false; this.collideDown = false; + }, + + /** + * Copies the tile data and properties from the given tile to this tile. + * @method Phaser.Tile#copy + * @param {Phaser.Tile} tile - The tile to copy from. + */ + copy: function (tile) { + + this.index = tile.index; + this.alpha = tile.alpha; + this.properties = tile.properties; + this.collides = tile.collides; + this.collideNone = tile.collideNone; + this.collideUp = tile.collideUp; + this.collideDown = tile.collideDown; + this.collideLeft = tile.collideLeft; + this.collideRight = tile.collideRight; + this.collisionCallback = tile.collisionCallback; + this.collisionCallbackContext = tile.collisionCallbackContext; + } }; +Phaser.Tile.prototype.constructor = Phaser.Tile; + /** -* @name Phaser.Tile#bottom -* @property {number} bottom - The sum of the y and height properties. +* @name Phaser.Tile#canCollide +* @property {boolean} canCollide - True if this tile can collide or has a collision callback. * @readonly */ -Object.defineProperty(Phaser.Tile.prototype, "bottom", { +Object.defineProperty(Phaser.Tile.prototype, "canCollide", { get: function () { - return this.y + this.height; + return (this.collides || this.collisionCallback || this.layer.callbacks[this.index]); + } + +}); + +/** +* @name Phaser.Tile#left +* @property {number} left - The x value. +* @readonly +*/ +Object.defineProperty(Phaser.Tile.prototype, "left", { + + get: function () { + return this.x; } }); @@ -38003,9 +42765,35 @@ Object.defineProperty(Phaser.Tile.prototype, "right", { }); +/** +* @name Phaser.Tile#top +* @property {number} top - The y value. +* @readonly +*/ +Object.defineProperty(Phaser.Tile.prototype, "top", { + + get: function () { + return this.y; + } + +}); + +/** +* @name Phaser.Tile#bottom +* @property {number} bottom - The sum of the y and height properties. +* @readonly +*/ +Object.defineProperty(Phaser.Tile.prototype, "bottom", { + + get: function () { + return this.y + this.height; + } + +}); + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -38026,22 +42814,52 @@ Phaser.Tilemap = function (game, key) { this.game = game; /** - * @property {array} layers - An array of Tilemap layers. + * @property {string} key - The key of this map data in the Phaser.Cache. */ - this.layers = null; + this.key = key; - if (typeof key === 'string') - { - this.key = key; + var data = Phaser.TilemapParser.parse(this.game, key); - this.layers = game.cache.getTilemapData(key).layers; - this.calculateIndexes(); - } - else + if (data === null) { - this.layers = []; + return; } + this.width = data.width; + this.height = data.height; + this.tileWidth = data.tileWidth; + this.tileHeight = data.tileHeight; + this.orientation = data.orientation; + this.version = data.version; + this.properties = data.properties; + this.widthInPixels = data.widthInPixels; + this.heightInPixels = data.heightInPixels; + + /** + * @property {array} layers - An array of Tilemap layer data. + */ + this.layers = data.layers; + + /** + * @property {array} tilesets - An array of Tilesets. + */ + this.tilesets = data.tilesets; + + /** + * @property {array} tiles - The super array of Tiles. + */ + this.tiles = data.tiles; + + /** + * @property {array} objects - An array of Tiled Object Layers. + */ + this.objects = data.objects; + + /** + * @property {array} images - An array of Tiled Image Layers. + */ + this.images = data.images; + /** * @property {number} currentLayer - The current layer. */ @@ -38050,14 +42868,8 @@ Phaser.Tilemap = function (game, key) { /** * @property {array} debugMap - Map data used for debug values only. */ - this.debugMap = []; - /** - * @property {boolean} dirty - Internal rendering related flag. - */ - this.dirty = false; - /** * @property {array} _results - Internal var. * @private @@ -38125,36 +42937,500 @@ Phaser.Tilemap.prototype = { tileSpacing: 0, format: Phaser.Tilemap.CSV, data: data, - indexes: [] + indexes: [], + dirty: true }); this.currentLayer = this.layers.length - 1; - this.dirty = true; + }, + + /** + * Adds an image to the map to be used as a tileset. A single map may use multiple tilesets. + * Note that the tileset name can be found in the JSON file exported from Tiled, or in the Tiled editor. + * + * @method Phaser.Tilemap#addTilesetImage + * @param {string} tileset - The name of the tileset as specified in the map data. + * @param {string} [key] - The key of the Phaser.Cache image used for this tileset. If not specified it will look for an image with a key matching the tileset parameter. + */ + addTilesetImage: function (tileset, key) { + + if (typeof key === 'undefined') + { + if (typeof tileset === 'string') + { + key = tileset; + } + else + { + return false; + } + } + + if (typeof tileset === 'string') + { + tileset = this.getTilesetIndex(tileset); + } + + if (this.tilesets[tileset]) + { + this.tilesets[tileset].image = this.game.cache.getImage(key); + + return true; + } + + return false; + + }, + + // Region? Remove tile from map data? + createFromTiles: function (layer, tileIndex, key, frame, group) { + + if (typeof group === 'undefined') { group = this.game.world; } }, /** - * Internal function that calculates the tile indexes for the map data. + * Creates a Sprite for every object matching the given gid in the map data. You can optionally specify the group that the Sprite will be created in. If none is + * given it will be created in the World. All properties from the map data objectgroup are copied across to the Sprite, so you can use this as an easy way to + * configure Sprite properties from within the map editor. For example giving an object a property if alpha: 0.5 in the map editor will duplicate that when the + * Sprite is created. You could also give it a value like: body.velocity.x: 100 to set it moving automatically. * - * @method Phaser.Tilemap#calculateIndexes + * @method Phaser.Tileset#createFromObjects + * @param {string} name - The name of the Object Group to create Sprites from. + * @param {number} gid - The layer array index value, or if a string is given the layer name, within the map data that this TilemapLayer represents. + * @param {string} key - The Game.cache key of the image that this Sprite will use. + * @param {number|string} [frame] - If the Sprite image contains multiple frames you can specify which one to use here. + * @param {boolean} [exists=true] - The default exists state of the Sprite. + * @param {boolean} [autoCull=true] - The default autoCull state of the Sprite. Sprites that are autoCulled are culled from the camera if out of its range. + * @param {Phaser.Group} [group] - Optional Group to add the Sprite to. If not specified it will be added to the World group. */ - calculateIndexes: function () { + createFromObjects: function (name, gid, key, frame, exists, autoCull, group) { - for (var layer = 0; layer < this.layers.length; layer++) + if (typeof exists === 'undefined') { exists = true; } + if (typeof autoCull === 'undefined') { autoCull = true; } + if (typeof group === 'undefined') { group = this.game.world; } + + if (!this.objects[name]) { - this.layers[layer].indexes = []; + console.warn('Tilemap.createFromObjects: Invalid objectgroup name given: ' + name); + return; + } - for (var y = 0; y < this.layers[layer].height ; y++) + var sprite; + + for (var i = 0, len = this.objects[name].length; i < len; i++) + { + if (this.objects[name][i].gid === gid) { - for (var x = 0; x < this.layers[layer].width; x++) - { - var idx = this.layers[layer].data[y][x]; + sprite = group.create(this.objects[name][i].x, this.objects[name][i].y, key, frame, exists); - if (this.layers[layer].indexes.indexOf(idx) === -1) + sprite.anchor.setTo(0, 1); + sprite.name = this.objects[name][i].name; + sprite.visible = this.objects[name][i].visible; + sprite.autoCull = autoCull; + + for (property in this.objects[name][i].properties) + { + group.set(sprite, property, this.objects[name][i].properties[property], false, false, 0); + } + } + } + + }, + + /** + * Creates a new TilemapLayer object. By default TilemapLayers are fixed to the camera. + * + * @method Phaser.Tileset#createLayer + * @param {number|string} layer - The layer array index value, or if a string is given the layer name, within the map data that this TilemapLayer represents. + * @param {number} [width] - The rendered width of the layer, should never be wider than Game.width. If not given it will be set to Game.width. + * @param {number} [height] - The rendered height of the layer, should never be wider than Game.height. If not given it will be set to Game.height. + * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. + * @return {Phaser.TilemapLayer} The TilemapLayer object. This is an extension of Phaser.Sprite and can be moved around the display list accordingly. + */ + createLayer: function (layer, width, height, group) { + + // Add Buffer support for the left of the canvas + + if (typeof width === 'undefined') { width = this.game.width; } + if (typeof height === 'undefined') { height = this.game.height; } + if (typeof group === 'undefined') { group = this.game.world; } + + var index = layer; + + if (typeof layer === 'string') + { + index = this.getLayerIndex(layer); + } + + if (index === null || index > this.layers.length) + { + console.warn('Tilemap.createLayer: Invalid layer ID given: ' + index); + return; + } + + return group.add(new Phaser.TilemapLayer(this.game, this, index, width, height)); + + }, + + /** + * Gets the layer index based on the layers name. + * + * @method Phaser.Tileset#getIndex + * @protected + * @param {array} location - The local array to search. + * @param {string} name - The name of the array element to get. + * @return {number} The index of the element in the array, or null if not found. + */ + getIndex: function (location, name) { + + for (var i = 0; i < location.length; i++) + { + if (location[i].name === name) + { + return i; + } + } + + return null; + + }, + + /** + * Gets the layer index based on its name. + * + * @method Phaser.Tileset#getLayerIndex + * @param {string} name - The name of the layer to get. + * @return {number} The index of the layer in this tilemap, or null if not found. + */ + getLayerIndex: function (name) { + + return this.getIndex(this.layers, name); + + }, + + /** + * Gets the tileset index based on its name. + * + * @method Phaser.Tileset#getTilesetIndex + * @param {string} name - The name of the tileset to get. + * @return {number} The index of the tileset in this tilemap, or null if not found. + */ + getTilesetIndex: function (name) { + + return this.getIndex(this.tilesets, name); + + }, + + /** + * Gets the image index based on its name. + * + * @method Phaser.Tileset#getImageIndex + * @param {string} name - The name of the image to get. + * @return {number} The index of the image in this tilemap, or null if not found. + */ + getImageIndex: function (name) { + + return this.getIndex(this.images, name); + + }, + + /** + * Gets the object index based on its name. + * + * @method Phaser.Tileset#getObjectIndex + * @param {string} name - The name of the object to get. + * @return {number} The index of the object in this tilemap, or null if not found. + */ + getObjectIndex: function (name) { + + return this.getIndex(this.objects, name); + + }, + + /** + * Sets a global collision callback for the given tile index within the layer. This will affect all tiles on this layer that have the same index. + * If a callback is already set for the tile index it will be replaced. Set the callback to null to remove it. + * If you want to set a callback for a tile at a specific location on the map then see setTileLocationCallback. + * + * @method Phaser.Tileset#setTileIndexCallback + * @param {number|array} indexes - Either a single tile index, or an array of tile indexes to have a collision callback set for. + * @param {function} callback - The callback that will be invoked when the tile is collided with. + * @param {object} callbackContext - The context under which the callback is called. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer. + */ + setTileIndexCallback: function (indexes, callback, callbackContext, layer) { + + layer = this.getLayer(layer); + + if (typeof indexes === 'number') + { + // This may seem a bit wasteful, because it will cause empty array elements to be created, but the look-up cost is much + // less than having to iterate through the callbacks array hunting down tile indexes each time, so I'll take the small memory hit. + this.layers[layer].callbacks[indexes] = { callback: callback, callbackContext: callbackContext }; + } + else + { + for (var i = 0, len = indexes.length; i < len; i++) + { + this.layers[layer].callbacks[indexes[i]] = { callback: callback, callbackContext: callbackContext }; + } + } + + }, + + /** + * Sets a global collision callback for the given tile index within the layer. This will affect all tiles on this layer that have the same index. + * If a callback is already set for the tile index it will be replaced. Set the callback to null to remove it. + * If you want to set a callback for a tile at a specific location on the map then see setTileLocationCallback. + * + * @method Phaser.Tileset#setTileLocationCallback + * @param {number} x - X position of the top left of the area to copy (given in tiles, not pixels) + * @param {number} y - Y position of the top left of the area to copy (given in tiles, not pixels) + * @param {number} width - The width of the area to copy (given in tiles, not pixels) + * @param {number} height - The height of the area to copy (given in tiles, not pixels) + * @param {function} callback - The callback that will be invoked when the tile is collided with. + * @param {object} callbackContext - The context under which the callback is called. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer. + */ + setTileLocationCallback: function (x, y, width, height, callback, callbackContext, layer) { + + layer = this.getLayer(layer); + + this.copy(x, y, width, height, layer); + + if (this._results.length < 2) + { + return; + } + + for (var i = 1; i < this._results.length; i++) + { + this._results[i].setCollisionCallback(callback, callbackContext); + } + + }, + + /** + * Sets collision the given tile or tiles. You can pass in either a single numeric index or an array of indexes: [ 2, 3, 15, 20]. + * The `collides` parameter controls if collision will be enabled (true) or disabled (false). + * + * @method Phaser.Tileset#setCollision + * @param {number|array} indexes - Either a single tile index, or an array of tile IDs to be checked for collision. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer. + */ + setCollision: function (indexes, collides, layer) { + + if (typeof collides === 'undefined') { collides = true; } + + layer = this.getLayer(layer); + + if (typeof indexes === 'number') + { + return this.setCollisionByIndex(indexes, collides, layer, true); + } + else + { + // Collide all of the IDs given in the indexes array + for (var i = 0, len = indexes.length; i < len; i++) + { + this.setCollisionByIndex(indexes[i], collides, layer, false); + } + + // Now re-calculate interesting faces + this.calculateFaces(layer); + } + + }, + + /** + * Sets collision on a range of tiles where the tile IDs increment sequentially. + * Calling this with a start value of 10 and a stop value of 14 would set collision for tiles 10, 11, 12, 13 and 14. + * The `collides` parameter controls if collision will be enabled (true) or disabled (false). + * + * @method Phaser.Tileset#setCollisionBetween + * @param {number} start - The first index of the tile to be set for collision. + * @param {number} stop - The last index of the tile to be set for collision. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer. + */ + setCollisionBetween: function (start, stop, collides, layer) { + + if (typeof collides === 'undefined') { collides = true; } + + layer = this.getLayer(layer); + + if (start > stop) + { + return; + } + + for (var index = start; index <= stop; index++) + { + this.setCollisionByIndex(index, collides, layer, false); + } + + // Now re-calculate interesting faces + this.calculateFaces(layer); + + }, + + /** + * Sets collision on all tiles in the given layer, except for the IDs of those in the given array. + * The `collides` parameter controls if collision will be enabled (true) or disabled (false). + * + * @method Phaser.Tileset#setCollisionByExclusion + * @param {array} indexes - An array of the tile IDs to not be counted for collision. + * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer. + */ + setCollisionByExclusion: function (indexes, collides, layer) { + + if (typeof collides === 'undefined') { collides = true; } + + layer = this.getLayer(layer); + + // Collide everything, except the IDs given in the indexes array + for (var i = 0, len = this.tiles.length; i < len; i++) + { + if (indexes.indexOf(i) === -1) + { + this.setCollisionByIndex(i, collides, layer, false); + } + } + + // Now re-calculate interesting faces + this.calculateFaces(layer); + + }, + + /** + * Sets collision values on a tile in the set. + * You shouldn't usually call this method directly, instead use setCollision, setCollisionBetween or setCollisionByExclusion. + * + * @method Phaser.Tileset#setCollisionByIndex + * @protected + * @param {number} index - The index of the tile on the layer. + * @param {boolean} [collides=true] - If true it will enable collision on the tile. If false it will clear collision values from the tile. + * @param {number} [layer] - The layer to operate on. If not given will default to this.currentLayer. + * @param {boolean} [recalculate=true] - Recalculates the tile faces after the update. + */ + setCollisionByIndex: function (index, collides, layer, recalculate) { + + if (typeof collides === 'undefined') { collides = true; } + if (typeof layer === 'undefined') { layer = this.currentLayer; } + if (typeof recalculate === 'undefined') { recalculate = true; } + + for (var y = 0; y < this.layers[layer].height ; y++) + { + for (var x = 0; x < this.layers[layer].width; x++) + { + var tile = this.layers[layer].data[y][x]; + + if (tile && tile.index === index) + { + tile.collides = collides; + tile.faceTop = collides; + tile.faceBottom = collides; + tile.faceLeft = collides; + tile.faceRight = collides; + } + } + } + + if (recalculate) + { + // Now re-calculate interesting faces + this.calculateFaces(layer); + } + + return layer; + + }, + + /** + * Gets the TilemapLayer index as used in the setCollision calls. + * + * @method Phaser.Tileset#getLayer + * @protected + * @param {number|string|Phaser.TilemapLayer} layer - The layer to operate on. If not given will default to this.currentLayer. + * @return {number} The TilemapLayer index. + */ + getLayer: function (layer) { + + if (typeof layer === 'undefined') + { + layer = this.currentLayer; + } + // else if (typeof layer === 'number') + // { + // layer = layer; + // } + else if (typeof layer === 'string') + { + layer = this.getLayerIndex(layer); + } + else if (layer instanceof Phaser.TilemapLayer) + { + layer = layer.index; + } + + return layer; + + }, + + /** + * Internal function. + * + * @method Phaser.Tileset#calculateFaces + * @protected + * @param {number} layer - The index of the TilemapLayer to operate on. + */ + calculateFaces: function (layer) { + + var above = null; + var below = null; + var left = null; + var right = null; + + for (var y = 0, h = this.layers[layer].height; y < h; y++) + { + for (var x = 0, w = this.layers[layer].width; x < w; x++) + { + var tile = this.layers[layer].data[y][x]; + + if (tile) + { + above = this.getTileAbove(layer, x, y); + below = this.getTileBelow(layer, x, y); + left = this.getTileLeft(layer, x, y); + right = this.getTileRight(layer, x, y); + + if (above && above.collides) { - this.layers[layer].indexes.push(idx); + // There is a tile above this one that also collides, so the top of this tile is no longer interesting + tile.faceTop = false; + } + + if (below && below.collides) + { + // There is a tile below this one that also collides, so the bottom of this tile is no longer interesting + tile.faceBottom = false; + } + + if (left && left.collides) + { + // There is a tile left this one that also collides, so the left of this tile is no longer interesting + tile.faceLeft = false; + } + + if (right && right.collides) + { + // There is a tile right this one that also collides, so the right of this tile is no longer interesting + tile.faceRight = false; } } } @@ -38162,14 +43438,96 @@ Phaser.Tilemap.prototype = { }, + /** + * Gets the tile above the tile coordinates given. + * Mostly used as an internal function by calculateFaces. + * + * @method Phaser.Tileset#getTileAbove + * @param {number} layer - The local layer index to get the tile from. Can be determined by Tilemap.getLayer(). + * @param {number} x - The x coordinate to get the tile from. In tiles, not pixels. + * @param {number} y - The y coordinate to get the tile from. In tiles, not pixels. + */ + getTileAbove: function (layer, x, y) { + + if (y > 0) + { + return this.layers[layer].data[y - 1][x]; + } + + return null; + + }, + + /** + * Gets the tile below the tile coordinates given. + * Mostly used as an internal function by calculateFaces. + * + * @method Phaser.Tileset#getTileBelow + * @param {number} layer - The local layer index to get the tile from. Can be determined by Tilemap.getLayer(). + * @param {number} x - The x coordinate to get the tile from. In tiles, not pixels. + * @param {number} y - The y coordinate to get the tile from. In tiles, not pixels. + */ + getTileBelow: function (layer, x, y) { + + if (y < this.layers[layer].height - 1) + { + return this.layers[layer].data[y + 1][x]; + } + + return null; + + }, + + /** + * Gets the tile to the left of the tile coordinates given. + * Mostly used as an internal function by calculateFaces. + * + * @method Phaser.Tileset#getTileLeft + * @param {number} layer - The local layer index to get the tile from. Can be determined by Tilemap.getLayer(). + * @param {number} x - The x coordinate to get the tile from. In tiles, not pixels. + * @param {number} y - The y coordinate to get the tile from. In tiles, not pixels. + */ + getTileLeft: function (layer, x, y) { + + if (x > 0) + { + return this.layers[layer].data[y][x - 1]; + } + + return null; + + }, + + /** + * Gets the tile to the right of the tile coordinates given. + * Mostly used as an internal function by calculateFaces. + * + * @method Phaser.Tileset#getTileRight + * @param {number} layer - The local layer index to get the tile from. Can be determined by Tilemap.getLayer(). + * @param {number} x - The x coordinate to get the tile from. In tiles, not pixels. + * @param {number} y - The y coordinate to get the tile from. In tiles, not pixels. + */ + getTileRight: function (layer, x, y) { + + if (x < this.layers[layer].width - 1) + { + return this.layers[layer].data[y][x + 1]; + } + + return null; + + }, + /** * Sets the current layer to the given index. * * @method Phaser.Tilemap#setLayer - * @param {number} layer - Sets the current layer to the given index. + * @param {number|string|Phaser.TilemapLayer} layer - The layer to set as current. */ setLayer: function (layer) { + layer = this.getLayer(layer); + if (this.layers[layer]) { this.currentLayer = layer; @@ -38179,36 +43537,68 @@ Phaser.Tilemap.prototype = { /** * Puts a tile of the given index value at the coordinate specified. + * * @method Phaser.Tilemap#putTile - * @param {number} index - The index of this tile to set. + * @param {Phaser.Tile|number} tile - The index of this tile to set or a Phaser.Tile object. * @param {number} x - X position to place the tile (given in tile units, not pixels) * @param {number} y - Y position to place the tile (given in tile units, not pixels) - * @param {number} [layer] - The Tilemap Layer to operate on. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to modify. */ - putTile: function (index, x, y, layer) { + putTile: function (tile, x, y, layer) { - if (typeof layer === "undefined") { layer = this.currentLayer; } + layer = this.getLayer(layer); if (x >= 0 && x < this.layers[layer].width && y >= 0 && y < this.layers[layer].height) { - this.layers[layer].data[y][x] = index; + if (tile instanceof Phaser.Tile) + { + this.layers[layer].data[y][x].copy(tile); + } + else + { + this.layers[layer].data[y][x].index = tile; + } + + this.layers[layer].dirty = true; + this.calculateFaces(layer); } - this.dirty = true; + }, + + /** + * Puts a tile into the Tilemap layer. The coordinates are given in pixel values. + * + * @method Phaser.Tilemap#putTileWorldXY + * @param {Phaser.Tile|number} tile - The index of this tile to set or a Phaser.Tile object. + * @param {number} x - X position to insert the tile (given in pixels) + * @param {number} y - Y position to insert the tile (given in pixels) + * @param {number} tileWidth - The width of the tile in pixels. + * @param {number} tileHeight - The height of the tile in pixels. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to modify. + */ + putTileWorldXY: function (tile, x, y, tileWidth, tileHeight, layer) { + + layer = this.getLayer(layer); + + x = this.game.math.snapToFloor(x, tileWidth) / tileWidth; + y = this.game.math.snapToFloor(y, tileHeight) / tileHeight; + + this.putTile(tile, x, y, layer); }, /** * Gets a tile from the Tilemap Layer. The coordinates are given in tile values. + * * @method Phaser.Tilemap#getTile * @param {number} x - X position to get the tile from (given in tile units, not pixels) * @param {number} y - Y position to get the tile from (given in tile units, not pixels) - * @param {number} [layer] - The Tilemap Layer to operate on. - * @return {number} The index of the tile at the given coordinates. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to get the tile from. + * @return {Phaser.Tile} The tile at the given coordinates. */ getTile: function (x, y, layer) { - if (typeof layer === "undefined") { layer = this.currentLayer; } + layer = this.getLayer(layer); if (x >= 0 && x < this.layers[layer].width && y >= 0 && y < this.layers[layer].height) { @@ -38219,65 +43609,38 @@ Phaser.Tilemap.prototype = { /** * Gets a tile from the Tilemap layer. The coordinates are given in pixel values. + * * @method Phaser.Tilemap#getTileWorldXY * @param {number} x - X position to get the tile from (given in pixels) * @param {number} y - Y position to get the tile from (given in pixels) - * @param {number} [layer] - The Tilemap Layer to operate on. - * @return {number} The index of the tile at the given coordinates. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to get the tile from. + * @return {Phaser.Tile} The tile at the given coordinates. */ getTileWorldXY: function (x, y, tileWidth, tileHeight, layer) { - if (typeof layer === "undefined") { layer = this.currentLayer; } + layer = this.getLayer(layer); x = this.game.math.snapToFloor(x, tileWidth) / tileWidth; y = this.game.math.snapToFloor(y, tileHeight) / tileHeight; - if (x >= 0 && x < this.layers[layer].width && y >= 0 && y < this.layers[layer].height) - { - return this.layers[layer].data[y][x]; - } - - }, - - /** - * Puts a tile into the Tilemap layer. The coordinates are given in pixel values. - * @method Phaser.Tilemap#putTileWorldXY - * @param {number} index - The index of the tile to put into the layer. - * @param {number} x - X position to insert the tile (given in pixels) - * @param {number} y - Y position to insert the tile (given in pixels) - * @param {number} tileWidth - The width of the tile in pixels. - * @param {number} tileHeight - The height of the tile in pixels. - * @param {number} [layer] - The Tilemap Layer to operate on. - */ - putTileWorldXY: function (index, x, y, tileWidth, tileHeight, layer) { - - if (typeof layer === "undefined") { layer = this.currentLayer; } - - x = this.game.math.snapToFloor(x, tileWidth) / tileWidth; - y = this.game.math.snapToFloor(y, tileHeight) / tileHeight; - - if (x >= 0 && x < this.layers[layer].width && y >= 0 && y < this.layers[layer].height) - { - this.layers[layer].data[y][x] = index; - } - - this.dirty = true; + return this.getTile(x, y, layer); }, /** * Copies all of the tiles in the given rectangular block into the tilemap data buffer. + * * @method Phaser.Tilemap#copy * @param {number} x - X position of the top left of the area to copy (given in tiles, not pixels) * @param {number} y - Y position of the top left of the area to copy (given in tiles, not pixels) * @param {number} width - The width of the area to copy (given in tiles, not pixels) * @param {number} height - The height of the area to copy (given in tiles, not pixels) - * @param {number} [layer] - The Tilemap Layer to operate on. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to copy the tiles from. * @return {array} An array of the tiles that were copied. */ copy: function (x, y, width, height, layer) { - if (typeof layer === "undefined") { layer = this.currentLayer; } + layer = this.getLayer(layer); if (!this.layers[layer]) { @@ -38318,7 +43681,7 @@ Phaser.Tilemap.prototype = { { for (var tx = x; tx < x + width; tx++) { - this._results.push({ x: tx, y: ty, index: this.layers[layer].data[ty][tx] }); + this._results.push(this.layers[layer].data[ty][tx]); } } @@ -38328,17 +43691,19 @@ Phaser.Tilemap.prototype = { /** * Pastes a previously copied block of tile data into the given x/y coordinates. Data should have been prepared with Tilemap.copy. + * * @method Phaser.Tilemap#paste * @param {number} x - X position of the top left of the area to paste to (given in tiles, not pixels) * @param {number} y - Y position of the top left of the area to paste to (given in tiles, not pixels) * @param {array} tileblock - The block of tiles to paste. - * @param {number} layer - The Tilemap Layer to operate on. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to paste the tiles into. */ paste: function (x, y, tileblock, layer) { if (typeof x === "undefined") { x = 0; } if (typeof y === "undefined") { y = 0; } - if (typeof layer === "undefined") { layer = this.currentLayer; } + + layer = this.getLayer(layer); if (!tileblock || tileblock.length < 2) { @@ -38351,15 +43716,17 @@ Phaser.Tilemap.prototype = { for (var i = 1; i < tileblock.length; i++) { - this.layers[layer].data[ diffY + tileblock[i].y ][ diffX + tileblock[i].x ] = tileblock[i].index; + this.layers[layer].data[ diffY + tileblock[i].y ][ diffX + tileblock[i].x ].copy(tileblock[i]); } - this.dirty = true; + this.layers[layer].dirty = true; + this.calculateFaces(layer); }, /** - * Swap tiles with 2 kinds of indexes. + * Scans the given area for tiles with an index matching tileA and swaps them with tileB. + * * @method Phaser.Tilemap#swapTile * @param {number} tileA - First tile index. * @param {number} tileB - Second tile index. @@ -38367,9 +43734,12 @@ Phaser.Tilemap.prototype = { * @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels. * @param {number} width - The width in tiles of the area to operate on. * @param {number} height - The height in tiles of the area to operate on. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. */ swap: function (tileA, tileB, x, y, width, height, layer) { + layer = this.getLayer(layer); + this.copy(x, y, width, height, layer); if (this._results.length < 2) @@ -38382,13 +43752,15 @@ Phaser.Tilemap.prototype = { this._results.forEach(this.swapHandler, this); - this.paste(x, y, this._results); + this.paste(x, y, this._results, layer); }, /** * Internal function that handles the swapping of tiles. + * * @method Phaser.Tilemap#swapHandler + * @private * @param {number} value * @param {number} index */ @@ -38406,7 +43778,8 @@ Phaser.Tilemap.prototype = { }, /** - * For each tile in the given area (defined by x/y and width/height) run the given callback. + * For each tile in the given area defined by x/y and width/height run the given callback. + * * @method Phaser.Tilemap#forEach * @param {number} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter. * @param {number} context - The context under which the callback should be run. @@ -38414,10 +43787,12 @@ Phaser.Tilemap.prototype = { * @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels. * @param {number} width - The width in tiles of the area to operate on. * @param {number} height - The height in tiles of the area to operate on. - * @param {number} [layer] - The Tilemap Layer to operate on. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. */ forEach: function (callback, context, x, y, width, height, layer) { + layer = this.getLayer(layer); + this.copy(x, y, width, height, layer); if (this._results.length < 2) @@ -38427,22 +43802,25 @@ Phaser.Tilemap.prototype = { this._results.forEach(callback, context); - this.paste(x, y, this._results); + this.paste(x, y, this._results, layer); }, /** - * Replaces one type of tile with another in the given area (defined by x/y and width/height). + * Scans the given area for tiles with an index matching `source` and updates their index to match `dest`. + * * @method Phaser.Tilemap#replace - * @param {number} tileA - First tile index. - * @param {number} tileB - Second tile index. + * @param {number} source - The tile index value to scan for. + * @param {number} dest - The tile index value to replace found tiles with. * @param {number} x - X position of the top left of the area to operate one, given in tiles, not pixels. * @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels. * @param {number} width - The width in tiles of the area to operate on. * @param {number} height - The height in tiles of the area to operate on. - * @param {number} [layer] - The Tilemap Layer to operate on. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. */ - replace: function (tileA, tileB, x, y, width, height, layer) { + replace: function (source, dest, x, y, width, height, layer) { + + layer = this.getLayer(layer); this.copy(x, y, width, height, layer); @@ -38453,30 +43831,29 @@ Phaser.Tilemap.prototype = { for (var i = 1; i < this._results.length; i++) { - if (this._results[i].index === tileA) + if (this._results[i].index === source) { - this._results[i].index = tileB; + this._results[i].index = dest; } } - this.paste(x, y, this._results); + this.paste(x, y, this._results, layer); }, /** * Randomises a set of tiles in a given area. + * * @method Phaser.Tilemap#random - * @param {number} tileA - First tile index. - * @param {number} tileB - Second tile index. * @param {number} x - X position of the top left of the area to operate one, given in tiles, not pixels. * @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels. * @param {number} width - The width in tiles of the area to operate on. * @param {number} height - The height in tiles of the area to operate on. - * @param {number} [layer] - The Tilemap Layer to operate on. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. */ random: function (x, y, width, height, layer) { - if (typeof layer === "undefined") { layer = this.currentLayer; } + layer = this.getLayer(layer); this.copy(x, y, width, height, layer); @@ -38489,11 +43866,14 @@ Phaser.Tilemap.prototype = { for (var t = 1; t < this._results.length; t++) { - var idx = this._results[t].index; - - if (indexes.indexOf(idx) === -1) + if (this._results[t].index) { - indexes.push(idx); + var idx = this._results[t].index; + + if (indexes.indexOf(idx) === -1) + { + indexes.push(idx); + } } } @@ -38502,24 +43882,23 @@ Phaser.Tilemap.prototype = { this._results[i].index = this.game.rnd.pick(indexes); } - this.paste(x, y, this._results); + this.paste(x, y, this._results, layer); }, /** * Shuffles a set of tiles in a given area. It will only randomise the tiles in that area, so if they're all the same nothing will appear to have changed! + * * @method Phaser.Tilemap#shuffle - * @param {number} tileA - First tile index. - * @param {number} tileB - Second tile index. * @param {number} x - X position of the top left of the area to operate one, given in tiles, not pixels. * @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels. * @param {number} width - The width in tiles of the area to operate on. * @param {number} height - The height in tiles of the area to operate on. - * @param {number} [layer] - The Tilemap Layer to operate on. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. */ shuffle: function (x, y, width, height, layer) { - if (typeof layer === "undefined") { layer = this.currentLayer; } + layer = this.getLayer(layer); this.copy(x, y, width, height, layer); @@ -38528,28 +43907,42 @@ Phaser.Tilemap.prototype = { return; } - var header = this._results.shift(); + var indexes = []; - Phaser.Utils.shuffle(this._results); + for (var t = 1; t < this._results.length; t++) + { + if (this._results[t].index) + { + indexes.push(this._results[t].index); + } + } - this._results.unshift(header); + Phaser.Utils.shuffle(indexes); - this.paste(x, y, this._results); + for (var i = 1; i < this._results.length; i++) + { + this._results[i].index = indexes[i - 1]; + } + + this.paste(x, y, this._results, layer); }, /** - * Fill a block with a specific tile index. + * Fills the given area with the specified tile. + * * @method Phaser.Tilemap#fill - * @param {number} index - Index of tiles you want to fill with. + * @param {number} index - The index of the tile that the area will be filled with. * @param {number} x - X position of the top left of the area to operate one, given in tiles, not pixels. * @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels. * @param {number} width - The width in tiles of the area to operate on. * @param {number} height - The height in tiles of the area to operate on. - * @param {number} [layer] - The Tilemap Layer to operate on. + * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. */ fill: function (index, x, y, width, height, layer) { + layer = this.getLayer(layer); + this.copy(x, y, width, height, layer); if (this._results.length < 2) @@ -38562,12 +43955,13 @@ Phaser.Tilemap.prototype = { this._results[i].index = index; } - this.paste(x, y, this._results); + this.paste(x, y, this._results, layer); }, /** * Removes all layers from this tile map. + * * @method Phaser.Tilemap#removeAllLayers */ removeAllLayers: function () { @@ -38579,6 +43973,7 @@ Phaser.Tilemap.prototype = { /** * Dumps the tilemap data out to the console. + * * @method Phaser.Tilemap#dump */ dump: function () { @@ -38619,20 +44014,24 @@ Phaser.Tilemap.prototype = { /** * Removes all layers from this tile map and nulls the game reference. + * * @method Phaser.Tilemap#destroy */ destroy: function () { this.removeAllLayers(); + this.data = []; this.game = null; } }; +Phaser.Tilemap.prototype.constructor = Phaser.Tilemap; + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -38642,25 +44041,37 @@ Phaser.Tilemap.prototype = { * @class Phaser.TilemapLayer * @constructor * @param {Phaser.Game} game - Game reference to the currently running game. -* @param {number} x - The x coordinate of this layer. -* @param {number} y - The y coordinate of this layer. -* @param {number} renderWidth - Width of the layer. -* @param {number} renderHeight - Height of the layer. -* @param {Phaser.Tileset|string} tileset - The tile set used for rendering. * @param {Phaser.Tilemap} tilemap - The tilemap to which this layer belongs. -* @param {number} layer - The layer index within the map. +* @param {number} index - The layer index within the map that this TilemapLayer represents. +* @param {number} width - Width of the renderable area of the layer. +* @param {number} height - Height of the renderable area of the layer. */ -Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, tilemap, layer) { +Phaser.TilemapLayer = function (game, tilemap, index, width, height) { /** * @property {Phaser.Game} game - A reference to the currently running Game. */ this.game = game; - + /** - * @property {HTMLCanvasElement} canvas - The canvas to which this BitmapData draws. + * @property {Phaser.Tilemap} map - The Tilemap to which this layer is bound. */ - this.canvas = Phaser.Canvas.create(renderWidth, renderHeight); + this.map = tilemap; + + /** + * @property {number} index - The index of this layer within the Tilemap. + */ + this.index = index; + + /** + * @property {object} layer - The layer object within the Tilemap that this layer represents. + */ + this.layer = tilemap.layers[index]; + + /** + * @property {HTMLCanvasElement} canvas - The canvas to which this TilemapLayer draws. + */ + this.canvas = Phaser.Canvas.create(width, height); /** * @property {CanvasRenderingContext2D} context - The 2d context of the canvas. @@ -38680,9 +44091,14 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, /** * @property {Phaser.Frame} textureFrame - Dimensions of the renderable area. */ - this.textureFrame = new Phaser.Frame(0, 0, 0, renderWidth, renderHeight, 'tilemaplayer', game.rnd.uuid()); + this.textureFrame = new Phaser.Frame(0, 0, 0, width, height, 'tilemapLayer', game.rnd.uuid()); - Phaser.Sprite.call(this, this.game, x, y, this.texture, this.textureFrame); + Phaser.Sprite.call(this, this.game, 0, 0, this.texture, this.textureFrame); + + /** + * @property {string} name - The name of the layer. + */ + this.name = ''; /** * @property {number} type - The const type of this object. @@ -38691,58 +44107,91 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, this.type = Phaser.TILEMAPLAYER; /** - * A layer that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera. - * @property {boolean} fixedToCamera - Fixes this layer to the Camera. + * An object that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera. + * @property {boolean} fixedToCamera - Fixes this object to the Camera. * @default */ this.fixedToCamera = true; /** - * @property {Phaser.Tileset} tileset - The tile set used for rendering. + * @property {Phaser.Point} cameraOffset - If this object is fixed to the camera then use this Point to specify how far away from the Camera x/y it's rendered. */ - this.tileset = null; + this.cameraOffset = new Phaser.Point(0, 0); /** - * @property {number} tileWidth - The width of a single tile in pixels. + * @property {string} tileColor - If no tileset is given the tiles will be rendered as rectangles in this color. Provide in hex or rgb/rgba string format. + * @default */ - this.tileWidth = 0; + this.tileColor = 'rgb(255, 255, 255)'; /** - * @property {number} tileHeight - The height of a single tile in pixels. + * @property {boolean} debug - If set to true the collideable tile edges path will be rendered. Only works when game is running in Phaser.CANVAS mode. + * @default */ - this.tileHeight = 0; + this.debug = false; /** - * @property {number} tileMargin - The margin around the tiles. + * @property {number} debugAlpha - If debug is true then the tileset is rendered with this alpha level, to make the tile edges clearer. + * @default */ - this.tileMargin = 0; + this.debugAlpha = 0.5; /** - * @property {number} tileSpacing - The spacing around the tiles. + * @property {string} debugColor - If debug is true this is the color used to outline the edges of collidable tiles. Provide in hex or rgb/rgba string format. + * @default */ - this.tileSpacing = 0; + this.debugColor = 'rgba(0, 255, 0, 1)'; /** - * @property {number} widthInPixels - Do NOT recommend changing after the map is loaded! - * @readonly + * @property {boolean} debugFill - If true the debug tiles are filled with debugFillColor AND stroked around. + * @default */ - this.widthInPixels = 0; + this.debugFill = false; /** - * @property {number} heightInPixels - Do NOT recommend changing after the map is loaded! - * @readonly + * @property {string} debugFillColor - If debugFill is true this is the color used to fill the tiles. Provide in hex or rgb/rgba string format. + * @default */ - this.heightInPixels = 0; + this.debugFillColor = 'rgba(0, 255, 0, 0.2)'; /** - * @property {number} renderWidth - The width of the area being rendered. + * @property {string} debugCallbackColor - If debug is true this is the color used to outline the edges of tiles that have collision callbacks. Provide in hex or rgb/rgba string format. + * @default */ - this.renderWidth = renderWidth; + this.debugCallbackColor = 'rgba(255, 0, 0, 1)'; /** - * @property {number} renderHeight - The height of the area being rendered. + * @property {number} scrollFactorX - speed at which this layer scrolls + * horizontally, relative to the camera (e.g. scrollFactorX of 0.5 scrolls + * half as quickly as the 'normal' camera-locked layers do) + * @default 1 */ - this.renderHeight = renderHeight; + this.scrollFactorX = 1; + + /** + * @property {number} scrollFactorY - speed at which this layer scrolls + * vertically, relative to the camera (e.g. scrollFactorY of 0.5 scrolls + * half as quickly as the 'normal' camera-locked layers do) + * @default 1 + */ + this.scrollFactorY = 1; + + /** + * @property {boolean} dirty - Flag controlling when to re-render the layer. + */ + this.dirty = true; + + /** + * @property {number} _cw - Local collision var. + * @private + */ + this._cw = tilemap.tileWidth; + + /** + * @property {number} _ch - Local collision var. + * @private + */ + this._ch = tilemap.tileHeight; /** * @property {number} _ga - Local render loop var to help avoid gc spikes. @@ -38858,51 +44307,7 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, */ this._prevY = 0; - /** - * @property {number} scrollFactorX - speed at which this layer scrolls - * horizontally, relative to the camera (e.g. scrollFactorX of 0.5 scrolls - * half as quickly as the 'normal' camera-locked layers do) - * @default 1 - */ - this.scrollFactorX = 1; - - /** - * @property {number} scrollFactorY - speed at which this layer scrolls - * vertically, relative to the camera (e.g. scrollFactorY of 0.5 scrolls - * half as quickly as the 'normal' camera-locked layers do) - * @default 1 - */ - this.scrollFactorY = 1; - - /** - * @property {Phaser.Tilemap} tilemap - The Tilemap to which this layer is bound. - */ - this.tilemap = null; - - /** - * @property {number} layer - Tilemap layer index. - */ - this.layer = null; - - /** - * @property {number} index - */ - this.index = 0; - - /** - * @property {boolean} dirty - Flag controlling when to re-render the layer. - */ - this.dirty = true; - - if (tileset instanceof Phaser.Tileset || typeof tileset === 'string') - { - this.updateTileset(tileset); - } - - if (tilemap instanceof Phaser.Tilemap) - { - this.updateMapData(tilemap, layer); - } + this.updateMax(); }; @@ -38911,13 +44316,16 @@ Phaser.TilemapLayer.prototype = Phaser.Utils.extend(true, Phaser.TilemapLayer.pr Phaser.TilemapLayer.prototype.constructor = Phaser.TilemapLayer; /** -* Automatically called by World.preUpdate. Handles cache updates. +* Automatically called by World.postUpdate. Handles cache updates. * -* @method Phaser.TilemapLayer#update +* @method Phaser.TilemapLayer#postUpdate * @memberof Phaser.TilemapLayer */ -Phaser.TilemapLayer.prototype.update = function () { +Phaser.TilemapLayer.prototype.postUpdate = function () { + Phaser.Sprite.prototype.postUpdate.call(this); + + // Stops you being able to auto-scroll the camera if it's not following a sprite this.scrollX = this.game.camera.x * this.scrollFactorX; this.scrollY = this.game.camera.y * this.scrollFactorY; @@ -38933,69 +44341,12 @@ Phaser.TilemapLayer.prototype.update = function () { */ Phaser.TilemapLayer.prototype.resizeWorld = function () { - this.game.world.setBounds(0, 0, this.widthInPixels, this.heightInPixels); + this.game.world.setBounds(0, 0, this.layer.widthInPixels, this.layer.heightInPixels); } /** -* Updates the Tileset data. -* -* @method Phaser.TilemapLayer#updateTileset -* @memberof Phaser.TilemapLayer -* @param {Phaser.Tileset|string} tileset - The tileset to use for this layer. -*/ -Phaser.TilemapLayer.prototype.updateTileset = function (tileset) { - - if (tileset instanceof Phaser.Tileset) - { - this.tileset = tileset; - } - else if (typeof tileset === 'string') - { - this.tileset = this.game.cache.getTileset('tiles'); - } - else - { - return; - } - - this.tileWidth = this.tileset.tileWidth; - this.tileHeight = this.tileset.tileHeight; - this.tileMargin = this.tileset.tileMargin; - this.tileSpacing = this.tileset.tileSpacing; - - this.updateMax(); - -} - -/** -* Updates the Tilemap data. -* -* @method Phaser.TilemapLayer#updateMapData -* @memberof Phaser.TilemapLayer -* @param {Phaser.Tilemap} tilemap - The tilemap to which this layer belongs. -* @param {number} layer - The layer index within the map. -*/ -Phaser.TilemapLayer.prototype.updateMapData = function (tilemap, layer) { - - if (typeof layer === 'undefined') - { - layer = 0; - } - - if (tilemap instanceof Phaser.Tilemap) - { - this.tilemap = tilemap; - this.layer = this.tilemap.layers[layer]; - this.index = layer; - this.updateMax(); - this.tilemap.dirty = true; - } - -} - -/** -* Take an x coordinate that doesn't account for scrollFactorY and 'fix' it +* Take an x coordinate that doesn't account for scrollFactorX and 'fix' it * into a scrolled local space. Used primarily internally * @method Phaser.TilemapLayer#_fixX * @memberof Phaser.TilemapLayer @@ -39005,19 +44356,22 @@ Phaser.TilemapLayer.prototype.updateMapData = function (tilemap, layer) { */ Phaser.TilemapLayer.prototype._fixX = function(x) { + if (x < 0) + { + x = 0; + } + if (this.scrollFactorX === 1) { return x; } - var leftEdge = x - (this._x / this.scrollFactorX); - - return this._x + leftEdge; + return this._x + (x - (this._x / this.scrollFactorX)); } /** -* Take an x coordinate that _does_ account for scrollFactorY and 'unfix' it +* Take an x coordinate that _does_ account for scrollFactorX and 'unfix' it * back to camera space. Used primarily internally * @method Phaser.TilemapLayer#_unfixX * @memberof Phaser.TilemapLayer @@ -39032,9 +44386,7 @@ Phaser.TilemapLayer.prototype._unfixX = function(x) { return x; } - var leftEdge = x - this._x; - - return (this._x / this.scrollFactorX) + leftEdge; + return (this._x / this.scrollFactorX) + (x - this._x); } @@ -39049,14 +44401,17 @@ Phaser.TilemapLayer.prototype._unfixX = function(x) { */ Phaser.TilemapLayer.prototype._fixY = function(y) { + if (y < 0) + { + y = 0; + } + if (this.scrollFactorY === 1) { return y; } - var topEdge = y - (this._y / this.scrollFactorY); - - return this._y + topEdge; + return this._y + (y - (this._y / this.scrollFactorY)); } @@ -39076,9 +44431,7 @@ Phaser.TilemapLayer.prototype._unfixY = function(y) { return y; } - var topEdge = y - this._y; - - return (this._y / this.scrollFactorY) + topEdge; + return (this._y / this.scrollFactorY) + (y - this._y); } @@ -39091,9 +44444,9 @@ Phaser.TilemapLayer.prototype._unfixY = function(y) { */ Phaser.TilemapLayer.prototype.getTileX = function (x) { - var tileWidth = this.tileWidth * this.scale.x; + // var tileWidth = this.tileWidth * this.scale.x; - return this.game.math.snapToFloor(this._fixX(x), tileWidth) / tileWidth; + return this.game.math.snapToFloor(this._fixX(x), this.map.tileWidth) / this.map.tileWidth; } @@ -39106,9 +44459,9 @@ Phaser.TilemapLayer.prototype.getTileX = function (x) { */ Phaser.TilemapLayer.prototype.getTileY = function (y) { - var tileHeight = this.tileHeight * this.scale.y; + // var tileHeight = this.tileHeight * this.scale.y; - return this.game.math.snapToFloor(this._fixY(y), tileHeight) / tileHeight; + return this.game.math.snapToFloor(this._fixY(y), this.map.tileHeight) / this.map.tileHeight; } @@ -39118,7 +44471,8 @@ Phaser.TilemapLayer.prototype.getTileY = function (y) { * @memberof Phaser.TilemapLayer * @param {number} x - X position of the point in target tile. * @param {number} y - Y position of the point in target tile. -* @return {Phaser.Tile} The tile with specific properties. +* @param {Phaser.Point|object} point - The Point object to set the x and y values on. +* @return {Phaser.Point|object} A Point object with its x and y properties set. */ Phaser.TilemapLayer.prototype.getTileXY = function (x, y, point) { @@ -39130,73 +44484,43 @@ Phaser.TilemapLayer.prototype.getTileXY = function (x, y, point) { } /** -* Get the tiles within the given area. +* Get all tiles that exist within the given area, defined by the top-left corner, width and height. Values given are in pixels, not tiles. * @method Phaser.TilemapLayer#getTiles * @memberof Phaser.TilemapLayer -* @param {number} x - X position of the top left of the area to copy (given in tiles, not pixels) -* @param {number} y - Y position of the top left of the area to copy (given in tiles, not pixels) -* @param {number} width - The width of the area to copy (given in tiles, not pixels) -* @param {number} height - The height of the area to copy (given in tiles, not pixels) -* @param {boolean} collides - If true only return tiles that collide on one or more faces. +* @param {number} x - X position of the top left corner. +* @param {number} y - Y position of the top left corner. +* @param {number} width - Width of the area to get. +* @param {number} height - Height of the area to get. +* @param {boolean} [collides=false] - If true only return tiles that collide on one or more faces. * @return {array} Array with tiles informations (each contains x, y, and the tile). */ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides) { - if (this.tilemap === null) - { - return; - } - // Should we only get tiles that have at least one of their collision flags set? (true = yes, false = no just get them all) if (typeof collides === 'undefined') { collides = false; } - // Cap the values - - if (x < 0) - { - x = 0; - } - - if (y < 0) - { - y = 0; - } - // adjust the x,y coordinates for scrollFactor - x = this._fixX( x ); - y = this._fixY( y ); + x = this._fixX(x); + y = this._fixY(y); - if (width > this.widthInPixels) + if (width > this.layer.widthInPixels) { - width = this.widthInPixels; + width = this.layer.widthInPixels; } - if (height > this.heightInPixels) + if (height > this.layer.heightInPixels) { - height = this.heightInPixels; + height = this.layer.heightInPixels; } - var tileWidth = this.tileWidth * this.scale.x; - var tileHeight = this.tileHeight * this.scale.y; - // Convert the pixel values into tile coordinates - this._tx = this.game.math.snapToFloor(x, tileWidth) / tileWidth; - this._ty = this.game.math.snapToFloor(y, tileHeight) / tileHeight; - this._tw = (this.game.math.snapToCeil(width, tileWidth) + tileWidth) / tileWidth; - this._th = (this.game.math.snapToCeil(height, tileHeight) + tileHeight) / tileHeight; + this._tx = this.game.math.snapToFloor(x, this._cw) / this._cw; + this._ty = this.game.math.snapToFloor(y, this._ch) / this._ch; + this._tw = (this.game.math.snapToCeil(width, this._cw) + this._cw) / this._cw; + this._th = (this.game.math.snapToCeil(height, this._ch) + this._ch) / this._ch; // This should apply the layer x/y here - - // this._results.length = 0; - this._results = []; - - // pretty sure we don't use this any more? - // this._results.push( { x: x, y: y, width: width, height: height, tx: this._tx, ty: this._ty, tw: this._tw, th: this._th }); - - var _index = 0; - var _tile = null; - var sx = 0; - var sy = 0; + this._results.length = 0; for (var wy = this._ty; wy < this._ty + this._th; wy++) { @@ -39204,19 +44528,20 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides { if (this.layer.data[wy] && this.layer.data[wy][wx]) { - // Could combine - _index = this.layer.data[wy][wx] - 1; - _tile = this.tileset.getTile(_index); - - sx = _tile.width * this.scale.x; - sy = _tile.height * this.scale.y; - - if (collides === false || (collides && _tile.collideNone === false)) + if (collides === false || (collides && this.layer.data[wy][wx].canCollide)) { - // convert tile coordinates back to camera space for return - var _wx = this._unfixX( wx*sx ) / tileWidth; - var _wy = this._unfixY( wy*sy ) / tileHeight; - this._results.push({ x: _wx * sx, right: (_wx * sx) + sx, y: _wy * sy, bottom: (_wy * sy) + sy, width: sx, height: sy, tx: _wx, ty: _wy, tile: _tile }); + // Convert tile coordinates back to camera space for return + var _wx = this._unfixX(wx * this._cw) / this._cw; + var _wy = this._unfixY(wy * this._ch) / this._ch; + + this._results.push({ + x: _wx * this._cw, + y: _wy * this._ch, + right: (_wx * this._cw) + this._cw, + bottom: (_wy * this._ch) + this._ch, + tile: this.layer.data[wy][wx], + layer: this.layer.data[wy][wx].layer + }); } } } @@ -39233,8 +44558,8 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides */ Phaser.TilemapLayer.prototype.updateMax = function () { - this._maxX = this.game.math.ceil(this.canvas.width / this.tileWidth) + 1; - this._maxY = this.game.math.ceil(this.canvas.height / this.tileHeight) + 1; + this._maxX = this.game.math.ceil(this.canvas.width / this.map.tileWidth) + 1; + this._maxY = this.game.math.ceil(this.canvas.height / this.map.tileHeight) + 1; if (this.layer) { @@ -39247,9 +44572,6 @@ Phaser.TilemapLayer.prototype.updateMax = function () { { this._maxY = this.layer.height; } - - this.widthInPixels = this.layer.width * this.tileWidth; - this.heightInPixels = this.layer.height * this.tileHeight; } this.dirty = true; @@ -39263,12 +44585,12 @@ Phaser.TilemapLayer.prototype.updateMax = function () { */ Phaser.TilemapLayer.prototype.render = function () { - if (this.tilemap && this.tilemap.dirty) + if (this.layer.dirty) { this.dirty = true; } - if (!this.dirty || !this.tileset || !this.tilemap || !this.visible) + if (!this.dirty || !this.visible) { return; } @@ -39276,101 +44598,194 @@ Phaser.TilemapLayer.prototype.render = function () { this._prevX = this._dx; this._prevY = this._dy; - this._dx = -(this._x - (this._startX * this.tileWidth)); - this._dy = -(this._y - (this._startY * this.tileHeight)); + this._dx = -(this._x - (this._startX * this.map.tileWidth)); + this._dy = -(this._y - (this._startY * this.map.tileHeight)); this._tx = this._dx; this._ty = this._dy; this.context.clearRect(0, 0, this.canvas.width, this.canvas.height); - for (var y = this._startY; y < this._startY + this._maxY; y++) + this.context.fillStyle = this.tileColor; + + var tile; + var set; + var ox = 0; + var oy = 0; + + if (this.debug) + { + this.context.globalAlpha = this.debugAlpha; + } + + for (var y = this._startY, lenY = this._startY + this._maxY; y < lenY; y++) { this._column = this.layer.data[y]; - for (var x = this._startX; x < this._startX + this._maxX; x++) + for (var x = this._startX, lenX = this._startX + this._maxX; x < lenX; x++) { - // only -1 on TILED maps, not CSV - var tile = this.tileset.tiles[this._column[x]-1]; - - if (tile) + if (this._column[x]) { - this.context.drawImage( - this.tileset.image, - tile.x, - tile.y, - this.tileWidth, - this.tileHeight, - Math.floor(this._tx), - Math.floor(this._ty), - this.tileWidth, - this.tileHeight - ); + tile = this._column[x]; + + if (this.map.tiles[tile.index]) + { + set = this.map.tilesets[this.map.tiles[tile.index][2]] + + if (set.image) + { + if (this.debug === false && tile.alpha !== this.context.globalAlpha) + { + this.context.globalAlpha = tile.alpha; + } + + if (set.tileWidth !== this.map.tileWidth || set.tileHeight !== this.map.tileHeight) + { + // TODO: Smaller sized tile check + this.context.drawImage( + this.map.tilesets[this.map.tiles[tile.index][2]].image, + this.map.tiles[tile.index][0], + this.map.tiles[tile.index][1], + set.tileWidth, + set.tileHeight, + Math.floor(this._tx), + Math.floor(this._ty) - (set.tileHeight - this.map.tileHeight), + set.tileWidth, + set.tileHeight + ); + } + else + { + this.context.drawImage( + this.map.tilesets[this.map.tiles[tile.index][2]].image, + this.map.tiles[tile.index][0], + this.map.tiles[tile.index][1], + this.map.tileWidth, + this.map.tileHeight, + Math.floor(this._tx), + Math.floor(this._ty), + this.map.tileWidth, + this.map.tileHeight + ); + } + + if (tile.debug) + { + this.context.fillStyle = 'rgba(0, 255, 0, 0.4)'; + this.context.fillRect(Math.floor(this._tx), Math.floor(this._ty), this.map.tileWidth, this.map.tileHeight); + } + } + else + { + this.context.fillRect(Math.floor(this._tx), Math.floor(this._ty), this.map.tileWidth, this.map.tileHeight); + } + } } - this._tx += this.tileWidth; + this._tx += this.map.tileWidth; } this._tx = this._dx; - this._ty += this.tileHeight; + this._ty += this.map.tileHeight; + + } + + if (this.debug) + { + this.context.globalAlpha = 1; + this.renderDebug(); } // Only needed if running in WebGL, otherwise this array will never get cleared down I don't think! - if (this.game.renderType == Phaser.WEBGL) + if (this.game.renderType === Phaser.WEBGL) { PIXI.texturesToUpdate.push(this.baseTexture); } this.dirty = false; - - if (this.tilemap.dirty) - { - this.tilemap.dirty = false; - } + this.layer.dirty = false; return true; } /** -* Returns the absolute delta x value. -* @method Phaser.TilemapLayer#deltaAbsX +* Renders a collision debug overlay on-top of the canvas. Called automatically by render when debug = true. +* @method Phaser.TilemapLayer#renderDebug * @memberof Phaser.TilemapLayer -* @return {number} Absolute delta X value */ -Phaser.TilemapLayer.prototype.deltaAbsX = function () { - return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX()); -} +Phaser.TilemapLayer.prototype.renderDebug = function () { -/** -* Returns the absolute delta y value. -* @method Phaser.TilemapLayer#deltaAbsY -* @memberof Phaser.TilemapLayer -* @return {number} Absolute delta Y value -*/ -Phaser.TilemapLayer.prototype.deltaAbsY = function () { - return (this.deltaY() > 0 ? this.deltaY() : -this.deltaY()); -} + this._tx = this._dx; + this._ty = this._dy; -/** -* Returns the delta x value. -* @method Phaser.TilemapLayer#deltaX -* @memberof Phaser.TilemapLayer -* @return {number} Delta X value -*/ -Phaser.TilemapLayer.prototype.deltaX = function () { - return this._dx - this._prevX; -} + this.context.strokeStyle = this.debugColor; + this.context.fillStyle = this.debugFillColor; + + for (var y = this._startY, lenY = this._startY + this._maxY; y < lenY; y++) + { + this._column = this.layer.data[y]; + + for (var x = this._startX, lenX = this._startX + this._maxX; x < lenX; x++) + { + var tile = this._column[x]; + + if (tile && (tile.faceTop || tile.faceBottom || tile.faceLeft || tile.faceRight)) + { + this._tx = Math.floor(this._tx); + + if (this.debugFill) + { + this.context.fillRect(this._tx, this._ty, this._cw, this._ch); + } + + this.context.beginPath(); + + if (tile.faceTop) + { + this.context.moveTo(this._tx, this._ty); + this.context.lineTo(this._tx + this._cw, this._ty); + } + + if (tile.faceBottom) + { + this.context.moveTo(this._tx, this._ty + this._ch); + this.context.lineTo(this._tx + this._cw, this._ty + this._ch); + } + + if (tile.faceLeft) + { + this.context.moveTo(this._tx, this._ty); + this.context.lineTo(this._tx, this._ty + this._ch); + } + + if (tile.faceRight) + { + this.context.moveTo(this._tx + this._cw, this._ty); + this.context.lineTo(this._tx + this._cw, this._ty + this._ch); + } + + this.context.stroke(); + } + + // Collision callback + if (tile && (tile.collisionCallback || tile.layer.callbacks[tile.index])) + { + this.context.fillStyle = this.debugCallbackColor; + this.context.fillRect(this._tx, this._ty, this._cw, this._ch); + this.context.fillStyle = this.debugFillColor; + } + + this._tx += this.map.tileWidth; + + } + + this._tx = this._dx; + this._ty += this.map.tileHeight; + + } -/** -* Returns the delta y value. -* @method Phaser.TilemapLayer#deltaY -* @memberof Phaser.TilemapLayer -* @return {number} Delta Y value -*/ -Phaser.TilemapLayer.prototype.deltaY = function () { - return this._dy - this._prevY; } /** @@ -39385,16 +44800,17 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollX", { set: function (value) { - if (value !== this._x && value >= 0 && this.layer) + // if (value !== this._x && value >= 0 && this.layer && this.layer.widthInPixels > this.width) + if (value !== this._x && value >= 0 && this.layer.widthInPixels > this.width) { this._x = value; - - if (this._x > (this.widthInPixels - this.renderWidth)) + + if (this._x > (this.layer.widthInPixels - this.width)) { - this._x = this.widthInPixels - this.renderWidth; + this._x = this.layer.widthInPixels - this.width; } - this._startX = this.game.math.floor(this._x / this.tileWidth); + this._startX = this.game.math.floor(this._x / this.map.tileWidth); if (this._startX < 0) { @@ -39425,16 +44841,17 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollY", { set: function (value) { - if (value !== this._y && value >= 0 && this.layer) + // if (value !== this._y && value >= 0 && this.layer && this.heightInPixels > this.renderHeight) + if (value !== this._y && value >= 0 && this.layer.heightInPixels > this.height) { this._y = value; - if (this._y > (this.heightInPixels - this.renderHeight)) + if (this._y > (this.layer.heightInPixels - this.height)) { - this._y = this.heightInPixels - this.renderHeight; + this._y = this.layer.heightInPixels - this.height; } - this._startY = this.game.math.floor(this._y / this.tileHeight); + this._startY = this.game.math.floor(this._y / this.map.tileHeight); if (this._startY < 0) { @@ -39453,9 +44870,49 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollY", { }); +/** +* @name Phaser.TilemapLayer#collisionWidth +* @property {number} collisionWidth - The width of the collision tiles. +*/ +Object.defineProperty(Phaser.TilemapLayer.prototype, "collisionWidth", { + + get: function () { + return this._cw; + }, + + set: function (value) { + + this._cw = value; + + this.dirty = true; + + } + +}); + +/** +* @name Phaser.TilemapLayer#collisionHeight +* @property {number} collisionHeight - The height of the collision tiles. +*/ +Object.defineProperty(Phaser.TilemapLayer.prototype, "collisionHeight", { + + get: function () { + return this._ch; + }, + + set: function (value) { + + this._ch = value; + + this.dirty = true; + + } + +}); + /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -39470,47 +44927,45 @@ Phaser.TilemapParser = { * Creates a Tileset object. * @method Phaser.TilemapParser.tileset * @param {Phaser.Game} game - Game reference to the currently running game. - * @param {string} key - * @param {number} tileWidth - * @param {number} tileHeight - * @param {number} tileMax - * @param {number} tileMargin - * @param {number} tileSpacing + * @param {string} key - The Cache key of this tileset. + * @param {number} tileWidth - Width of each single tile in pixels. + * @param {number} tileHeight - Height of each single tile in pixels. + * @param {number} [tileMargin=0] - If the tiles have been drawn with a margin, specify the amount here. + * @param {number} [tileSpacing=0] - If the tiles have been drawn with spacing between them, specify the amount here. + * @param {number} [rows=-1] - How many tiles are placed horizontally in each row? If -1 it will calculate rows by dividing the image width by tileWidth. + * @param {number} [columns=-1] - How many tiles are placed vertically in each column? If -1 it will calculate columns by dividing the image height by tileHeight. + * @param {number} [total=-1] - The maximum number of tiles to extract from the image. If -1 it will extract `rows * columns` worth. You can also set a value lower than the actual number of tiles. * @return {Phaser.Tileset} Generated Tileset object. */ - tileset: function (game, key, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) { + tileset: function (game, key, tileWidth, tileHeight, tileMargin, tileSpacing, rows, columns, total) { // How big is our image? var img = game.cache.getTilesetImage(key); - if (img == null) + if (img === null) { + console.warn("Phaser.TilemapParser.tileSet: Invalid image key given"); return null; } var width = img.width; var height = img.height; - // If no tile width/height is given, try and figure it out (won't work if the tileset has margin/spacing) - if (tileWidth <= 0) + if (rows === -1) { - tileWidth = Math.floor(-width / Math.min(-1, tileWidth)); + rows = Math.round(width / tileWidth); } - if (tileHeight <= 0) + if (columns === -1) { - tileHeight = Math.floor(-height / Math.min(-1, tileHeight)); + columns = Math.round(height / tileHeight); } - var row = Math.round(width / tileWidth); - var column = Math.round(height / tileHeight); - var total = row * column; + if (total === -1) + { + total = rows * columns; + } - if (tileMax !== -1) - { - total = tileMax; - } - // Zero or smaller than tile sizes? if (width === 0 || height === 0 || width < tileWidth || height < tileHeight || total === 0) { @@ -39518,26 +44973,7 @@ Phaser.TilemapParser = { return null; } - // Let's create some tiles - var x = tileMargin; - var y = tileMargin; - - var tileset = new Phaser.Tileset(img, key, tileWidth, tileHeight, tileMargin, tileSpacing); - - for (var i = 0; i < total; i++) - { - tileset.addTile(new Phaser.Tile(tileset, i, x, y, tileWidth, tileHeight)); - - x += tileWidth + tileSpacing; - - if (x === width) - { - x = tileMargin; - y += tileHeight + tileSpacing; - } - } - - return tileset; + return new Phaser.Tileset(img, key, tileWidth, tileHeight, tileMargin, tileSpacing, rows, columns, total); }, @@ -39545,19 +44981,27 @@ Phaser.TilemapParser = { * Parse tileset data from the cache and creates a Tileset object. * @method Phaser.TilemapParser.parse * @param {Phaser.Game} game - Game reference to the currently running game. - * @param {object} data - * @param {string} format - * @return {Phaser.Tileset} Generated Tileset object. + * @param {string} key - The key of the tilemap in the Cache. + * @return {object} The parsed map object. */ - parse: function (game, data, format) { + parse: function (game, key) { - if (format === Phaser.Tilemap.CSV) + var map = game.cache.getTilemapData(key); + + if (map) { - return this.parseCSV(data); + if (map.format === Phaser.Tilemap.CSV) + { + return this.parseCSV(map.data); + } + else if (map.format === Phaser.Tilemap.TILED_JSON) + { + return this.parseTiledJSON(map.data); + } } - else if (format === Phaser.Tilemap.TILED_JSON) + else { - return this.parseTiledJSON(data); + return { layers: [], objects: [], images: [], tilesets: [] }; } }, @@ -39595,6 +45039,8 @@ Phaser.TilemapParser = { } } + // Build collision map + return [{ name: 'csv', width: width, height: height, alpha: 1, visible: true, indexes: [], tileMargin: 0, tileSpacing: 0, data: output }]; }, @@ -39602,66 +45048,242 @@ Phaser.TilemapParser = { /** * Parses a Tiled JSON file into valid map data. * @method Phaser.TilemapParser.parseJSON - * @param {object} json- The Tiled JSON data. - * @return {object} Generated map data. + * @param {object} json - The JSON map data. + * @return {object} Generated and parsed map data. */ parseTiledJSON: function (json) { + if (json.orientation !== 'orthogonal') + { + console.warn('TilemapParser.parseTiledJSON: Only orthogonal map types are supported in this version of Phaser'); + return null; + } + + // Map data will consist of: layers, objects, images, tilesets, sizes + var map = {}; + + map.width = json.width; + map.height = json.height; + map.tileWidth = json.tilewidth; + map.tileHeight = json.tileheight; + map.orientation = json.orientation; + map.version = json.version; + map.properties = json.properties; + map.widthInPixels = map.width * map.tileWidth; + map.heightInPixels = map.height * map.tileHeight; + + // Tile Layers var layers = []; for (var i = 0; i < json.layers.length; i++) { - // Check it's a data layer - if (!json.layers[i].data) + if (json.layers[i].type !== 'tilelayer') { continue; } - // json.tilewidth - // json.tileheight - var layer = { name: json.layers[i].name, + x: json.layers[i].x, + y: json.layers[i].y, width: json.layers[i].width, height: json.layers[i].height, + widthInPixels: json.layers[i].width * json.tilewidth, + heightInPixels: json.layers[i].height * json.tileheight, alpha: json.layers[i].opacity, visible: json.layers[i].visible, + properties: {}, indexes: [], - - tileMargin: json.tilesets[0].margin, - tileSpacing: json.tilesets[0].spacing + callbacks: [] }; - var output = []; - var c = 0; - var row; - - for (var t = 0; t < json.layers[i].data.length; t++) + if (json.layers[i].properties) { - if (c === 0) + layer.properties = json.layers[i].properties; + } + + var x = 0; + var row = []; + var output = []; + + // Loop through the data field in the JSON. + + // This is an array containing the tile indexes, one after the other. 0 = no tile, everything else = the tile index (starting at 1) + // If the map contains multiple tilesets then the indexes are relative to that which the set starts from. + // Need to set which tileset in the cache = which tileset in the JSON, if you do this manually it means you can use the same map data but a new tileset. + + for (var t = 0, len = json.layers[i].data.length; t < len; t++) + { + // index, x, y, width, height + if (json.layers[i].data[t] > 0) { - row = []; + row.push(new Phaser.Tile(layer, json.layers[i].data[t], x, output.length, json.tilewidth, json.tileheight)); + } + else + { + row.push(null); } - row.push(json.layers[i].data[t]); - c++; + x++; - if (c == json.layers[i].width) + if (x === json.layers[i].width) { output.push(row); - c = 0; + x = 0; + row = []; } } layer.data = output; - + layers.push(layer); } - return layers; + map.layers = layers; + + // Images + var images = []; + + for (var i = 0; i < json.layers.length; i++) + { + if (json.layers[i].type !== 'imagelayer') + { + continue; + } + + var image = { + + name: json.layers[i].name, + image: json.layers[i].image, + x: json.layers[i].x, + y: json.layers[i].y, + alpha: json.layers[i].opacity, + visible: json.layers[i].visible, + properties: {} + + }; + + if (json.layers[i].properties) + { + image.properties = json.layers[i].properties; + } + + images.push(image); + + } + + map.images = images; + + // Objects + var objects = {}; + + for (var i = 0; i < json.layers.length; i++) + { + if (json.layers[i].type !== 'objectgroup') + { + continue; + } + + objects[json.layers[i].name] = []; + + for (var v = 0, len = json.layers[i].objects.length; v < len; v++) + { + // For now we'll just support object tiles + if (json.layers[i].objects[v].gid) + { + var object = { + + gid: json.layers[i].objects[v].gid, + name: json.layers[i].objects[v].name, + x: json.layers[i].objects[v].x, + y: json.layers[i].objects[v].y, + visible: json.layers[i].objects[v].visible, + properties: json.layers[i].objects[v].properties + + }; + + objects[json.layers[i].name].push(object); + } + + } + } + + map.objects = objects; + + // Tilesets + var tilesets = []; + + for (var i = 0; i < json.tilesets.length; i++) + { + // name, firstgid, width, height, margin, spacing, properties + var set = json.tilesets[i]; + var newSet = new Phaser.Tileset(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties); + + if (set.tileproperties) + { + newSet.tileProperties = set.tileproperties; + } + + newSet.rows = (set.imageheight - set.margin) / (set.tileheight + set.spacing); + newSet.columns = (set.imagewidth - set.margin) / (set.tilewidth + set.spacing); + newSet.total = newSet.rows * newSet.columns; + + tilesets.push(newSet); + } + + map.tilesets = tilesets; + + map.tiles = []; + + // Finally lets build our super tileset index + for (var i = 0; i < map.tilesets.length; i++) + { + var set = map.tilesets[i]; + + var x = set.tileMargin; + var y = set.tileMargin; + + var count = 0; + var countX = 0; + var countY = 0; + + for (var t = set.firstgid; t < set.firstgid + set.total; t++) + { + // Can add extra properties here as needed + map.tiles[t] = [x, y, i]; + + x += set.tileWidth + set.tileSpacing; + + count++; + + if (count === set.total) + { + break; + } + + countX++; + + if (countX === set.columns) + { + x = set.tileMargin; + y += set.tileHeight + set.tileSpacing; + + countX = 0; + countY++; + + if (countY === set.rows) + { + break; + } + } + } + + } + + return map; } @@ -39669,97 +45291,129 @@ Phaser.TilemapParser = { /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** * A Tile set is a combination of an image containing the tiles and collision data per tile. +* You should not normally instantiate this class directly. * * @class Phaser.Tileset * @constructor -* @param {Image} image - The Image object from the Cache. -* @param {string} key - The key of the tileset in the cache. -* @param {number} tileWidth - The width of the tile in pixels. -* @param {number} tileHeight - The height of the tile in pixels. -* @param {number} [tileMargin] - The margin around the tiles in the sheet. -* @param {number} [tileSpacing] - The spacing between the tiles in the sheet. +* @param {string} name - The name of the tileset in the map data. +* @param {number} firstgid - The Tiled firstgid value. +* @param {number} width - Width of each tile in pixels. +* @param {number} height - Height of each tile in pixels. +* @param {number} margin - The amount of margin around the tilesheet. +* @param {number} spacing - The amount of spacing between each tile in the sheet. +* @param {object} properties - Tileset properties. */ -Phaser.Tileset = function (image, key, tileWidth, tileHeight, tileMargin, tileSpacing) { - - if (typeof tileMargin === "undefined") { tileMargin = 0; } - if (typeof tileSpacing === "undefined") { tileSpacing = 0; } +Phaser.Tileset = function (name, firstgid, width, height, margin, spacing, properties) { /** - * @property {string} key - The cache ID. + * @property {string} name - The name of the Tileset. */ - this.key = key; + this.name = name; /** - * @property {object} image - The image used for rendering. + * @property {number} firstgid - The Tiled firstgid value. + * @default */ - this.image = image; + this.firstgid = firstgid; /** * @property {number} tileWidth - The width of a tile in pixels. */ - this.tileWidth = tileWidth; + this.tileWidth = width; /** * @property {number} tileHeight - The height of a tile in pixels. */ - this.tileHeight = tileHeight; + this.tileHeight = height; /** * @property {number} tileMargin - The margin around the tiles in the sheet. */ - this.margin = tileMargin; + this.tileMargin = margin; /** * @property {number} tileSpacing - The margin around the tiles in the sheet. */ - this.spacing = tileSpacing; + this.tileSpacing = spacing; /** - * @property {array} tiles - An array of the tile collision data. + * @property {object} properties - Tileset specific properties (typically defined in the Tiled editor). */ - this.tiles = []; + this.properties = properties; -} + /** + * @property {object} tilePproperties - Tile specific properties (typically defined in the Tiled editor). + */ + // this.tileProperties = {}; + + /** + * @property {object} image - The image used for rendering. This is a reference to the image stored in Phaser.Cache. + */ + this.image = null; + + /** + * @property {number} rows - The number of rows in the tile sheet. + */ + this.rows = 0; + + /** + * @property {number} columns - The number of columns in the tile sheet. + */ + this.columns = 0; + + /** + * @property {number} total - The total number of tiles in the tilesheet. + */ + this.total = 0; + +}; Phaser.Tileset.prototype = { - /** - * Adds a Tile into this set. - * - * @method Phaser.Tileset#addTile - * @param {Phaser.Tile} tile - The tile to add to this set. - */ - addTile: function (tile) { - - this.tiles.push(tile); - - return tile; - - }, - /** * Gets a Tile from this set. * * @method Phaser.Tileset#getTile * @param {number} index - The index of the tile within the set. - * @return {Phaser.Tile} The tile. - */ + * @return {object} The tile object. getTile: function (index) { - if (this.tiles[index]) - { - return this.tiles[index]; - } - - return null; + return this.tiles[index]; }, + */ + + /** + * Gets a Tile from this set. + * + * @method Phaser.Tileset#getTileX + * @param {number} index - The index of the tile within the set. + * @return {object} The tile object. + getTileX: function (index) { + + return this.tiles[index][0]; + + }, + */ + + /** + * Gets a Tile from this set. + * + * @method Phaser.Tileset#getTileY + * @param {number} index - The index of the tile within the set. + * @return {object} The tile object. + getTileY: function (index) { + + return this.tiles[index][1]; + + }, + */ /** * Sets tile spacing and margins. @@ -39775,93 +45429,22 @@ Phaser.Tileset.prototype = { }, - /** - * Checks if the tile at the given index can collide. - * - * @method Phaser.Tileset#canCollide - * @param {number} index - The index of the tile within the set. - * @return {boolean} True or false depending on the tile collision or null if no tile was found at the given index. - */ - canCollide: function (index) { - - if (this.tiles[index]) - { - return this.tiles[index].collideNone; - } - - return null; - - }, - /** * Checks if the tile at the given index exists. * * @method Phaser.Tileset#checkTileIndex * @param {number} index - The index of the tile within the set. * @return {boolean} True if a tile exists at the given index otherwise false. - */ checkTileIndex: function (index) { return (this.tiles[index]); - }, - - /** - * Sets collision values on a range of tiles in the set. - * - * @method Phaser.Tileset#setCollisionRange - * @param {number} start - The index to start setting the collision data on. - * @param {number} stop - The index to stop setting the collision data on. - * @param {boolean} left - Should the tile collide on the left? - * @param {boolean} right - Should the tile collide on the right? - * @param {boolean} up - Should the tile collide on the top? - * @param {boolean} down - Should the tile collide on the bottom? - */ - setCollisionRange: function (start, stop, left, right, up, down) { - - if (this.tiles[start] && this.tiles[stop] && start < stop) - { - for (var i = start; i <= stop; i++) - { - this.tiles[i].setCollision(left, right, up, down); - } - } - - }, - - /** - * Sets collision values on a tile in the set. - * - * @method Phaser.Tileset#setCollision - * @param {number} index - The index of the tile within the set. - * @param {boolean} left - Should the tile collide on the left? - * @param {boolean} right - Should the tile collide on the right? - * @param {boolean} up - Should the tile collide on the top? - * @param {boolean} down - Should the tile collide on the bottom? - */ - setCollision: function (index, left, right, up, down) { - - if (this.tiles[index]) - { - this.tiles[index].setCollision(left, right, up, down); - } - } + */ -} +}; -/** -* @name Phaser.Tileset#total -* @property {number} total - The total number of tiles in this Tileset. -* @readonly -*/ -Object.defineProperty(Phaser.Tileset.prototype, "total", { - - get: function () { - return this.tiles.length; - } - -}); +Phaser.Tileset.prototype.constructor = Phaser.Tileset; /** * We're replacing a couple of Pixi's methods here to fix or add some vital functionality: @@ -39869,6 +45452,7 @@ Object.defineProperty(Phaser.Tileset.prototype, "total", { * 1) Added support for Trimmed sprite sheets * 2) Skip display objects with an alpha of zero * 3) Avoid Style Recalculation from the incorrect bgcolor value +* 4) Added support for Canvas unit rounding via Phaser.CANVAS_PX_ROUND boolean (disabled by default). * * Hopefully we can remove this once Pixi has been updated to support these things. */ @@ -39888,8 +45472,13 @@ PIXI.CanvasRenderer.prototype.render = function(stage) stage.updateTransform(); this.context.setTransform(1, 0, 0, 1, 0, 0); - this.context.clearRect(0, 0, this.width, this.height) - this.renderDisplayObject(stage); + + if (Phaser.CANVAS_CLEAR_RECT) + { + this.context.clearRect(0, 0, this.width, this.height) + } + + this.renderDisplayObject(stage, false); // Remove frame updates if (PIXI.Texture.frameUpdates.length > 0) @@ -39899,7 +45488,9 @@ PIXI.CanvasRenderer.prototype.render = function(stage) } -PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) +// @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered. + +PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject, renderHidden) { // Once the display object hits this we can break the loop var testObject = displayObject.last._iNext; @@ -39907,9 +45498,7 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) do { - //transform = displayObject.worldTransform; - - if (!displayObject.visible) + if (!displayObject.visible && !renderHidden) { displayObject = displayObject.last._iNext; continue; @@ -39923,19 +45512,41 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) if (displayObject instanceof PIXI.Sprite) { - // var frame = displayObject.texture.frame; - if (displayObject.texture.frame) { this.context.globalAlpha = displayObject.worldAlpha; - - if (displayObject.texture.trimmed) + + if (Phaser.CANVAS_PX_ROUND) { - this.context.setTransform(displayObject.worldTransform[0], displayObject.worldTransform[3], displayObject.worldTransform[1], displayObject.worldTransform[4], displayObject.worldTransform[2] + displayObject.texture.trim.x, displayObject.worldTransform[5] + displayObject.texture.trim.y); + this.context.setTransform( + displayObject.worldTransform[0], + displayObject.worldTransform[3], + displayObject.worldTransform[1], + displayObject.worldTransform[4], + Math.floor(displayObject.worldTransform[2]), + Math.floor(displayObject.worldTransform[5])); } else { - this.context.setTransform(displayObject.worldTransform[0], displayObject.worldTransform[3], displayObject.worldTransform[1], displayObject.worldTransform[4], displayObject.worldTransform[2], displayObject.worldTransform[5]); + this.context.setTransform( + displayObject.worldTransform[0], + displayObject.worldTransform[3], + displayObject.worldTransform[1], + displayObject.worldTransform[4], + displayObject.worldTransform[2], + displayObject.worldTransform[5]); + } + + if (displayObject.texture.trimmed) + { + this.context.transform(1, 0, 0, 1, displayObject.texture.trim.x, displayObject.texture.trim.y); + } + + //if smoothingEnabled is supported and we need to change the smoothing property for this texture + if (this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) + { + this.scaleMode = displayObject.texture.baseTexture.scaleMode; + this.context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); } this.context.drawImage( @@ -39944,8 +45555,8 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) displayObject.texture.frame.y, displayObject.texture.frame.width, displayObject.texture.frame.height, - (displayObject.anchor.x) * -displayObject.texture.frame.width, - (displayObject.anchor.y) * -displayObject.texture.frame.height, + Math.floor((displayObject.anchor.x) * -displayObject.texture.frame.width), + Math.floor((displayObject.anchor.y) * -displayObject.texture.frame.height), displayObject.texture.frame.width, displayObject.texture.frame.height); } diff --git a/build/phaser.min.js b/build/phaser.min.js index 4f17eda8..26cbc352 100644 --- a/build/phaser.min.js +++ b/build/phaser.min.js @@ -1,12 +1,13 @@ -/*! Phaser v1.1.3 | (c) 2013 Photon Storm Ltd. */ -!function(a,b){"function"==typeof define&&define.amd?define(b):"object"==typeof exports?module.exports=b():a.Phaser=b()}(this,function(){function a(a){return[(255&a>>16)/255,(255&a>>8)/255,(255&a)/255]}function b(){return c.Matrix="undefined"!=typeof Float32Array?Float32Array:Array,c.Matrix}function a(a){return[(255&a>>16)/255,(255&a>>8)/255,(255&a)/255]}var c=c||{},d=d||{VERSION:"1.1.3",DEV_VERSION:"1.1.3",GAMES:[],AUTO:0,CANVAS:1,WEBGL:2,HEADLESS:3,SPRITE:0,BUTTON:1,BULLET:2,GRAPHICS:3,TEXT:4,TILESPRITE:5,BITMAPTEXT:6,GROUP:7,RENDERTEXTURE:8,TILEMAP:9,TILEMAPLAYER:10,EMITTER:11,POLYGON:12,BITMAPDATA:13,CANVAS_FILTER:14,WEBGL_FILTER:15,NONE:0,LEFT:1,RIGHT:2,UP:3,DOWN:4};c.InteractionManager=function(){},d.Utils={shuffle:function(a){for(var b=a.length-1;b>0;b--){var c=Math.floor(Math.random()*(b+1)),d=a[b];a[b]=a[c],a[c]=d}return a},pad:function(a,b,c,d){if("undefined"==typeof b)var b=0;if("undefined"==typeof c)var c=" ";if("undefined"==typeof d)var d=3;var e=0;if(b+1>=a.length)switch(d){case 1:a=Array(b+1-a.length).join(c)+a;break;case 3:var f=Math.ceil((e=b-a.length)/2),g=e-f;a=Array(g+1).join(c)+a+Array(f+1).join(c);break;default:a+=Array(b+1-a.length).join(c)}return a},isPlainObject:function(a){if("object"!=typeof a||a.nodeType||a===a.window)return!1;try{if(a.constructor&&!hasOwn.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(b){return!1}return!0},extend:function(){var a,b,c,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;for("boolean"==typeof h&&(k=h,h=arguments[1]||{},i=2),j===i&&(h=this,--i);j>i;i++)if(null!=(a=arguments[i]))for(b in a)c=h[b],e=a[b],h!==e&&(k&&e&&(d.Utils.isPlainObject(e)||(f=Array.isArray(e)))?(f?(f=!1,g=c&&Array.isArray(c)?c:[]):g=c&&d.Utils.isPlainObject(c)?c:{},h[b]=d.Utils.extend(k,g,e)):void 0!==e&&(h[b]=e));return h}},function(){var a=!1;a&&(window.console=void 0),void 0===window.console&&(window.console={debug:function(){return!0},info:function(){return!1},warn:function(){return!1},log:function(){return!1}}),debug=function(a){window.console.debug(a)},info=function(a){window.console.info(a)},warn=function(a){window.console.warn(a)},log=function(a){window.console.log(a)}}(),"function"!=typeof Function.prototype.bind&&(Function.prototype.bind=function(){var a=Array.prototype.slice;return function(b){function c(){var f=e.concat(a.call(arguments));d.apply(this instanceof c?this:b,f)}var d=this,e=a.call(arguments,1);if("function"!=typeof d)throw new TypeError;return c.prototype=function f(a){return a&&(f.prototype=a),this instanceof f?void 0:new f}(d.prototype),c}}()),b(),c.mat3={},c.mat3.create=function(){var a=new c.Matrix(9);return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=1,a[5]=0,a[6]=0,a[7]=0,a[8]=1,a},c.mat3.identity=function(a){return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=1,a[5]=0,a[6]=0,a[7]=0,a[8]=1,a},c.mat4={},c.mat4.create=function(){var a=new c.Matrix(16);return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=1,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1,a},c.mat3.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],f=a[2],g=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],m=b[0],n=b[1],o=b[2],p=b[3],q=b[4],r=b[5],s=b[6],t=b[7],u=b[8];return c[0]=m*d+n*g+o*j,c[1]=m*e+n*h+o*k,c[2]=m*f+n*i+o*l,c[3]=p*d+q*g+r*j,c[4]=p*e+q*h+r*k,c[5]=p*f+q*i+r*l,c[6]=s*d+t*g+u*j,c[7]=s*e+t*h+u*k,c[8]=s*f+t*i+u*l,c},c.mat3.clone=function(a){var b=new c.Matrix(9);return b[0]=a[0],b[1]=a[1],b[2]=a[2],b[3]=a[3],b[4]=a[4],b[5]=a[5],b[6]=a[6],b[7]=a[7],b[8]=a[8],b},c.mat3.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[5];return a[1]=a[3],a[2]=a[6],a[3]=c,a[5]=a[7],a[6]=d,a[7]=e,a}return b[0]=a[0],b[1]=a[3],b[2]=a[6],b[3]=a[1],b[4]=a[4],b[5]=a[7],b[6]=a[2],b[7]=a[5],b[8]=a[8],b},c.mat3.toMat4=function(a,b){return b||(b=c.mat4.create()),b[15]=1,b[14]=0,b[13]=0,b[12]=0,b[11]=0,b[10]=a[8],b[9]=a[7],b[8]=a[6],b[7]=0,b[6]=a[5],b[5]=a[4],b[4]=a[3],b[3]=0,b[2]=a[2],b[1]=a[1],b[0]=a[0],b},c.mat4.create=function(){var a=new c.Matrix(16);return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=1,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1,a},c.mat4.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[3],f=a[6],g=a[7],h=a[11];return a[1]=a[4],a[2]=a[8],a[3]=a[12],a[4]=c,a[6]=a[9],a[7]=a[13],a[8]=d,a[9]=f,a[11]=a[14],a[12]=e,a[13]=g,a[14]=h,a}return b[0]=a[0],b[1]=a[4],b[2]=a[8],b[3]=a[12],b[4]=a[1],b[5]=a[5],b[6]=a[9],b[7]=a[13],b[8]=a[2],b[9]=a[6],b[10]=a[10],b[11]=a[14],b[12]=a[3],b[13]=a[7],b[14]=a[11],b[15]=a[15],b},c.mat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],f=a[2],g=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],m=a[9],n=a[10],o=a[11],p=a[12],q=a[13],r=a[14],s=a[15],t=b[0],u=b[1],v=b[2],w=b[3];return c[0]=t*d+u*h+v*l+w*p,c[1]=t*e+u*i+v*m+w*q,c[2]=t*f+u*j+v*n+w*r,c[3]=t*g+u*k+v*o+w*s,t=b[4],u=b[5],v=b[6],w=b[7],c[4]=t*d+u*h+v*l+w*p,c[5]=t*e+u*i+v*m+w*q,c[6]=t*f+u*j+v*n+w*r,c[7]=t*g+u*k+v*o+w*s,t=b[8],u=b[9],v=b[10],w=b[11],c[8]=t*d+u*h+v*l+w*p,c[9]=t*e+u*i+v*m+w*q,c[10]=t*f+u*j+v*n+w*r,c[11]=t*g+u*k+v*o+w*s,t=b[12],u=b[13],v=b[14],w=b[15],c[12]=t*d+u*h+v*l+w*p,c[13]=t*e+u*i+v*m+w*q,c[14]=t*f+u*j+v*n+w*r,c[15]=t*g+u*k+v*o+w*s,c},c.Point=function(a,b){this.x=a||0,this.y=b||0},c.Point.prototype.clone=function(){return new c.Point(this.x,this.y)},c.Point.prototype.constructor=c.Point,c.Rectangle=function(a,b,c,d){this.x=a||0,this.y=b||0,this.width=c||0,this.height=d||0},c.Rectangle.prototype.clone=function(){return new c.Rectangle(this.x,this.y,this.width,this.height)},c.Rectangle.prototype.contains=function(a,b){if(this.width<=0||this.height<=0)return!1;var c=this.x;if(a>=c&&a<=c+this.width){var d=this.y;if(b>=d&&b<=d+this.height)return!0}return!1},c.Rectangle.prototype.constructor=c.Rectangle,c.Polygon=function(a){if(a instanceof Array||(a=Array.prototype.slice.call(arguments)),"number"==typeof a[0]){for(var b=[],d=0,e=a.length;e>d;d+=2)b.push(new c.Point(a[d],a[d+1]));a=b}this.points=a},c.Polygon.prototype.clone=function(){for(var a=[],b=0;bb!=i>b&&(h-f)*(b-g)/(i-g)+f>a;j&&(c=!c)}return c},c.Polygon.prototype.constructor=c.Polygon,c.DisplayObject=function(){this.last=this,this.first=this,this.position=new c.Point,this.scale=new c.Point(1,1),this.pivot=new c.Point(0,0),this.rotation=0,this.alpha=1,this.visible=!0,this.hitArea=null,this.buttonMode=!1,this.renderable=!1,this.parent=null,this.stage=null,this.worldAlpha=1,this._interactive=!1,this.worldTransform=c.mat3.create(),this.localTransform=c.mat3.create(),this.color=[],this.dynamic=!0,this._sr=0,this._cr=1,this.filterArea=new c.Rectangle(0,0,1,1)},c.DisplayObject.prototype.constructor=c.DisplayObject,c.DisplayObject.prototype.setInteractive=function(a){this.interactive=a},Object.defineProperty(c.DisplayObject.prototype,"interactive",{get:function(){return this._interactive},set:function(a){this._interactive=a,this.stage&&(this.stage.dirty=!0)}}),Object.defineProperty(c.DisplayObject.prototype,"mask",{get:function(){return this._mask},set:function(a){a?this._mask?(a.start=this._mask.start,a.end=this._mask.end):(this.addFilter(a),a.renderable=!1):(this.removeFilter(this._mask),this._mask.renderable=!0),this._mask=a}}),Object.defineProperty(c.DisplayObject.prototype,"filters",{get:function(){return this._filters},set:function(a){if(a){this._filters&&this.removeFilter(this._filters),this.addFilter(a);for(var b=[],c=0;c=0&&b<=this.children.length))throw new Error(a+" The index "+b+" supplied is out of bounds "+this.children.length);if(void 0!=a.parent&&a.parent.removeChild(a),a.parent=this,this.stage){var c=a;do c.interactive&&(this.stage.dirty=!0),c.stage=this.stage,c=c._iNext;while(c)}var d,e,f=a.first,g=a.last;if(b==this.children.length){e=this.last;for(var h=this,i=this.last;h;)h.last==i&&(h.last=a.last),h=h.parent}else e=0===b?this:this.children[b-1].last;d=e._iNext,d&&(d._iPrev=g,g._iNext=d),f._iPrev=e,e._iNext=f,this.children.splice(b,0,a),this.__renderGroup&&(a.__renderGroup&&a.__renderGroup.removeDisplayObjectAndChildren(a),this.__renderGroup.addDisplayObjectAndChildren(a))},c.DisplayObjectContainer.prototype.swapChildren=function(){},c.DisplayObjectContainer.prototype.getChildAt=function(a){if(a>=0&&aa;a++)this.children[a].updateTransform()}},c.blendModes={},c.blendModes.NORMAL=0,c.blendModes.SCREEN=1,c.Sprite=function(a){c.DisplayObjectContainer.call(this),this.anchor=new c.Point,this.texture=a,this.blendMode=c.blendModes.NORMAL,this._width=0,this._height=0,a.baseTexture.hasLoaded?this.updateFrame=!0:(this.onTextureUpdateBind=this.onTextureUpdate.bind(this),this.texture.addEventListener("update",this.onTextureUpdateBind)),this.renderable=!0},c.Sprite.prototype=Object.create(c.DisplayObjectContainer.prototype),c.Sprite.prototype.constructor=c.Sprite,Object.defineProperty(c.Sprite.prototype,"width",{get:function(){return this.scale.x*this.texture.frame.width},set:function(a){this.scale.x=a/this.texture.frame.width,this._width=a}}),Object.defineProperty(c.Sprite.prototype,"height",{get:function(){return this.scale.y*this.texture.frame.height},set:function(a){this.scale.y=a/this.texture.frame.height,this._height=a}}),c.Sprite.prototype.setTexture=function(a){this.texture.baseTexture!=a.baseTexture?(this.textureChange=!0,this.texture=a,this.__renderGroup&&this.__renderGroup.updateTexture(this)):this.texture=a,this.updateFrame=!0},c.Sprite.prototype.onTextureUpdate=function(){this._width&&(this.scale.x=this._width/this.texture.frame.width),this._height&&(this.scale.y=this._height/this.texture.frame.height),this.updateFrame=!0},c.Sprite.fromFrame=function(a){var b=c.TextureCache[a];if(!b)throw new Error("The frameId '"+a+"' does not exist in the texture cache"+this);return new c.Sprite(b)},c.Sprite.fromImage=function(a){var b=c.Texture.fromImage(a);return new c.Sprite(b)},c.Stage=function(a){c.DisplayObjectContainer.call(this),this.worldTransform=c.mat3.create(),this.interactive=!0,this.interactionManager=new c.InteractionManager(this),this.dirty=!0,this.__childrenAdded=[],this.__childrenRemoved=[],this.stage=this,this.stage.hitArea=new c.Rectangle(0,0,1e5,1e5),this.setBackgroundColor(a),this.worldVisible=!0},c.Stage.prototype=Object.create(c.DisplayObjectContainer.prototype),c.Stage.prototype.constructor=c.Stage,c.Stage.prototype.setInteractionDelegate=function(a){this.interactionManager.setTargetDomElement(a)},c.Stage.prototype.updateTransform=function(){this.worldAlpha=1,this.vcount=c.visibleCount;for(var a=0,b=this.children.length;b>a;a++)this.children[a].updateTransform();this.dirty&&(this.dirty=!1,this.interactionManager.dirty=!0),this.interactive&&this.interactionManager.update()},c.Stage.prototype.setBackgroundColor=function(b){this.backgroundColor=b||0,this.backgroundColorSplit=a(this.backgroundColor);var c=this.backgroundColor.toString(16);c="000000".substr(0,6-c.length)+c,this.backgroundColorString="#"+c},c.Stage.prototype.getMousePosition=function(){return this.interactionManager.mouse.global},c.CustomRenderable=function(){c.DisplayObject.call(this),this.renderable=!0},c.CustomRenderable.prototype=Object.create(c.DisplayObject.prototype),c.CustomRenderable.prototype.constructor=c.CustomRenderable,c.CustomRenderable.prototype.renderCanvas=function(){},c.CustomRenderable.prototype.initWebGL=function(){},c.CustomRenderable.prototype.renderWebGL=function(){},c.Strip=function(a,b,d){c.DisplayObjectContainer.call(this),this.texture=a,this.blendMode=c.blendModes.NORMAL;try{this.uvs=new Float32Array([0,1,1,1,1,0,0,1]),this.verticies=new Float32Array([0,0,0,0,0,0,0,0,0]),this.colors=new Float32Array([1,1,1,1]),this.indices=new Uint16Array([0,1,2,3])}catch(e){this.uvs=[0,1,1,1,1,0,0,1],this.verticies=[0,0,0,0,0,0,0,0,0],this.colors=[1,1,1,1],this.indices=[0,1,2,3]}this.width=b,this.height=d,a.baseTexture.hasLoaded?(this.width=this.texture.frame.width,this.height=this.texture.frame.height,this.updateFrame=!0):(this.onTextureUpdateBind=this.onTextureUpdate.bind(this),this.texture.addEventListener("update",this.onTextureUpdateBind)),this.renderable=!0},c.Strip.prototype=Object.create(c.DisplayObjectContainer.prototype),c.Strip.prototype.constructor=c.Strip,c.Strip.prototype.setTexture=function(a){this.texture=a,this.width=a.frame.width,this.height=a.frame.height,this.updateFrame=!0},c.Strip.prototype.onTextureUpdate=function(){this.updateFrame=!0},c.Rope=function(a,b){c.Strip.call(this,a),this.points=b;try{this.verticies=new Float32Array(4*b.length),this.uvs=new Float32Array(4*b.length),this.colors=new Float32Array(2*b.length),this.indices=new Uint16Array(2*b.length)}catch(d){this.verticies=verticies,this.uvs=uvs,this.colors=colors,this.indices=indices}this.refresh()},c.Rope.prototype=Object.create(c.Strip.prototype),c.Rope.prototype.constructor=c.Rope,c.Rope.prototype.refresh=function(){var a=this.points;if(!(a.length<1)){var b=this.uvs,c=this.indices,d=this.colors,e=a[0],f=a[0];this.count-=.2,b[0]=0,b[1]=1,b[2]=0,b[3]=1,d[0]=1,d[1]=1,c[0]=0,c[1]=1;for(var g=a.length,h=1;g>h;h++){var f=a[h],i=4*h,j=h/(g-1);h%2?(b[i]=j,b[i+1]=0,b[i+2]=j,b[i+3]=1):(b[i]=j,b[i+1]=0,b[i+2]=j,b[i+3]=1),i=2*h,d[i]=1,d[i+1]=1,i=2*h,c[i]=i,c[i+1]=i+1,e=f}}},c.Rope.prototype.updateTransform=function(){var a=this.points;if(!(a.length<1)){var b,d=this.verticies,e=a[0],f={x:0,y:0},g=a[0];this.count-=.2,d[0]=g.x+f.x,d[1]=g.y+f.y,d[2]=g.x-f.x,d[3]=g.y-f.y;for(var h=a.length,i=1;h>i;i++){var g=a[i],j=4*i;b=i1&&(k=1);var l=Math.sqrt(f.x*f.x+f.y*f.y),m=this.texture.height/2;f.x/=l,f.y/=l,f.x*=m,f.y*=m,d[j]=g.x+f.x,d[j+1]=g.y+f.y,d[j+2]=g.x-f.x,d[j+3]=g.y-f.y,e=g}c.DisplayObjectContainer.prototype.updateTransform.call(this)}},c.Rope.prototype.setTexture=function(a){this.texture=a,this.updateFrame=!0},c.TilingSprite=function(a,b,d){c.DisplayObjectContainer.call(this),this.texture=a,this.width=b,this.height=d,this.tileScale=new c.Point(1,1),this.tilePosition=new c.Point(0,0),this.renderable=!0,this.blendMode=c.blendModes.NORMAL},c.TilingSprite.prototype=Object.create(c.DisplayObjectContainer.prototype),c.TilingSprite.prototype.constructor=c.TilingSprite,c.TilingSprite.prototype.setTexture=function(a){this.texture=a,this.updateFrame=!0},c.TilingSprite.prototype.onTextureUpdate=function(){this.updateFrame=!0},c.AbstractFilter=function(a,b){this.passes=[this],this.dirty=!0,this.padding=0,this.uniforms=b||{},this.fragmentSrc=a||[]},c.FilterBlock=function(){this.visible=!0,this.renderable=!0},c.Graphics=function(){c.DisplayObjectContainer.call(this),this.renderable=!0,this.fillAlpha=1,this.lineWidth=0,this.lineColor="black",this.graphicsData=[],this.currentPath={points:[]}},c.Graphics.prototype=Object.create(c.DisplayObjectContainer.prototype),c.Graphics.prototype.constructor=c.Graphics,c.Graphics.prototype.lineStyle=function(a,b,d){0===this.currentPath.points.length&&this.graphicsData.pop(),this.lineWidth=a||0,this.lineColor=b||0,this.lineAlpha=void 0==d?1:d,this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[],type:c.Graphics.POLY},this.graphicsData.push(this.currentPath)},c.Graphics.prototype.moveTo=function(a,b){0===this.currentPath.points.length&&this.graphicsData.pop(),this.currentPath=this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[],type:c.Graphics.POLY},this.currentPath.points.push(a,b),this.graphicsData.push(this.currentPath)},c.Graphics.prototype.lineTo=function(a,b){this.currentPath.points.push(a,b),this.dirty=!0},c.Graphics.prototype.beginFill=function(a,b){this.filling=!0,this.fillColor=a||0,this.fillAlpha=void 0==b?1:b},c.Graphics.prototype.endFill=function(){this.filling=!1,this.fillColor=null,this.fillAlpha=1},c.Graphics.prototype.drawRect=function(a,b,d,e){0===this.currentPath.points.length&&this.graphicsData.pop(),this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[a,b,d,e],type:c.Graphics.RECT},this.graphicsData.push(this.currentPath),this.dirty=!0},c.Graphics.prototype.drawCircle=function(a,b,d){0===this.currentPath.points.length&&this.graphicsData.pop(),this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[a,b,d,d],type:c.Graphics.CIRC},this.graphicsData.push(this.currentPath),this.dirty=!0},c.Graphics.prototype.drawElipse=function(a,b,d,e){0===this.currentPath.points.length&&this.graphicsData.pop(),this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[a,b,d,e],type:c.Graphics.ELIP},this.graphicsData.push(this.currentPath),this.dirty=!0},c.Graphics.prototype.clear=function(){this.lineWidth=0,this.filling=!1,this.dirty=!0,this.clearDirty=!0,this.graphicsData=[],this.bounds=null},c.Graphics.prototype.updateFilterBounds=function(){if(!this.bounds){for(var a,b,d,e=1/0,f=-1/0,g=1/0,h=-1/0,i=0;ib?b:e,f=b+m>f?b+m:f,g=g>d?b:g,h=d+n>h?d+n:h}else if(k===c.Graphics.CIRC||k===c.Graphics.ELIP){b=a.x,d=a.y;var o=a.radius+l/2;e=e>b-o?b-o:e,f=b+o>f?b+o:f,g=g>d-o?d-o:g,h=d+o>h?d+o:h}else for(var p=0;pb-l?b-l:e,f=b+l>f?b+l:f,g=g>d-l?d-l:g,h=d+l>h?d+l:h}this.bounds=new c.Rectangle(e,g,f-e,h-g)}},c.Graphics.POLY=0,c.Graphics.RECT=1,c.Graphics.CIRC=2,c.Graphics.ELIP=3,c.CanvasGraphics=function(){},c.CanvasGraphics.renderGraphics=function(a,b){for(var d=a.worldAlpha,e=0;e1&&(d=1,console.log("Pixi.js warning: masks in canvas can only mask using the first path in the graphics object"));for(var e=0;1>e;e++){var f=a.graphicsData[e],g=f.points;if(f.type==c.Graphics.POLY){b.beginPath(),b.moveTo(g[0],g[1]);for(var h=1;h0&&(c.Texture.frameUpdates=[])},c.CanvasRenderer.prototype.resize=function(a,b){this.width=a,this.height=b,this.view.width=a,this.view.height=b},c.CanvasRenderer.prototype.renderDisplayObject=function(a){var b,d=this.context;d.globalCompositeOperation="source-over";var e=a.last._iNext;a=a.first;do if(b=a.worldTransform,a.visible)if(a.renderable){if(a instanceof c.Sprite){var f=a.texture.frame;f&&f.width&&f.height&&(d.globalAlpha=a.worldAlpha,d.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]),d.drawImage(a.texture.baseTexture.source,f.x,f.y,f.width,f.height,a.anchor.x*-f.width,a.anchor.y*-f.height,f.width,f.height))}else if(a instanceof c.Strip)d.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]),this.renderStrip(a);else if(a instanceof c.TilingSprite)d.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]),this.renderTilingSprite(a);else if(a instanceof c.CustomRenderable)d.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]),a.renderCanvas(this);else if(a instanceof c.Graphics)d.setTransform(b[0],b[3],b[1],b[4],b[2],b[5]),c.CanvasGraphics.renderGraphics(a,d);else if(a instanceof c.FilterBlock&&a.data instanceof c.Graphics){var g=a.data;if(a.open){d.save();var h=g.alpha,i=g.worldTransform;d.setTransform(i[0],i[3],i[1],i[4],i[2],i[5]),g.worldAlpha=.5,d.worldAlpha=0,c.CanvasGraphics.renderGraphicsMask(g,d),d.clip(),g.worldAlpha=h}else d.restore()}a=a._iNext}else a=a._iNext;else a=a.last._iNext;while(a!=e)},c.CanvasRenderer.prototype.renderStripFlat=function(a){var b=this.context,c=a.verticies;a.uvs;var d=c.length/2;this.count++,b.beginPath();for(var e=1;d-2>e;e++){var f=2*e,g=c[f],h=c[f+2],i=c[f+4],j=c[f+1],k=c[f+3],l=c[f+5];b.moveTo(g,j),b.lineTo(h,k),b.lineTo(i,l)}b.fillStyle="#FF0000",b.fill(),b.closePath()},c.CanvasRenderer.prototype.renderTilingSprite=function(a){var b=this.context;b.globalAlpha=a.worldAlpha,a.__tilePattern||(a.__tilePattern=b.createPattern(a.texture.baseTexture.source,"repeat")),b.beginPath();var c=a.tilePosition,d=a.tileScale;b.scale(d.x,d.y),b.translate(c.x,c.y),b.fillStyle=a.__tilePattern,b.fillRect(-c.x,-c.y,a.width/d.x,a.height/d.y),b.scale(1/d.x,1/d.y),b.translate(-c.x,-c.y),b.closePath()},c.CanvasRenderer.prototype.renderStrip=function(a){var b=this.context,c=a.verticies,d=a.uvs,e=c.length/2;this.count++;for(var f=1;e-2>f;f++){var g=2*f,h=c[g],i=c[g+2],j=c[g+4],k=c[g+1],l=c[g+3],m=c[g+5],n=d[g]*a.texture.width,o=d[g+2]*a.texture.width,p=d[g+4]*a.texture.width,q=d[g+1]*a.texture.height,r=d[g+3]*a.texture.height,s=d[g+5]*a.texture.height;b.save(),b.beginPath(),b.moveTo(h,k),b.lineTo(i,l),b.lineTo(j,m),b.closePath(),b.clip();var t=n*r+q*p+o*s-r*p-q*o-n*s,u=h*r+q*j+i*s-r*j-q*i-h*s,v=n*i+h*p+o*j-i*p-h*o-n*j,w=n*r*j+q*i*p+h*o*s-h*r*p-q*o*j-n*i*s,x=k*r+q*m+l*s-r*m-q*l-k*s,y=n*l+k*p+o*m-l*p-k*o-n*m,z=n*r*m+q*l*p+k*o*s-k*r*p-q*o*m-n*l*s;b.transform(u/t,x/t,v/t,y/t,w/t,z/t),b.drawImage(a.texture.baseTexture.source,0,0),b.restore()}},c.PixiShader=function(){this.program,this.fragmentSrc=["precision lowp float;","varying vec2 vTextureCoord;","varying float vColor;","uniform sampler2D uSampler;","void main(void) {","gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;","}"],this.textureCount=0},c.PixiShader.prototype.init=function(){var a=c.compileProgram(this.vertexSrc||c.PixiShader.defaultVertexSrc,this.fragmentSrc),b=c.gl;b.useProgram(a),this.uSampler=b.getUniformLocation(a,"uSampler"),this.projectionVector=b.getUniformLocation(a,"projectionVector"),this.offsetVector=b.getUniformLocation(a,"offsetVector"),this.dimensions=b.getUniformLocation(a,"dimensions"),this.aVertexPosition=b.getAttribLocation(a,"aVertexPosition"),this.colorAttribute=b.getAttribLocation(a,"aColor"),this.aTextureCoord=b.getAttribLocation(a,"aTextureCoord");for(var d in this.uniforms)this.uniforms[d].uniformLocation=b.getUniformLocation(a,d);this.initUniforms(),this.program=a},c.PixiShader.prototype.initUniforms=function(){this.textureCount=1;var a;for(var b in this.uniforms){var a=this.uniforms[b],d=a.type;"sampler2D"==d?(a._init=!1,null!==a.value&&this.initSampler2D(a)):"mat2"==d||"mat3"==d||"mat4"==d?(a.glMatrix=!0,a.glValueLength=1,"mat2"==d?a.glFunc=c.gl.uniformMatrix2fv:"mat3"==d?a.glFunc=c.gl.uniformMatrix3fv:"mat4"==d&&(a.glFunc=c.gl.uniformMatrix4fv)):(a.glFunc=c.gl["uniform"+d],a.glValueLength="2f"==d||"2i"==d?2:"3f"==d||"3i"==d?3:"4f"==d||"4i"==d?4:1)}},c.PixiShader.prototype.initSampler2D=function(a){if(a.value&&a.value.baseTexture&&a.value.baseTexture.hasLoaded){if(c.gl.activeTexture(c.gl["TEXTURE"+this.textureCount]),c.gl.bindTexture(c.gl.TEXTURE_2D,a.value.baseTexture._glTexture),a.textureData){var b=a.textureData,d=b.magFilter?b.magFilter:c.gl.LINEAR,e=b.minFilter?b.minFilter:c.gl.LINEAR,f=b.wrapS?b.wrapS:c.gl.CLAMP_TO_EDGE,g=b.wrapT?b.wrapT:c.gl.CLAMP_TO_EDGE,h=b.luminance?c.gl.LUMINANCE:c.gl.RGBA;if(b.repeat&&(f=c.gl.REPEAT,g=c.gl.REPEAT),c.gl.pixelStorei(c.gl.UNPACK_FLIP_Y_WEBGL,!1),b.width){var i=b.width?b.width:512,j=b.height?b.height:2,k=b.border?b.border:0;c.gl.texImage2D(c.gl.TEXTURE_2D,0,h,i,j,k,h,c.gl.UNSIGNED_BYTE,null)}else c.gl.texImage2D(c.gl.TEXTURE_2D,0,h,c.gl.RGBA,c.gl.UNSIGNED_BYTE,a.value.baseTexture.source);c.gl.texParameteri(c.gl.TEXTURE_2D,c.gl.TEXTURE_MAG_FILTER,d),c.gl.texParameteri(c.gl.TEXTURE_2D,c.gl.TEXTURE_MIN_FILTER,e),c.gl.texParameteri(c.gl.TEXTURE_2D,c.gl.TEXTURE_WRAP_S,f),c.gl.texParameteri(c.gl.TEXTURE_2D,c.gl.TEXTURE_WRAP_T,g)}c.gl.uniform1i(a.uniformLocation,this.textureCount),a._init=!0,this.textureCount++}},c.PixiShader.prototype.syncUniforms=function(){this.textureCount=1;var a;for(var b in this.uniforms)a=this.uniforms[b],1==a.glValueLength?a.glMatrix===!0?a.glFunc.call(c.gl,a.uniformLocation,a.transpose,a.value):a.glFunc.call(c.gl,a.uniformLocation,a.value):2==a.glValueLength?a.glFunc.call(c.gl,a.uniformLocation,a.value.x,a.value.y):3==a.glValueLength?a.glFunc.call(c.gl,a.uniformLocation,a.value.x,a.value.y,a.value.z):4==a.glValueLength?a.glFunc.call(c.gl,a.uniformLocation,a.value.x,a.value.y,a.value.z,a.value.w):"sampler2D"==a.type&&(a._init?(c.gl.activeTexture(c.gl["TEXTURE"+this.textureCount]),c.gl.bindTexture(c.gl.TEXTURE_2D,a.value.baseTexture._glTexture),c.gl.uniform1i(a.uniformLocation,this.textureCount),this.textureCount++):this.initSampler2D(a))},c.PixiShader.defaultVertexSrc=["attribute vec2 aVertexPosition;","attribute vec2 aTextureCoord;","attribute float aColor;","uniform vec2 projectionVector;","uniform vec2 offsetVector;","varying vec2 vTextureCoord;","varying float vColor;","const vec2 center = vec2(-1.0, 1.0);","void main(void) {","gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);","vTextureCoord = aTextureCoord;","vColor = aColor;","}"],c.PrimitiveShader=function(){this.program,this.fragmentSrc=["precision mediump float;","varying vec4 vColor;","void main(void) {","gl_FragColor = vColor;","}"],this.vertexSrc=["attribute vec2 aVertexPosition;","attribute vec4 aColor;","uniform mat3 translationMatrix;","uniform vec2 projectionVector;","uniform vec2 offsetVector;","uniform float alpha;","varying vec4 vColor;","void main(void) {","vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);","v -= offsetVector.xyx;","gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);","vColor = aColor * alpha;","}"] -},c.PrimitiveShader.prototype.init=function(){var a=c.compileProgram(this.vertexSrc,this.fragmentSrc),b=c.gl;b.useProgram(a),this.projectionVector=b.getUniformLocation(a,"projectionVector"),this.offsetVector=b.getUniformLocation(a,"offsetVector"),this.aVertexPosition=b.getAttribLocation(a,"aVertexPosition"),this.colorAttribute=b.getAttribLocation(a,"aColor"),this.translationMatrix=b.getUniformLocation(a,"translationMatrix"),this.alpha=b.getUniformLocation(a,"alpha"),this.program=a},c.StripShader=function(){this.program,this.fragmentSrc=["precision mediump float;","varying vec2 vTextureCoord;","varying float vColor;","uniform float alpha;","uniform sampler2D uSampler;","void main(void) {","gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));","gl_FragColor = gl_FragColor * alpha;","}"],this.vertexSrc=["attribute vec2 aVertexPosition;","attribute vec2 aTextureCoord;","attribute float aColor;","uniform mat3 translationMatrix;","uniform vec2 projectionVector;","varying vec2 vTextureCoord;","varying vec2 offsetVector;","varying float vColor;","void main(void) {","vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);","v -= offsetVector.xyx;","gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);","vTextureCoord = aTextureCoord;","vColor = aColor;","}"]},c.StripShader.prototype.init=function(){var a=c.compileProgram(this.vertexSrc,this.fragmentSrc),b=c.gl;b.useProgram(a),this.uSampler=b.getUniformLocation(a,"uSampler"),this.projectionVector=b.getUniformLocation(a,"projectionVector"),this.offsetVector=b.getUniformLocation(a,"offsetVector"),this.colorAttribute=b.getAttribLocation(a,"aColor"),this.aVertexPosition=b.getAttribLocation(a,"aVertexPosition"),this.aTextureCoord=b.getAttribLocation(a,"aTextureCoord"),this.translationMatrix=b.getUniformLocation(a,"translationMatrix"),this.alpha=b.getUniformLocation(a,"alpha"),this.program=a},c._batchs=[],c._getBatch=function(a){return 0===c._batchs.length?new c.WebGLBatch(a):c._batchs.pop()},c._returnBatch=function(a){a.clean(),c._batchs.push(a)},c._restoreBatchs=function(a){for(var b=0;bc;c++){var d=6*c,e=4*c;this.indices[d+0]=e+0,this.indices[d+1]=e+1,this.indices[d+2]=e+2,this.indices[d+3]=e+0,this.indices[d+4]=e+2,this.indices[d+5]=e+3}a.bindBuffer(a.ELEMENT_ARRAY_BUFFER,this.indexBuffer),a.bufferData(a.ELEMENT_ARRAY_BUFFER,this.indices,a.STATIC_DRAW)},c.WebGLBatch.prototype.refresh=function(){this.gl,this.dynamicSizethis.width&&(f.width=this.width),f.y<0&&(f.y=0),f.height>this.height&&(f.height=this.height),b.bindFramebuffer(b.FRAMEBUFFER,e.frameBuffer),b.viewport(0,0,f.width,f.height),c.projection.x=f.width/2,c.projection.y=-f.height/2,c.offset.x=-f.x,c.offset.y=-f.y,b.uniform2f(c.defaultShader.projectionVector,f.width/2,-f.height/2),b.uniform2f(c.defaultShader.offsetVector,-f.x,-f.y),b.colorMask(!0,!0,!0,!0),b.clearColor(0,0,0,0),b.clear(b.COLOR_BUFFER_BIT),a._glFilterTexture=e},c.WebGLFilterManager.prototype.popFilter=function(){var a=c.gl,b=this.filterStack.pop(),d=b.target.filterArea,e=b._glFilterTexture;if(b.filterPasses.length>1){a.viewport(0,0,d.width,d.height),a.bindBuffer(a.ARRAY_BUFFER,this.vertexBuffer),this.vertexArray[0]=0,this.vertexArray[1]=d.height,this.vertexArray[2]=d.width,this.vertexArray[3]=d.height,this.vertexArray[4]=0,this.vertexArray[5]=0,this.vertexArray[6]=d.width,this.vertexArray[7]=0,a.bufferSubData(a.ARRAY_BUFFER,0,this.vertexArray),a.bindBuffer(a.ARRAY_BUFFER,this.uvBuffer),this.uvArray[2]=d.width/this.width,this.uvArray[5]=d.height/this.height,this.uvArray[6]=d.width/this.width,this.uvArray[7]=d.height/this.height,a.bufferSubData(a.ARRAY_BUFFER,0,this.uvArray);var f=e,g=this.texturePool.pop();g||(g=new c.FilterTexture(this.width,this.height)),a.bindFramebuffer(a.FRAMEBUFFER,g.frameBuffer),a.clear(a.COLOR_BUFFER_BIT),a.disable(a.BLEND);for(var h=0;hs?s:E,E=E>t?t:E,E=E>u?u:E,E=E>v?v:E,F=F>w?w:F,F=F>x?x:F,F=F>y?y:F,F=F>z?z:F,C=s>C?s:C,C=t>C?t:C,C=u>C?u:C,C=v>C?v:C,D=w>D?w:D,D=x>D?x:D,D=y>D?y:D,D=z>D?z:D),l=!1,A=A._iNext}while(A!=B);a.filterArea.x=E,a.filterArea.y=F,a.filterArea.width=C-E,a.filterArea.height=D-F},c.FilterTexture=function(a,b){var d=c.gl;this.frameBuffer=d.createFramebuffer(),this.texture=d.createTexture(),d.bindTexture(d.TEXTURE_2D,this.texture),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_MAG_FILTER,d.LINEAR),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_MIN_FILTER,d.LINEAR),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_WRAP_S,d.CLAMP_TO_EDGE),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_WRAP_T,d.CLAMP_TO_EDGE),d.bindFramebuffer(d.FRAMEBUFFER,this.framebuffer),d.bindFramebuffer(d.FRAMEBUFFER,this.frameBuffer),d.framebufferTexture2D(d.FRAMEBUFFER,d.COLOR_ATTACHMENT0,d.TEXTURE_2D,this.texture,0),this.resize(a,b)},c.FilterTexture.prototype.resize=function(a,b){this.width=a,this.height=b;var d=c.gl;d.bindTexture(d.TEXTURE_2D,this.texture),d.texImage2D(d.TEXTURE_2D,0,d.RGBA,a,b,0,d.RGBA,d.UNSIGNED_BYTE,null)},c.WebGLGraphics=function(){},c.WebGLGraphics.renderGraphics=function(a,b){var d=c.gl;a._webGL||(a._webGL={points:[],indices:[],lastIndex:0,buffer:d.createBuffer(),indexBuffer:d.createBuffer()}),a.dirty&&(a.dirty=!1,a.clearDirty&&(a.clearDirty=!1,a._webGL.lastIndex=0,a._webGL.points=[],a._webGL.indices=[]),c.WebGLGraphics.updateGraphics(a)),c.activatePrimitiveShader();var e=c.mat3.clone(a.worldTransform);c.mat3.transpose(e),d.blendFunc(d.ONE,d.ONE_MINUS_SRC_ALPHA),d.uniformMatrix3fv(c.primitiveShader.translationMatrix,!1,e),d.uniform2f(c.primitiveShader.projectionVector,b.x,-b.y),d.uniform2f(c.primitiveShader.offsetVector,-c.offset.x,-c.offset.y),d.uniform1f(c.primitiveShader.alpha,a.worldAlpha),d.bindBuffer(d.ARRAY_BUFFER,a._webGL.buffer),d.vertexAttribPointer(c.primitiveShader.aVertexPosition,2,d.FLOAT,!1,24,0),d.vertexAttribPointer(c.primitiveShader.colorAttribute,4,d.FLOAT,!1,24,8),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,a._webGL.indexBuffer),d.drawElements(d.TRIANGLE_STRIP,a._webGL.indices.length,d.UNSIGNED_SHORT,0),c.deactivatePrimitiveShader()},c.WebGLGraphics.updateGraphics=function(a){for(var b=a._webGL.lastIndex;b3&&c.WebGLGraphics.buildPoly(d,a._webGL),d.lineWidth>0&&c.WebGLGraphics.buildLine(d,a._webGL)):d.type==c.Graphics.RECT?c.WebGLGraphics.buildRectangle(d,a._webGL):(d.type==c.Graphics.CIRC||d.type==c.Graphics.ELIP)&&c.WebGLGraphics.buildCircle(d,a._webGL)}a._webGL.lastIndex=a.graphicsData.length;var e=c.gl;a._webGL.glPoints=new Float32Array(a._webGL.points),e.bindBuffer(e.ARRAY_BUFFER,a._webGL.buffer),e.bufferData(e.ARRAY_BUFFER,a._webGL.glPoints,e.STATIC_DRAW),a._webGL.glIndicies=new Uint16Array(a._webGL.indices),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,a._webGL.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,a._webGL.glIndicies,e.STATIC_DRAW)},c.WebGLGraphics.buildRectangle=function(b,d){var e=b.points,f=e[0],g=e[1],h=e[2],i=e[3];if(b.fill){var j=a(b.fillColor),k=b.fillAlpha,l=j[0]*k,m=j[1]*k,n=j[2]*k,o=d.points,p=d.indices,q=o.length/6;o.push(f,g),o.push(l,m,n,k),o.push(f+h,g),o.push(l,m,n,k),o.push(f,g+i),o.push(l,m,n,k),o.push(f+h,g+i),o.push(l,m,n,k),p.push(q,q,q+1,q+2,q+3,q+3)}b.lineWidth&&(b.points=[f,g,f+h,g,f+h,g+i,f,g+i,f,g],c.WebGLGraphics.buildLine(b,d))},c.WebGLGraphics.buildCircle=function(b,d){var e=b.points,f=e[0],g=e[1],h=e[2],i=e[3],j=40,k=2*Math.PI/j;if(b.fill){var l=a(b.fillColor),m=b.fillAlpha,n=l[0]*m,o=l[1]*m,p=l[2]*m,q=d.points,r=d.indices,s=q.length/6;r.push(s);for(var t=0;j+1>t;t++)q.push(f,g,n,o,p,m),q.push(f+Math.sin(k*t)*h,g+Math.cos(k*t)*i,n,o,p,m),r.push(s++,s++);r.push(s-1)}if(b.lineWidth){b.points=[];for(var t=0;j+1>t;t++)b.points.push(f+Math.sin(k*t)*h,g+Math.cos(k*t)*i);c.WebGLGraphics.buildLine(b,d)}},c.WebGLGraphics.buildLine=function(b,d){var e=b.points;if(0!==e.length){if(b.lineWidth%2)for(var f=0;ff;f++)k=e[2*(f-1)],l=e[2*(f-1)+1],m=e[2*f],n=e[2*f+1],o=e[2*(f+1)],p=e[2*(f+1)+1],q=-(l-n),r=k-m,E=Math.sqrt(q*q+r*r),q/=E,r/=E,q*=K,r*=K,s=-(n-p),t=m-o,E=Math.sqrt(s*s+t*t),s/=E,t/=E,s*=K,t*=K,w=-r+l-(-r+n),x=-q+m-(-q+k),y=(-q+k)*(-r+n)-(-q+m)*(-r+l),z=-t+p-(-t+n),A=-s+m-(-s+o),B=(-s+o)*(-t+n)-(-s+m)*(-t+p),C=w*A-z*x,Math.abs(C)<.1?(C+=10.1,F.push(m-q,n-r,N,O,P,M),F.push(m+q,n+r,N,O,P,M)):(px=(x*B-A*y)/C,py=(z*y-w*B)/C,D=(px-m)*(px-m)+(py-n)+(py-n),D>19600?(u=q-s,v=r-t,E=Math.sqrt(u*u+v*v),u/=E,v/=E,u*=K,v*=K,F.push(m-u,n-v),F.push(N,O,P,M),F.push(m+u,n+v),F.push(N,O,P,M),F.push(m-u,n-v),F.push(N,O,P,M),I++):(F.push(px,py),F.push(N,O,P,M),F.push(m-(px-m),n-(py-n)),F.push(N,O,P,M)));k=e[2*(H-2)],l=e[2*(H-2)+1],m=e[2*(H-1)],n=e[2*(H-1)+1],q=-(l-n),r=k-m,E=Math.sqrt(q*q+r*r),q/=E,r/=E,q*=K,r*=K,F.push(m-q,n-r),F.push(N,O,P,M),F.push(m+q,n+r),F.push(N,O,P,M),G.push(J);for(var f=0;I>f;f++)G.push(J++);G.push(J-1)}},c.WebGLGraphics.buildPoly=function(b,d){var e=b.points;if(!(e.length<6)){for(var f=d.points,g=d.indices,h=e.length/2,i=a(b.fillColor),j=b.fillAlpha,k=i[0]*j,l=i[1]*j,m=i[2]*j,n=c.PolyK.Triangulate(e),o=f.length/6,p=0;pp;p++)f.push(e[2*p],e[2*p+1],k,l,m,j)}},c._defaultFrame=new c.Rectangle(0,0,1,1),c.gl,c.WebGLRenderer=function(a,b,d,e,f){this.transparent=!!e,this.width=a||800,this.height=b||600,this.view=d||document.createElement("canvas"),this.view.width=this.width,this.view.height=this.height;var g=this;this.view.addEventListener("webglcontextlost",function(a){g.handleContextLost(a)},!1),this.view.addEventListener("webglcontextrestored",function(a){g.handleContextRestored(a)},!1),this.batchs=[];var h={alpha:this.transparent,antialias:!!f,premultipliedAlpha:!1,stencil:!0};try{c.gl=this.gl=this.view.getContext("experimental-webgl",h)}catch(i){try{c.gl=this.gl=this.view.getContext("webgl",h)}catch(i){throw new Error(" This browser does not support webGL. Try using the canvas renderer"+this)}}c.initDefaultShaders();var j=this.gl;j.useProgram(c.defaultShader.program),c.WebGLRenderer.gl=j,this.batch=new c.WebGLBatch(j),j.disable(j.DEPTH_TEST),j.disable(j.CULL_FACE),j.enable(j.BLEND),j.colorMask(!0,!0,!0,this.transparent),c.projection=new c.Point(400,300),c.offset=new c.Point(0,0),this.resize(this.width,this.height),this.contextLost=!1,this.stageRenderGroup=new c.WebGLRenderGroup(this.gl,this.transparent)},c.WebGLRenderer.prototype.constructor=c.WebGLRenderer,c.WebGLRenderer.getBatch=function(){return 0===c._batchs.length?new c.WebGLBatch(c.WebGLRenderer.gl):c._batchs.pop()},c.WebGLRenderer.returnBatch=function(a){a.clean(),c._batchs.push(a)},c.WebGLRenderer.prototype.render=function(a){if(!this.contextLost){this.__stage!==a&&(this.__stage=a,this.stageRenderGroup.setRenderable(a)),c.WebGLRenderer.updateTextures(),c.visibleCount++,a.updateTransform();var b=this.gl;if(b.colorMask(!0,!0,!0,this.transparent),b.viewport(0,0,this.width,this.height),b.bindFramebuffer(b.FRAMEBUFFER,null),b.clearColor(a.backgroundColorSplit[0],a.backgroundColorSplit[1],a.backgroundColorSplit[2],!this.transparent),b.clear(b.COLOR_BUFFER_BIT),this.stageRenderGroup.backgroundColor=a.backgroundColorSplit,c.projection.x=this.width/2,c.projection.y=-this.height/2,this.stageRenderGroup.render(c.projection),a.interactive&&(a._interactiveEventsAdded||(a._interactiveEventsAdded=!0,a.interactionManager.setTarget(this))),c.Texture.frameUpdates.length>0){for(var d=0;dn;n++)renderable=this.batchs[n],renderable instanceof c.WebGLBatch?this.batchs[n].render():this.renderSpecial(renderable,b);endBatch instanceof c.WebGLBatch?endBatch.render(0,h+1):this.renderSpecial(endBatch,b)},c.WebGLRenderGroup.prototype.renderSpecial=function(a,b){var d=a.vcount===c.visibleCount;a instanceof c.TilingSprite?d&&this.renderTilingSprite(a,b):a instanceof c.Strip?d&&this.renderStrip(a,b):a instanceof c.CustomRenderable?d&&a.renderWebGL(this,b):a instanceof c.Graphics?d&&a.renderable&&c.WebGLGraphics.renderGraphics(a,b):a instanceof c.FilterBlock&&this.handleFilterBlock(a,b)},flip=!1;var e=[],f=0;return c.WebGLRenderGroup.prototype.handleFilterBlock=function(a,b){var d=c.gl;if(a.open)a.data instanceof Array?this.filterManager.pushFilter(a):(f++,e.push(a),d.enable(d.STENCIL_TEST),d.colorMask(!1,!1,!1,!1),d.stencilFunc(d.ALWAYS,1,1),d.stencilOp(d.KEEP,d.KEEP,d.INCR),c.WebGLGraphics.renderGraphics(a.data,b),d.colorMask(!0,!0,!0,!0),d.stencilFunc(d.NOTEQUAL,0,e.length),d.stencilOp(d.KEEP,d.KEEP,d.KEEP));else if(a.data instanceof Array)this.filterManager.popFilter();else{var g=e.pop(a);g&&(d.colorMask(!1,!1,!1,!1),d.stencilFunc(d.ALWAYS,1,1),d.stencilOp(d.KEEP,d.KEEP,d.DECR),c.WebGLGraphics.renderGraphics(g.data,b),d.colorMask(!0,!0,!0,!0),d.stencilFunc(d.NOTEQUAL,0,e.length),d.stencilOp(d.KEEP,d.KEEP,d.KEEP)),d.disable(d.STENCIL_TEST)}},c.WebGLRenderGroup.prototype.updateTexture=function(a){this.removeObject(a);for(var b=a.first;b!=this.root&&(b=b._iPrev,!b.renderable||!b.__renderGroup););for(var c=a.last;c._iNext&&(c=c._iNext,!c.renderable||!c.__renderGroup););this.insertObject(a,b,c)},c.WebGLRenderGroup.prototype.addFilterBlocks=function(a,b){a.__renderGroup=this,b.__renderGroup=this;for(var c=a;c!=this.root.first&&(c=c._iPrev,!c.renderable||!c.__renderGroup););this.insertAfter(a,c);for(var d=b;d!=this.root.first&&(d=d._iPrev,!d.renderable||!d.__renderGroup););this.insertAfter(b,d)},c.WebGLRenderGroup.prototype.removeFilterBlocks=function(a,b){this.removeObject(a),this.removeObject(b)},c.WebGLRenderGroup.prototype.addDisplayObjectAndChildren=function(a){a.__renderGroup&&a.__renderGroup.removeDisplayObjectAndChildren(a);for(var b=a.first;b!=this.root.first&&(b=b._iPrev,!b.renderable||!b.__renderGroup););for(var c=a.last;c._iNext&&(c=c._iNext,!c.renderable||!c.__renderGroup););var d=a.first,e=a.last._iNext;do d.__renderGroup=this,d.renderable&&(this.insertObject(d,b,c),b=d),d=d._iNext;while(d!=e)},c.WebGLRenderGroup.prototype.removeDisplayObjectAndChildren=function(a){if(a.__renderGroup==this){a.last;do a.__renderGroup=null,a.renderable&&this.removeObject(a),a=a._iNext;while(a)}},c.WebGLRenderGroup.prototype.insertObject=function(a,b,d){var e=b,f=d;if(a instanceof c.Sprite){var g,h;if(e instanceof c.Sprite){if(g=e.batch,g&&g.texture==a.texture.baseTexture&&g.blendMode==a.blendMode)return g.insertAfter(a,e),void 0}else g=e;if(f)if(f instanceof c.Sprite){if(h=f.batch){if(h.texture==a.texture.baseTexture&&h.blendMode==a.blendMode)return h.insertBefore(a,f),void 0;if(h==g){var i=g.split(f),j=c.WebGLRenderer.getBatch(),k=this.batchs.indexOf(g);return j.init(a),this.batchs.splice(k+1,0,j,i),void 0}}}else h=f;var j=c.WebGLRenderer.getBatch();if(j.init(a),g){var k=this.batchs.indexOf(g);this.batchs.splice(k+1,0,j)}else this.batchs.push(j)}else a instanceof c.TilingSprite?this.initTilingSprite(a):a instanceof c.Strip&&this.initStrip(a),this.insertAfter(a,e)},c.WebGLRenderGroup.prototype.insertAfter=function(a,b){if(b instanceof c.Sprite){var d=b.batch;if(d)if(d.tail==b){var e=this.batchs.indexOf(d);this.batchs.splice(e+1,0,a)}else{var f=d.split(b.__next),e=this.batchs.indexOf(d);this.batchs.splice(e+1,0,a,f)}else this.batchs.push(a)}else{var e=this.batchs.indexOf(b);this.batchs.splice(e+1,0,a)}},c.WebGLRenderGroup.prototype.removeObject=function(a){var b;if(a instanceof c.Sprite){var d=a.batch;if(!d)return;d.remove(a),0==d.size&&(b=d)}else b=a;if(b){var e=this.batchs.indexOf(b);if(-1==e)return;if(0===e||e==this.batchs.length-1)return this.batchs.splice(e,1),b instanceof c.WebGLBatch&&c.WebGLRenderer.returnBatch(b),void 0;if(this.batchs[e-1]instanceof c.WebGLBatch&&this.batchs[e+1]instanceof c.WebGLBatch&&this.batchs[e-1].texture==this.batchs[e+1].texture&&this.batchs[e-1].blendMode==this.batchs[e+1].blendMode)return this.batchs[e-1].merge(this.batchs[e+1]),b instanceof c.WebGLBatch&&c.WebGLRenderer.returnBatch(b),c.WebGLRenderer.returnBatch(this.batchs[e+1]),this.batchs.splice(e,2),void 0;this.batchs.splice(e,1),b instanceof c.WebGLBatch&&c.WebGLRenderer.returnBatch(b)}},c.WebGLRenderGroup.prototype.initTilingSprite=function(a){var b=this.gl;a.verticies=new Float32Array([0,0,a.width,0,a.width,a.height,0,a.height]),a.uvs=new Float32Array([0,0,1,0,1,1,0,1]),a.colors=new Float32Array([1,1,1,1]),a.indices=new Uint16Array([0,1,3,2]),a._vertexBuffer=b.createBuffer(),a._indexBuffer=b.createBuffer(),a._uvBuffer=b.createBuffer(),a._colorBuffer=b.createBuffer(),b.bindBuffer(b.ARRAY_BUFFER,a._vertexBuffer),b.bufferData(b.ARRAY_BUFFER,a.verticies,b.STATIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._uvBuffer),b.bufferData(b.ARRAY_BUFFER,a.uvs,b.DYNAMIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._colorBuffer),b.bufferData(b.ARRAY_BUFFER,a.colors,b.STATIC_DRAW),b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,a._indexBuffer),b.bufferData(b.ELEMENT_ARRAY_BUFFER,a.indices,b.STATIC_DRAW),a.texture.baseTexture._glTexture?(b.bindTexture(b.TEXTURE_2D,a.texture.baseTexture._glTexture),b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,b.REPEAT),b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.REPEAT),a.texture.baseTexture._powerOf2=!0):a.texture.baseTexture._powerOf2=!0},c.WebGLRenderGroup.prototype.renderStrip=function(a,b){var d=this.gl;c.activateStripShader();var e=c.stripShader;e.program;var f=c.mat3.clone(a.worldTransform);c.mat3.transpose(f),d.uniformMatrix3fv(e.translationMatrix,!1,f),d.uniform2f(e.projectionVector,b.x,b.y),d.uniform2f(e.offsetVector,-c.offset.x,-c.offset.y),d.uniform1f(e.alpha,a.worldAlpha),a.dirty?(a.dirty=!1,d.bindBuffer(d.ARRAY_BUFFER,a._vertexBuffer),d.bufferData(d.ARRAY_BUFFER,a.verticies,d.STATIC_DRAW),d.vertexAttribPointer(e.aVertexPosition,2,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,a._uvBuffer),d.bufferData(d.ARRAY_BUFFER,a.uvs,d.STATIC_DRAW),d.vertexAttribPointer(e.aTextureCoord,2,d.FLOAT,!1,0,0),d.activeTexture(d.TEXTURE0),d.bindTexture(d.TEXTURE_2D,a.texture.baseTexture._glTexture),d.bindBuffer(d.ARRAY_BUFFER,a._colorBuffer),d.bufferData(d.ARRAY_BUFFER,a.colors,d.STATIC_DRAW),d.vertexAttribPointer(e.colorAttribute,1,d.FLOAT,!1,0,0),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,a._indexBuffer),d.bufferData(d.ELEMENT_ARRAY_BUFFER,a.indices,d.STATIC_DRAW)):(d.bindBuffer(d.ARRAY_BUFFER,a._vertexBuffer),d.bufferSubData(d.ARRAY_BUFFER,0,a.verticies),d.vertexAttribPointer(e.aVertexPosition,2,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,a._uvBuffer),d.vertexAttribPointer(e.aTextureCoord,2,d.FLOAT,!1,0,0),d.activeTexture(d.TEXTURE0),d.bindTexture(d.TEXTURE_2D,a.texture.baseTexture._glTexture),d.bindBuffer(d.ARRAY_BUFFER,a._colorBuffer),d.vertexAttribPointer(e.colorAttribute,1,d.FLOAT,!1,0,0),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,a._indexBuffer)),d.drawElements(d.TRIANGLE_STRIP,a.indices.length,d.UNSIGNED_SHORT,0),c.deactivateStripShader() -},c.WebGLRenderGroup.prototype.renderTilingSprite=function(a,b){var d=this.gl;c.shaderProgram;var e=a.tilePosition,f=a.tileScale,g=e.x/a.texture.baseTexture.width,h=e.y/a.texture.baseTexture.height,i=a.width/a.texture.baseTexture.width/f.x,j=a.height/a.texture.baseTexture.height/f.y;a.uvs[0]=0-g,a.uvs[1]=0-h,a.uvs[2]=1*i-g,a.uvs[3]=0-h,a.uvs[4]=1*i-g,a.uvs[5]=1*j-h,a.uvs[6]=0-g,a.uvs[7]=1*j-h,d.bindBuffer(d.ARRAY_BUFFER,a._uvBuffer),d.bufferSubData(d.ARRAY_BUFFER,0,a.uvs),this.renderStrip(a,b)},c.WebGLRenderGroup.prototype.initStrip=function(a){var b=this.gl;this.shaderProgram,a._vertexBuffer=b.createBuffer(),a._indexBuffer=b.createBuffer(),a._uvBuffer=b.createBuffer(),a._colorBuffer=b.createBuffer(),b.bindBuffer(b.ARRAY_BUFFER,a._vertexBuffer),b.bufferData(b.ARRAY_BUFFER,a.verticies,b.DYNAMIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._uvBuffer),b.bufferData(b.ARRAY_BUFFER,a.uvs,b.STATIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._colorBuffer),b.bufferData(b.ARRAY_BUFFER,a.colors,b.STATIC_DRAW),b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,a._indexBuffer),b.bufferData(b.ELEMENT_ARRAY_BUFFER,a.indices,b.STATIC_DRAW)},c.initDefaultShaders=function(){c.primitiveShader=new c.PrimitiveShader,c.primitiveShader.init(),c.stripShader=new c.StripShader,c.stripShader.init(),c.defaultShader=new c.PixiShader,c.defaultShader.init();var a=c.gl,b=c.defaultShader.program;a.useProgram(b),a.enableVertexAttribArray(c.defaultShader.aVertexPosition),a.enableVertexAttribArray(c.defaultShader.colorAttribute),a.enableVertexAttribArray(c.defaultShader.aTextureCoord)},c.activatePrimitiveShader=function(){var a=c.gl;a.useProgram(c.primitiveShader.program),a.disableVertexAttribArray(c.defaultShader.aVertexPosition),a.disableVertexAttribArray(c.defaultShader.colorAttribute),a.disableVertexAttribArray(c.defaultShader.aTextureCoord),a.enableVertexAttribArray(c.primitiveShader.aVertexPosition),a.enableVertexAttribArray(c.primitiveShader.colorAttribute)},c.deactivatePrimitiveShader=function(){var a=c.gl;a.useProgram(c.defaultShader.program),a.disableVertexAttribArray(c.primitiveShader.aVertexPosition),a.disableVertexAttribArray(c.primitiveShader.colorAttribute),a.enableVertexAttribArray(c.defaultShader.aVertexPosition),a.enableVertexAttribArray(c.defaultShader.colorAttribute),a.enableVertexAttribArray(c.defaultShader.aTextureCoord)},c.activateStripShader=function(){var a=c.gl;a.useProgram(c.stripShader.program)},c.deactivateStripShader=function(){var a=c.gl;a.useProgram(c.defaultShader.program)},c.CompileVertexShader=function(a,b){return c._CompileShader(a,b,a.VERTEX_SHADER)},c.CompileFragmentShader=function(a,b){return c._CompileShader(a,b,a.FRAGMENT_SHADER)},c._CompileShader=function(a,b,c){var d=b.join("\n"),e=a.createShader(c);return a.shaderSource(e,d),a.compileShader(e),a.getShaderParameter(e,a.COMPILE_STATUS)?e:(console.log(a.getShaderInfoLog(e)),null)},c.compileProgram=function(a,b){var d=c.gl,e=c.CompileFragmentShader(d,b),f=c.CompileVertexShader(d,a),g=d.createProgram();return d.attachShader(g,f),d.attachShader(g,e),d.linkProgram(g),d.getProgramParameter(g,d.LINK_STATUS)||console.log("Could not initialise shaders"),g},c.BitmapText=function(a,b){c.DisplayObjectContainer.call(this),this.setText(a),this.setStyle(b),this.updateText(),this.dirty=!1},c.BitmapText.prototype=Object.create(c.DisplayObjectContainer.prototype),c.BitmapText.prototype.constructor=c.BitmapText,c.BitmapText.prototype.setText=function(a){this.text=a||" ",this.dirty=!0},c.BitmapText.prototype.setStyle=function(a){a=a||{},a.align=a.align||"left",this.style=a;var b=a.font.split(" ");this.fontName=b[b.length-1],this.fontSize=b.length>=2?parseInt(b[b.length-2],10):c.BitmapText.fonts[this.fontName].size,this.dirty=!0},c.BitmapText.prototype.updateText=function(){for(var a=c.BitmapText.fonts[this.fontName],b=new c.Point,d=null,e=[],f=0,g=[],h=0,i=this.fontSize/a.size,j=0;j=j;j++){var n=0;"right"==this.style.align?n=f-g[j]:"center"==this.style.align&&(n=(f-g[j])/2),m.push(n)}for(j=0;j0;)this.removeChild(this.getChildAt(0));this.updateText(),this.dirty=!1}c.DisplayObjectContainer.prototype.updateTransform.call(this)},c.BitmapText.fonts={},c.Text=function(a,b){this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),c.Sprite.call(this,c.Texture.fromCanvas(this.canvas)),this.setText(a),this.setStyle(b),this.updateText(),this.dirty=!1},c.Text.prototype=Object.create(c.Sprite.prototype),c.Text.prototype.constructor=c.Text,c.Text.prototype.setStyle=function(a){a=a||{},a.font=a.font||"bold 20pt Arial",a.fill=a.fill||"black",a.align=a.align||"left",a.stroke=a.stroke||"black",a.strokeThickness=a.strokeThickness||0,a.wordWrap=a.wordWrap||!1,a.wordWrapWidth=a.wordWrapWidth||100,this.style=a,this.dirty=!0},c.Text.prototype.setText=function(a){this.text=a.toString()||" ",this.dirty=!0},c.Text.prototype.updateText=function(){this.context.font=this.style.font;var a=this.text;this.style.wordWrap&&(a=this.wordWrap(this.text));for(var b=a.split(/(?:\r\n|\r|\n)/),d=[],e=0,f=0;fe?(g>0&&(b+="\n"),b+=f[g]+" ",e=this.style.wordWrapWidth-h):(e-=i,b+=f[g]+" ")}b+="\n"}return b},c.Text.prototype.destroy=function(a){a&&this.texture.destroy()},c.Text.heightCache={},c.BaseTextureCache={},c.texturesToUpdate=[],c.texturesToDestroy=[],c.BaseTexture=function(a){if(c.EventTarget.call(this),this.width=100,this.height=100,this.hasLoaded=!1,this.source=a,a){if(this.source instanceof Image||this.source instanceof HTMLImageElement)if(this.source.complete)this.hasLoaded=!0,this.width=this.source.width,this.height=this.source.height,c.texturesToUpdate.push(this);else{var b=this;this.source.onload=function(){b.hasLoaded=!0,b.width=b.source.width,b.height=b.source.height,c.texturesToUpdate.push(b),b.dispatchEvent({type:"loaded",content:b})}}else this.hasLoaded=!0,this.width=this.source.width,this.height=this.source.height,c.texturesToUpdate.push(this);this._powerOf2=!1}},c.BaseTexture.prototype.constructor=c.BaseTexture,c.BaseTexture.prototype.destroy=function(){this.source instanceof Image&&(this.source.src=null),this.source=null,c.texturesToDestroy.push(this)},c.BaseTexture.fromImage=function(a,b){var d=c.BaseTextureCache[a];if(!d){var e=new Image;b&&(e.crossOrigin=""),e.src=a,d=new c.BaseTexture(e),c.BaseTextureCache[a]=d}return d},c.TextureCache={},c.FrameCache={},c.Texture=function(a,b){if(c.EventTarget.call(this),b||(this.noFrame=!0,b=new c.Rectangle(0,0,1,1)),a instanceof c.Texture&&(a=a.baseTexture),this.baseTexture=a,this.frame=b,this.trim=new c.Point,this.scope=this,a.hasLoaded)this.noFrame&&(b=new c.Rectangle(0,0,a.width,a.height)),this.setFrame(b);else{var d=this;a.addEventListener("loaded",function(){d.onBaseTextureLoaded()})}},c.Texture.prototype.constructor=c.Texture,c.Texture.prototype.onBaseTextureLoaded=function(){var a=this.baseTexture;a.removeEventListener("loaded",this.onLoaded),this.noFrame&&(this.frame=new c.Rectangle(0,0,a.width,a.height)),this.noFrame=!1,this.width=this.frame.width,this.height=this.frame.height,this.scope.dispatchEvent({type:"update",content:this})},c.Texture.prototype.destroy=function(a){a&&this.baseTexture.destroy()},c.Texture.prototype.setFrame=function(a){if(this.frame=a,this.width=a.width,this.height=a.height,a.x+a.width>this.baseTexture.width||a.y+a.height>this.baseTexture.height)throw new Error("Texture Error: frame does not fit inside the base Texture dimensions "+this);this.updateFrame=!0,c.Texture.frameUpdates.push(this)},c.Texture.fromImage=function(a,b){var d=c.TextureCache[a];return d||(d=new c.Texture(c.BaseTexture.fromImage(a,b)),c.TextureCache[a]=d),d},c.Texture.fromFrame=function(a){var b=c.TextureCache[a];if(!b)throw new Error("The frameId '"+a+"' does not exist in the texture cache "+this);return b},c.Texture.fromCanvas=function(a){var b=new c.BaseTexture(a);return new c.Texture(b)},c.Texture.addTextureToCache=function(a,b){c.TextureCache[b]=a},c.Texture.removeTextureFromCache=function(a){var b=c.TextureCache[a];return c.TextureCache[a]=null,b},c.Texture.frameUpdates=[],c.RenderTexture=function(a,b){c.EventTarget.call(this),this.width=a||100,this.height=b||100,this.indetityMatrix=c.mat3.create(),this.frame=new c.Rectangle(0,0,this.width,this.height),c.gl?this.initWebGL():this.initCanvas()},c.RenderTexture.prototype=Object.create(c.Texture.prototype),c.RenderTexture.prototype.constructor=c.RenderTexture,c.RenderTexture.prototype.initWebGL=function(){var a=c.gl;this.glFramebuffer=a.createFramebuffer(),a.bindFramebuffer(a.FRAMEBUFFER,this.glFramebuffer),this.glFramebuffer.width=this.width,this.glFramebuffer.height=this.height,this.baseTexture=new c.BaseTexture,this.baseTexture.width=this.width,this.baseTexture.height=this.height,this.baseTexture._glTexture=a.createTexture(),a.bindTexture(a.TEXTURE_2D,this.baseTexture._glTexture),a.texImage2D(a.TEXTURE_2D,0,a.RGBA,this.width,this.height,0,a.RGBA,a.UNSIGNED_BYTE,null),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MAG_FILTER,a.LINEAR),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MIN_FILTER,a.LINEAR),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_S,a.CLAMP_TO_EDGE),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_T,a.CLAMP_TO_EDGE),this.baseTexture.isRender=!0,a.bindFramebuffer(a.FRAMEBUFFER,this.glFramebuffer),a.framebufferTexture2D(a.FRAMEBUFFER,a.COLOR_ATTACHMENT0,a.TEXTURE_2D,this.baseTexture._glTexture,0),this.projection=new c.Point(this.width/2,-this.height/2),this.render=this.renderWebGL},c.RenderTexture.prototype.resize=function(a,b){if(this.width=a,this.height=b,c.gl){this.projection.x=this.width/2,this.projection.y=-this.height/2;var d=c.gl;d.bindTexture(d.TEXTURE_2D,this.baseTexture._glTexture),d.texImage2D(d.TEXTURE_2D,0,d.RGBA,this.width,this.height,0,d.RGBA,d.UNSIGNED_BYTE,null)}else this.frame.width=this.width,this.frame.height=this.height,this.renderer.resize(this.width,this.height)},c.RenderTexture.prototype.initCanvas=function(){this.renderer=new c.CanvasRenderer(this.width,this.height,null,0),this.baseTexture=new c.BaseTexture(this.renderer.view),this.frame=new c.Rectangle(0,0,this.width,this.height),this.render=this.renderCanvas},c.RenderTexture.prototype.renderWebGL=function(a,b,d){var e=c.gl;e.colorMask(!0,!0,!0,!0),e.viewport(0,0,this.width,this.height),e.bindFramebuffer(e.FRAMEBUFFER,this.glFramebuffer),d&&(e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT));var f=a.children,g=a.worldTransform;a.worldTransform=c.mat3.create(),a.worldTransform[4]=-1,a.worldTransform[5]=-2*this.projection.y,b&&(a.worldTransform[2]=b.x,a.worldTransform[5]-=b.y),c.visibleCount++,a.vcount=c.visibleCount;for(var h=0,i=f.length;i>h;h++)f[h].updateTransform();var j=a.__renderGroup;j?a==j.root?j.render(this.projection,this.glFramebuffer):j.renderSpecific(a,this.projection,this.glFramebuffer):(this.renderGroup||(this.renderGroup=new c.WebGLRenderGroup(e)),this.renderGroup.setRenderable(a),this.renderGroup.render(this.projection,this.glFramebuffer)),a.worldTransform=g},c.RenderTexture.prototype.renderCanvas=function(a,b,d){var e=a.children;a.worldTransform=c.mat3.create(),b&&(a.worldTransform[2]=b.x,a.worldTransform[5]=b.y);for(var f=0,g=e.length;g>f;f++)e[f].updateTransform();d&&this.renderer.context.clearRect(0,0,this.width,this.height),this.renderer.renderDisplayObject(a),this.renderer.context.setTransform(1,0,0,1,0,0)},c.EventTarget=function(){var a={};this.addEventListener=this.on=function(b,c){void 0===a[b]&&(a[b]=[]),-1===a[b].indexOf(c)&&a[b].push(c)},this.dispatchEvent=this.emit=function(b){if(a[b.type]&&a[b.type].length)for(var c=0,d=a[b.type].length;d>c;c++)a[b.type][c](b)},this.removeEventListener=this.off=function(b,c){var d=a[b].indexOf(c);-1!==d&&a[b].splice(d,1)}},c.PolyK={},c.PolyK.Triangulate=function(a){var b=!0,d=a.length>>1;if(3>d)return[];for(var e=[],f=[],g=0;d>g;g++)f.push(g);for(var g=0,h=d;h>3;){var i=f[(g+0)%h],j=f[(g+1)%h],k=f[(g+2)%h],l=a[2*i],m=a[2*i+1],n=a[2*j],o=a[2*j+1],p=a[2*k],q=a[2*k+1],r=!1;if(c.PolyK._convex(l,m,n,o,p,q,b)){r=!0;for(var s=0;h>s;s++){var t=f[s];if(t!=i&&t!=j&&t!=k&&c.PolyK._PointInTriangle(a[2*t],a[2*t+1],l,m,n,o,p,q)){r=!1;break}}}if(r)e.push(i,j,k),f.splice((g+1)%h,1),h--,g=0;else if(g++>3*h){if(!b)return console.log("PIXI Warning: shape too complex to fill"),[];var e=[];f=[];for(var g=0;d>g;g++)f.push(g);g=0,h=d,b=!1}}return e.push(f[0],f[1],f[2]),e},c.PolyK._PointInTriangle=function(a,b,c,d,e,f,g,h){var i=g-c,j=h-d,k=e-c,l=f-d,m=a-c,n=b-d,o=i*i+j*j,p=i*k+j*l,q=i*m+j*n,r=k*k+l*l,s=k*m+l*n,t=1/(o*r-p*p),u=(r*q-p*s)*t,v=(o*s-p*q)*t;return u>=0&&v>=0&&1>u+v},c.PolyK._convex=function(a,b,c,d,e,f,g){return(b-d)*(e-c)+(c-a)*(f-d)>=0==g},d.Camera=function(a,b,c,e,f,g){this.game=a,this.world=a.world,this.id=0,this.view=new d.Rectangle(c,e,f,g),this.screenView=new d.Rectangle(c,e,f,g),this.bounds=new d.Rectangle(c,e,f,g),this.deadzone=null,this.visible=!0,this.atLimit={x:!1,y:!1},this.target=null,this._edge=0,this.displayObject=null},d.Camera.FOLLOW_LOCKON=0,d.Camera.FOLLOW_PLATFORMER=1,d.Camera.FOLLOW_TOPDOWN=2,d.Camera.FOLLOW_TOPDOWN_TIGHT=3,d.Camera.prototype={follow:function(a,b){"undefined"==typeof b&&(b=d.Camera.FOLLOW_LOCKON),this.target=a;var c;switch(b){case d.Camera.FOLLOW_PLATFORMER:var e=this.width/8,f=this.height/3;this.deadzone=new d.Rectangle((this.width-e)/2,(this.height-f)/2-.25*f,e,f);break;case d.Camera.FOLLOW_TOPDOWN:c=Math.max(this.width,this.height)/4,this.deadzone=new d.Rectangle((this.width-c)/2,(this.height-c)/2,c,c);break;case d.Camera.FOLLOW_TOPDOWN_TIGHT:c=Math.max(this.width,this.height)/8,this.deadzone=new d.Rectangle((this.width-c)/2,(this.height-c)/2,c,c);break;case d.Camera.FOLLOW_LOCKON:this.deadzone=null;break;default:this.deadzone=null}},focusOn:function(a){this.setPosition(Math.round(a.x-this.view.halfWidth),Math.round(a.y-this.view.halfHeight))},focusOnXY:function(a,b){this.setPosition(Math.round(a-this.view.halfWidth),Math.round(b-this.view.halfHeight))},update:function(){this.target&&this.updateTarget(),this.bounds&&this.checkBounds(),this.displayObject.position.x=-this.view.x,this.displayObject.position.y=-this.view.y},updateTarget:function(){this.deadzone?(this._edge=this.target.x-this.deadzone.x,this.view.x>this._edge&&(this.view.x=this._edge),this._edge=this.target.x+this.target.width-this.deadzone.x-this.deadzone.width,this.view.xthis._edge&&(this.view.y=this._edge),this._edge=this.target.y+this.target.height-this.deadzone.y-this.deadzone.height,this.view.ythis.bounds.right-this.width&&(this.atLimit.x=!0,this.view.x=this.bounds.right-this.width+1),this.view.ythis.bounds.bottom-this.height&&(this.atLimit.y=!0,this.view.y=this.bounds.bottom-this.height+1),this.view.floor()},setPosition:function(a,b){this.view.x=a,this.view.y=b,this.bounds&&this.checkBounds()},setSize:function(a,b){this.view.width=a,this.view.height=b}},Object.defineProperty(d.Camera.prototype,"x",{get:function(){return this.view.x},set:function(a){this.view.x=a,this.bounds&&this.checkBounds()}}),Object.defineProperty(d.Camera.prototype,"y",{get:function(){return this.view.y},set:function(a){this.view.y=a,this.bounds&&this.checkBounds()}}),Object.defineProperty(d.Camera.prototype,"width",{get:function(){return this.view.width},set:function(a){this.view.width=a}}),Object.defineProperty(d.Camera.prototype,"height",{get:function(){return this.view.height},set:function(a){this.view.height=a}}),d.State=function(){this.game=null,this.add=null,this.camera=null,this.cache=null,this.input=null,this.load=null,this.math=null,this.sound=null,this.stage=null,this.time=null,this.tweens=null,this.world=null,this.particles=null,this.physics=null},d.State.prototype={preload:function(){},loadUpdate:function(){},loadRender:function(){},create:function(){},update:function(){},render:function(){},paused:function(){},destroy:function(){}},d.StateManager=function(a,b){this.game=a,this.states={},this._pendingState=null,null!==b&&(this._pendingState=b),this._created=!1,this.current="",this.onInitCallback=null,this.onPreloadCallback=null,this.onCreateCallback=null,this.onUpdateCallback=null,this.onRenderCallback=null,this.onPreRenderCallback=null,this.onLoadUpdateCallback=null,this.onLoadRenderCallback=null,this.onPausedCallback=null,this.onShutDownCallback=null},d.StateManager.prototype={boot:function(){this.game.onPause.add(this.pause,this),this.game.onResume.add(this.resume,this),null!==this._pendingState&&("string"==typeof this._pendingState?this.start(this._pendingState,!1,!1):this.add("default",this._pendingState,!0))},add:function(a,b,c){"undefined"==typeof c&&(c=!1);var e;return b instanceof d.State?e=b:"object"==typeof b?(e=b,e.game=this.game):"function"==typeof b&&(e=new b(this.game)),this.states[a]=e,c&&(this.game.isBooted?this.start(a):this._pendingState=a),e},remove:function(a){this.current==a&&(this.callbackContext=null,this.onInitCallback=null,this.onShutDownCallback=null,this.onPreloadCallback=null,this.onLoadRenderCallback=null,this.onLoadUpdateCallback=null,this.onCreateCallback=null,this.onUpdateCallback=null,this.onRenderCallback=null,this.onPausedCallback=null,this.onDestroyCallback=null),delete this.states[a]},start:function(a,b,c){return"undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=!1),this.game.isBooted===!1?(this._pendingState=a,void 0):(this.checkState(a)!==!1&&(this.current&&this.onShutDownCallback.call(this.callbackContext,this.game),b&&(this.game.tweens.removeAll(),this.game.world.destroy(),c===!0&&this.game.cache.destroy()),this.setCurrentState(a),this.onPreloadCallback?(this.game.load.reset(),this.onPreloadCallback.call(this.callbackContext,this.game),0===this.game.load.totalQueuedFiles()?this.game.loadComplete():this.game.load.start()):this.game.loadComplete()),void 0)},dummy:function(){},checkState:function(a){if(this.states[a]){var b=!1;return this.states[a].preload&&(b=!0),b===!1&&this.states[a].loadRender&&(b=!0),b===!1&&this.states[a].loadUpdate&&(b=!0),b===!1&&this.states[a].create&&(b=!0),b===!1&&this.states[a].update&&(b=!0),b===!1&&this.states[a].preRender&&(b=!0),b===!1&&this.states[a].render&&(b=!0),b===!1&&this.states[a].paused&&(b=!0),b===!1?(console.warn("Invalid Phaser State object given. Must contain at least a one of the required functions."),!1):!0}return console.warn("Phaser.StateManager - No state found with the key: "+a),!1},link:function(a){this.states[a].game=this.game,this.states[a].add=this.game.add,this.states[a].camera=this.game.camera,this.states[a].cache=this.game.cache,this.states[a].input=this.game.input,this.states[a].load=this.game.load,this.states[a].math=this.game.math,this.states[a].sound=this.game.sound,this.states[a].stage=this.game.stage,this.states[a].time=this.game.time,this.states[a].tweens=this.game.tweens,this.states[a].world=this.game.world,this.states[a].particles=this.game.particles,this.states[a].physics=this.game.physics,this.states[a].rnd=this.game.rnd},setCurrentState:function(a){this.callbackContext=this.states[a],this.link(a),this.onInitCallback=this.states[a].init||this.dummy,this.onPreloadCallback=this.states[a].preload||null,this.onLoadRenderCallback=this.states[a].loadRender||null,this.onLoadUpdateCallback=this.states[a].loadUpdate||null,this.onCreateCallback=this.states[a].create||null,this.onUpdateCallback=this.states[a].update||null,this.onPreRenderCallback=this.states[a].preRender||null,this.onRenderCallback=this.states[a].render||null,this.onPausedCallback=this.states[a].paused||null,this.onShutDownCallback=this.states[a].shutdown||this.dummy,this.current=a,this._created=!1,this.onInitCallback.call(this.callbackContext,this.game)},loadComplete:function(){this._created===!1&&this.onCreateCallback?(this._created=!0,this.onCreateCallback.call(this.callbackContext,this.game)):this._created=!0},pause:function(){this._created&&this.onPausedCallback&&this.onPausedCallback.call(this.callbackContext,this.game,!0)},resume:function(){this._created&&this.onre&&this.onPausedCallback.call(this.callbackContext,this.game,!1)},update:function(){this._created&&this.onUpdateCallback?this.onUpdateCallback.call(this.callbackContext,this.game):this.onLoadUpdateCallback&&this.onLoadUpdateCallback.call(this.callbackContext,this.game)},preRender:function(){this.onPreRenderCallback&&this.onPreRenderCallback.call(this.callbackContext,this.game)},render:function(){this._created&&this.onRenderCallback?(this.game.renderType===d.CANVAS&&(this.game.context.save(),this.game.context.setTransform(1,0,0,1,0,0)),this.onRenderCallback.call(this.callbackContext,this.game),this.game.renderType===d.CANVAS&&this.game.context.restore()):this.onLoadRenderCallback&&this.onLoadRenderCallback.call(this.callbackContext,this.game)},destroy:function(){this.callbackContext=null,this.onInitCallback=null,this.onShutDownCallback=null,this.onPreloadCallback=null,this.onLoadRenderCallback=null,this.onLoadUpdateCallback=null,this.onCreateCallback=null,this.onUpdateCallback=null,this.onRenderCallback=null,this.onPausedCallback=null,this.onDestroyCallback=null,this.game=null,this.states={},this._pendingState=null}},d.LinkedList=function(){this.next=null,this.prev=null,this.first=null,this.last=null,this.total=0},d.LinkedList.prototype={add:function(a){return 0===this.total&&null==this.first&&null==this.last?(this.first=a,this.last=a,this.next=a,a.prev=this,this.total++,a):(this.last.next=a,a.prev=this.last,this.last=a,this.total++,a)},remove:function(a){a==this.first?this.first=this.first.next:a==this.last&&(this.last=this.last.prev),a.prev&&(a.prev.next=a.next),a.next&&(a.next.prev=a.prev),a.next=a.prev=null,null==this.first&&(this.last=null),this.total--},callAll:function(a){if(this.first&&this.last){var b=this.first;do b&&b[a]&&b[a].call(b),b=b.next;while(b!=this.last.next)}}},d.Signal=function(){this._bindings=[],this._prevParams=null;var a=this;this.dispatch=function(){d.Signal.prototype.dispatch.apply(a,arguments)}},d.Signal.prototype={memorize:!1,_shouldPropagate:!0,active:!0,validateListener:function(a,b){if("function"!=typeof a)throw new Error("listener is a required param of {fn}() and should be a Function.".replace("{fn}",b))},_registerListener:function(a,b,c,e){var f,g=this._indexOfListener(a,c);if(-1!==g){if(f=this._bindings[g],f.isOnce()!==b)throw new Error("You cannot add"+(b?"":"Once")+"() then add"+(b?"Once":"")+"() the same listener without removing the relationship first.")}else f=new d.SignalBinding(this,a,b,c,e),this._addBinding(f);return this.memorize&&this._prevParams&&f.execute(this._prevParams),f},_addBinding:function(a){var b=this._bindings.length;do--b;while(this._bindings[b]&&a._priority<=this._bindings[b]._priority);this._bindings.splice(b+1,0,a)},_indexOfListener:function(a,b){for(var c,d=this._bindings.length;d--;)if(c=this._bindings[d],c._listener===a&&c.context===b)return d;return-1},has:function(a,b){return-1!==this._indexOfListener(a,b)},add:function(a,b,c){return this.validateListener(a,"add"),this._registerListener(a,!1,b,c)},addOnce:function(a,b,c){return this.validateListener(a,"addOnce"),this._registerListener(a,!0,b,c)},remove:function(a,b){this.validateListener(a,"remove");var c=this._indexOfListener(a,b);return-1!==c&&(this._bindings[c]._destroy(),this._bindings.splice(c,1)),a},removeAll:function(){for(var a=this._bindings.length;a--;)this._bindings[a]._destroy();this._bindings.length=0},getNumListeners:function(){return this._bindings.length},halt:function(){this._shouldPropagate=!1},dispatch:function(){if(this.active){var a,b=Array.prototype.slice.call(arguments),c=this._bindings.length;if(this.memorize&&(this._prevParams=b),c){a=this._bindings.slice(),this._shouldPropagate=!0;do c--;while(a[c]&&this._shouldPropagate&&a[c].execute(b)!==!1)}}},forget:function(){this._prevParams=null},dispose:function(){this.removeAll(),delete this._bindings,delete this._prevParams},toString:function(){return"[Phaser.Signal active:"+this.active+" numListeners:"+this.getNumListeners()+"]"}},d.SignalBinding=function(a,b,c,d,e){this._listener=b,this._isOnce=c,this.context=d,this._signal=a,this._priority=e||0},d.SignalBinding.prototype={active:!0,params:null,execute:function(a){var b,c;return this.active&&this._listener&&(c=this.params?this.params.concat(a):a,b=this._listener.apply(this.context,c),this._isOnce&&this.detach()),b},detach:function(){return this.isBound()?this._signal.remove(this._listener,this.context):null},isBound:function(){return!!this._signal&&!!this._listener},isOnce:function(){return this._isOnce},getListener:function(){return this._listener},getSignal:function(){return this._signal},_destroy:function(){delete this._signal,delete this._listener,delete this.context},toString:function(){return"[Phaser.SignalBinding isOnce:"+this._isOnce+", isBound:"+this.isBound()+", active:"+this.active+"]"}},d.Filter=function(a,b,c){this.game=a,this.type=d.WEBGL_FILTER,this.passes=[this],this.dirty=!0,this.padding=0,this.uniforms={time:{type:"1f",value:0},resolution:{type:"2f",value:{x:256,y:256}},mouse:{type:"2f",value:{x:0,y:0}}},this.fragmentSrc=c||[]},d.Filter.prototype={init:function(){},setResolution:function(a,b){this.uniforms.resolution.value.x=a,this.uniforms.resolution.value.y=b},update:function(a){"undefined"!=typeof a&&(a.x>0&&(this.uniforms.mouse.x=a.x.toFixed(2)),a.y>0&&(this.uniforms.mouse.y=a.y.toFixed(2))),this.uniforms.time.value=this.game.time.totalElapsedSeconds()},destroy:function(){this.game=null}},Object.defineProperty(d.Filter.prototype,"width",{get:function(){return this.uniforms.resolution.value.x},set:function(a){this.uniforms.resolution.value.x=a}}),Object.defineProperty(d.Filter.prototype,"height",{get:function(){return this.uniforms.resolution.value.y},set:function(a){this.uniforms.resolution.value.y=a}}),d.Plugin=function(a,b){"undefined"==typeof b&&(b=null),this.game=a,this.parent=b,this.active=!1,this.visible=!1,this.hasPreUpdate=!1,this.hasUpdate=!1,this.hasPostUpdate=!1,this.hasRender=!1,this.hasPostRender=!1},d.Plugin.prototype={preUpdate:function(){},update:function(){},render:function(){},postRender:function(){},destroy:function(){this.game=null,this.parent=null,this.active=!1,this.visible=!1}},d.PluginManager=function(a,b){this.game=a,this._parent=b,this.plugins=[],this._pluginsLength=0},d.PluginManager.prototype={add:function(a){var b=!1;return"function"==typeof a?a=new a(this.game,this._parent):(a.game=this.game,a.parent=this._parent),"function"==typeof a.preUpdate&&(a.hasPreUpdate=!0,b=!0),"function"==typeof a.update&&(a.hasUpdate=!0,b=!0),"function"==typeof a.postUpdate&&(a.hasPostUpdate=!0,b=!0),"function"==typeof a.render&&(a.hasRender=!0,b=!0),"function"==typeof a.postRender&&(a.hasPostRender=!0,b=!0),b?((a.hasPreUpdate||a.hasUpdate||a.hasPostUpdate)&&(a.active=!0),(a.hasRender||a.hasPostRender)&&(a.visible=!0),this._pluginsLength=this.plugins.push(a),"function"==typeof a.init&&a.init(),a):null},remove:function(a){if(0!==this._pluginsLength)for(this._p=0;this._pthis._nextOffsetCheck&&(d.Canvas.getOffset(this.canvas,this.offset),this._nextOffsetCheck=this.game.time.now+this.checkOffsetInterval)},visibilityChange:function(a){this.disableVisibilityChange||(this.game.paused="pagehide"==a.type||"blur"==a.type||document.hidden===!0||document.webkitHidden===!0?!0:!1)}},Object.defineProperty(d.Stage.prototype,"backgroundColor",{get:function(){return this._backgroundColor},set:function(a){this._backgroundColor=a,this.game.transparent===!1&&(this.game.renderType==d.CANVAS?this.game.canvas.style.backgroundColor=a:("string"==typeof a&&(a=d.Color.hexToRGB(a)),this._stage.setBackgroundColor(a)))}}),d.Group=function(a,b,e,f){("undefined"==typeof b||null===typeof b)&&(b=a.world),"undefined"==typeof f&&(f=!1),this.game=a,this.name=e||"group",f?this._container=this.game.stage._stage:(this._container=new c.DisplayObjectContainer,this._container.name=this.name,b?b instanceof d.Group?(b._container.addChild(this._container),b._container.updateTransform()):(b.addChild(this._container),b.updateTransform()):(this.game.stage._stage.addChild(this._container),this.game.stage._stage.updateTransform())),this.type=d.GROUP,this.exists=!0,this.scale=new d.Point(1,1),this.cursor=null},d.Group.RETURN_NONE=0,d.Group.RETURN_TOTAL=1,d.Group.RETURN_CHILD=2,d.Group.SORT_ASCENDING=-1,d.Group.SORT_DESCENDING=1,d.Group.prototype={add:function(a){return a.group!==this&&(a.group=this,a.events&&a.events.onAddedToGroup.dispatch(a,this),this._container.addChild(a),a.updateTransform(),null===this.cursor&&(this.cursor=a)),a},addAt:function(a,b){return a.group!==this&&(a.group=this,a.events&&a.events.onAddedToGroup.dispatch(a,this),this._container.addChildAt(a,b),a.updateTransform(),null===this.cursor&&(this.cursor=a)),a},getAt:function(a){return this._container.getChildAt(a)},create:function(a,b,c,e,f){"undefined"==typeof f&&(f=!0);var g=new d.Sprite(this.game,a,b,c,e);return g.group=this,g.exists=f,g.visible=f,g.alive=f,g.events&&g.events.onAddedToGroup.dispatch(g,this),this._container.addChild(g),g.updateTransform(),null===this.cursor&&(this.cursor=g),g},createMultiple:function(a,b,c,e){"undefined"==typeof e&&(e=!1);for(var f=0;a>f;f++){var g=new d.Sprite(this.game,0,0,b,c);g.group=this,g.exists=e,g.visible=e,g.alive=e,g.events&&g.events.onAddedToGroup.dispatch(g,this),this._container.addChild(g),g.updateTransform(),null===this.cursor&&(this.cursor=g)}},next:function(){this.cursor&&(this.cursor=this.cursor==this._container.last?this._container._iNext:this.cursor._iNext)},previous:function(){this.cursor&&(this.cursor=this.cursor==this._container._iNext?this._container.last:this.cursor._iPrev)},childTest:function(a,b){var c=a+" next: ";c+=b._iNext?b._iNext.name:"-null-",c=c+" "+a+" prev: ",c+=b._iPrev?b._iPrev.name:"-null-",console.log(c)},swapIndex:function(a,b){var c=this.getAt(a),d=this.getAt(b);console.log("swapIndex ",a," with ",b),this.swap(c,d)},swap:function(a,b){if(a===b||!a.parent||!b.parent||a.group!==this||b.group!==this)return!1;var c=a._iPrev,d=a._iNext,e=b._iPrev,f=b._iNext,g=this._container.last._iNext,h=this.game.stage._stage;do h!==a&&h!==b&&(h.first===a?h.first=b:h.first===b&&(h.first=a),h.last===a?h.last=b:h.last===b&&(h.last=a)),h=h._iNext;while(h!=g);return a._iNext==b?(a._iNext=f,a._iPrev=b,b._iNext=a,b._iPrev=c,c&&(c._iNext=b),f&&(f._iPrev=a),a.__renderGroup&&a.__renderGroup.updateTexture(a),b.__renderGroup&&b.__renderGroup.updateTexture(b),!0):b._iNext==a?(a._iNext=b,a._iPrev=e,b._iNext=d,b._iPrev=a,e&&(e._iNext=a),d&&(d._iPrev=b),a.__renderGroup&&a.__renderGroup.updateTexture(a),b.__renderGroup&&b.__renderGroup.updateTexture(b),!0):(a._iNext=f,a._iPrev=e,b._iNext=d,b._iPrev=c,c&&(c._iNext=b),d&&(d._iPrev=b),e&&(e._iNext=a),f&&(f._iPrev=a),a.__renderGroup&&a.__renderGroup.updateTexture(a),b.__renderGroup&&b.__renderGroup.updateTexture(b),!0)},bringToTop:function(a){return a.group===this&&(this.remove(a),this.add(a)),a},getIndex:function(a){return this._container.children.indexOf(a)},replace:function(a,b){if(this._container.first._iNext){var c=this.getIndex(a);-1!=c&&(void 0!==b.parent&&(b.events.onRemovedFromGroup.dispatch(b,this),b.parent.removeChild(b)),this._container.removeChild(a),this._container.addChildAt(b,c),b.events.onAddedToGroup.dispatch(b,this),b.updateTransform(),this.cursor==a&&(this.cursor=this._container._iNext))}},setProperty:function(a,b,c,d){d=d||0;var e=b.length;1==e?0===d?a[b[0]]=c:1==d?a[b[0]]+=c:2==d?a[b[0]]-=c:3==d?a[b[0]]*=c:4==d&&(a[b[0]]/=c):2==e?0===d?a[b[0]][b[1]]=c:1==d?a[b[0]][b[1]]+=c:2==d?a[b[0]][b[1]]-=c:3==d?a[b[0]][b[1]]*=c:4==d&&(a[b[0]][b[1]]/=c):3==e?0===d?a[b[0]][b[1]][b[2]]=c:1==d?a[b[0]][b[1]][b[2]]+=c:2==d?a[b[0]][b[1]][b[2]]-=c:3==d?a[b[0]][b[1]][b[2]]*=c:4==d&&(a[b[0]][b[1]][b[2]]/=c):4==e&&(0===d?a[b[0]][b[1]][b[2]][b[3]]=c:1==d?a[b[0]][b[1]][b[2]][b[3]]+=c:2==d?a[b[0]][b[1]][b[2]][b[3]]-=c:3==d?a[b[0]][b[1]][b[2]][b[3]]*=c:4==d&&(a[b[0]][b[1]][b[2]][b[3]]/=c))},setAll:function(a,b,c,d,e){if(a=a.split("."),"undefined"==typeof c&&(c=!1),"undefined"==typeof d&&(d=!1),e=e||0,this._container.children.length>0&&this._container.first._iNext){var f=this._container.first._iNext;do(c===!1||c&&f.alive)&&(d===!1||d&&f.visible)&&this.setProperty(f,a,b,e),f=f._iNext;while(f!=this._container.last._iNext)}},addAll:function(a,b,c,d){this.setAll(a,b,c,d,1)},subAll:function(a,b,c,d){this.setAll(a,b,c,d,2)},multiplyAll:function(a,b,c,d){this.setAll(a,b,c,d,3)},divideAll:function(a,b,c,d){this.setAll(a,b,c,d,4)},callAllExists:function(a,b){var c=Array.prototype.splice.call(arguments,2);if(this._container.children.length>0&&this._container.first._iNext){var d=this._container.first._iNext;do d.exists==b&&d[a]&&d[a].apply(d,c),d=d._iNext;while(d!=this._container.last._iNext)}},callbackFromArray:function(a,b,c){if(1==c){if(a[b[0]])return a[b[0]]}else if(2==c){if(a[b[0]][b[1]])return a[b[0]][b[1]]}else if(3==c){if(a[b[0]][b[1]][b[2]])return a[b[0]][b[1]][b[2]]}else if(4==c){if(a[b[0]][b[1]][b[2]][b[3]])return a[b[0]][b[1]][b[2]][b[3]]}else if(a[b])return a[b];return!1},callAll:function(a,b){if("undefined"!=typeof a){a=a.split(".");var c=a.length;if("undefined"==typeof b)b=null;else if("string"==typeof b){b=b.split(".");var d=b.length}var e=Array.prototype.splice.call(arguments,2),f=null,g=null;if(this._container.children.length>0&&this._container.first._iNext){var h=this._container.first._iNext;do f=this.callbackFromArray(h,a,c),b&&f?(g=this.callbackFromArray(h,b,d),f&&f.apply(g,e)):f&&f.apply(h,e),h=h._iNext;while(h!=this._container.last._iNext)}}},forEach:function(a,b,c){"undefined"==typeof c&&(c=!1);var d=Array.prototype.splice.call(arguments,3);if(d.unshift(null),this._container.children.length>0&&this._container.first._iNext){var e=this._container.first._iNext;do(c===!1||c&&e.exists)&&(d[0]=e,a.apply(b,d)),e=e._iNext;while(e!=this._container.last._iNext)}},forEachExists:function(a,b){var c=Array.prototype.splice.call(arguments,2);c.unshift(null),this.iterate("exists",!0,d.Group.RETURN_TOTAL,a,b,c)},forEachAlive:function(a,b){var c=Array.prototype.splice.call(arguments,2);c.unshift(null),this.iterate("alive",!0,d.Group.RETURN_TOTAL,a,b,c)},forEachDead:function(a,b){var c=Array.prototype.splice.call(arguments,2);c.unshift(null),this.iterate("alive",!1,d.Group.RETURN_TOTAL,a,b,c)},sort:function(a,b){"undefined"==typeof a&&(a="y"),"undefined"==typeof b&&(b=d.Group.SORT_ASCENDING);var c,e;do{c=!1;for(var f=0,g=this._container.children.length-1;g>f;f++)b==d.Group.SORT_ASCENDING?this._container.children[f][a]>this._container.children[f+1][a]&&(this.swap(this.getAt(f),this.getAt(f+1)),e=this._container.children[f],this._container.children[f]=this._container.children[f+1],this._container.children[f+1]=e,c=!0):this._container.children[f][a]0&&this._container.first._iNext){var i=this._container.first._iNext;do{if(i[a]===b&&(h++,e&&(g[0]=i,e.apply(f,g)),c==d.Group.RETURN_CHILD))return i;i=i._iNext}while(i!=this._container.last._iNext)}return c==d.Group.RETURN_TOTAL?h:c==d.Group.RETURN_CHILD?null:void 0},getFirstExists:function(a){return"boolean"!=typeof a&&(a=!0),this.iterate("exists",a,d.Group.RETURN_CHILD)},getFirstAlive:function(){return this.iterate("alive",!0,d.Group.RETURN_CHILD)},getFirstDead:function(){return this.iterate("alive",!1,d.Group.RETURN_CHILD)},countLiving:function(){return this.iterate("alive",!0,d.Group.RETURN_TOTAL)},countDead:function(){return this.iterate("alive",!1,d.Group.RETURN_TOTAL)},getRandom:function(a,b){return 0===this._container.children.length?null:(a=a||0,b=b||this._container.children.length,this.game.math.getRandom(this._container.children,a,b))},remove:function(a){return a.group!==this?!1:(a.events&&a.events.onRemovedFromGroup.dispatch(a,this),a.parent===this._container&&this._container.removeChild(a),this.cursor==a&&(this.cursor=this._container._iNext?this._container._iNext:null),a.group=null,!0)},removeAll:function(){if(0!==this._container.children.length){do this._container.children[0].events&&this._container.children[0].events.onRemovedFromGroup.dispatch(this._container.children[0],this),this._container.removeChild(this._container.children[0]);while(this._container.children.length>0);this.cursor=null}},removeBetween:function(a,b){if(0!==this._container.children.length){if(a>b||0>a||b>this._container.children.length)return!1;for(var c=a;b>c;c++){var d=this._container.children[c];d.events.onRemovedFromGroup.dispatch(d,this),this._container.removeChild(d),this.cursor==d&&(this.cursor=this._container._iNext?this._container._iNext:null)}}},destroy:function(){this.removeAll(),this._container.parent.removeChild(this._container),this._container=null,this.game=null,this.exists=!1,this.cursor=null},validate:function(){var a=this.game.stage._stage.last._iNext,b=this.game.stage._stage,c=null,d=null,e=0;do{if(e>0){if(b!==c)return console.log("check next fail"),!1;if(b._iPrev!==d)return console.log("check previous fail"),!1}c=b._iNext,d=b,b=b._iNext,e++}while(b!=a);return!0},dump:function(a){"undefined"==typeof a&&(a=!1);var b=20,c="\n"+d.Utils.pad("Node",b)+"|"+d.Utils.pad("Next",b)+"|"+d.Utils.pad("Previous",b)+"|"+d.Utils.pad("First",b)+"|"+d.Utils.pad("Last",b);console.log(c);var c=d.Utils.pad("----------",b)+"|"+d.Utils.pad("----------",b)+"|"+d.Utils.pad("----------",b)+"|"+d.Utils.pad("----------",b)+"|"+d.Utils.pad("----------",b);if(console.log(c),a)var e=this.game.stage._stage.last._iNext,f=this.game.stage._stage;else var e=this._container.last._iNext,f=this._container;do{var g=f.name||"*";if(this.cursor==f)var g="> "+g;var h="-",i="-",j="-",k="-";f._iNext&&(h=f._iNext.name),f._iPrev&&(i=f._iPrev.name),f.first&&(j=f.first.name),f.last&&(k=f.last.name),"undefined"==typeof h&&(h="-"),"undefined"==typeof i&&(i="-"),"undefined"==typeof j&&(j="-"),"undefined"==typeof k&&(k="-");var c=d.Utils.pad(g,b)+"|"+d.Utils.pad(h,b)+"|"+d.Utils.pad(i,b)+"|"+d.Utils.pad(j,b)+"|"+d.Utils.pad(k,b);console.log(c),f=f._iNext}while(f!=e)}},Object.defineProperty(d.Group.prototype,"total",{get:function(){return this.iterate("exists",!0,d.Group.RETURN_TOTAL)}}),Object.defineProperty(d.Group.prototype,"length",{get:function(){return this.iterate("exists",!0,d.Group.RETURN_TOTAL)}}),Object.defineProperty(d.Group.prototype,"x",{get:function(){return this._container.position.x},set:function(a){this._container.position.x=a}}),Object.defineProperty(d.Group.prototype,"y",{get:function(){return this._container.position.y},set:function(a){this._container.position.y=a}}),Object.defineProperty(d.Group.prototype,"angle",{get:function(){return d.Math.radToDeg(this._container.rotation)},set:function(a){this._container.rotation=d.Math.degToRad(a)}}),Object.defineProperty(d.Group.prototype,"rotation",{get:function(){return this._container.rotation},set:function(a){this._container.rotation=a}}),Object.defineProperty(d.Group.prototype,"visible",{get:function(){return this._container.visible},set:function(a){this._container.visible=a}}),Object.defineProperty(d.Group.prototype,"alpha",{get:function(){return this._container.alpha},set:function(a){this._container.alpha=a}}),d.World=function(a){d.Group.call(this,a,null,"__world",!1),this.scale=new d.Point(1,1),this.bounds=new d.Rectangle(0,0,a.width,a.height),this.camera=null,this.currentRenderOrderID=0},d.World.prototype=Object.create(d.Group.prototype),d.World.prototype.constructor=d.World,d.World.prototype.boot=function(){this.camera=new d.Camera(this.game,0,0,0,this.game.width,this.game.height),this.camera.displayObject=this._container,this.game.camera=this.camera},d.World.prototype.update=function(){if(this.currentRenderOrderID=0,this.game.stage._stage.first._iNext){var a,b=this.game.stage._stage.first._iNext;do a=!1,b.preUpdate&&(a=b.preUpdate()===!1),b.update&&(a=b.update()===!1||a),b=a?b.last._iNext:b._iNext;while(b!=this.game.stage._stage.last._iNext)}},d.World.prototype.postUpdate=function(){if(this.game.stage._stage.first._iNext){var a=this.game.stage._stage.first._iNext;do a.postUpdate&&a.postUpdate(),a=a._iNext;while(a!=this.game.stage._stage.last._iNext)}this.camera.update()},d.World.prototype.setBounds=function(a,b,c,d){this.bounds.setTo(a,b,c,d),this.camera.bounds&&this.camera.bounds.setTo(a,b,c,d)},d.World.prototype.destroy=function(){this.camera.x=0,this.camera.y=0,this.game.input.reset(!0),this.removeAll()},Object.defineProperty(d.World.prototype,"width",{get:function(){return this.bounds.width},set:function(a){this.bounds.width=a}}),Object.defineProperty(d.World.prototype,"height",{get:function(){return this.bounds.height},set:function(a){this.bounds.height=a}}),Object.defineProperty(d.World.prototype,"centerX",{get:function(){return this.bounds.halfWidth}}),Object.defineProperty(d.World.prototype,"centerY",{get:function(){return this.bounds.halfHeight}}),Object.defineProperty(d.World.prototype,"randomX",{get:function(){return this.bounds.x<0?this.game.rnd.integerInRange(this.bounds.x,this.bounds.width-Math.abs(this.bounds.x)):this.game.rnd.integerInRange(this.bounds.x,this.bounds.width)}}),Object.defineProperty(d.World.prototype,"randomY",{get:function(){return this.bounds.y<0?this.game.rnd.integerInRange(this.bounds.y,this.bounds.height-Math.abs(this.bounds.y)):this.game.rnd.integerInRange(this.bounds.y,this.bounds.height)}}),Object.defineProperty(d.World.prototype,"visible",{get:function(){return this._container.visible},set:function(a){this._container.visible=a}}),d.Game=function(a,b,c,e,f,g,h){a=a||800,b=b||600,c=c||d.AUTO,e=e||"",f=f||null,"undefined"==typeof g&&(g=!1),"undefined"==typeof h&&(h=!0),this.id=d.GAMES.push(this)-1,this.parent=e,this.width=a,this.height=b,this.transparent=g,this.antialias=h,this.renderer=null,this.state=new d.StateManager(this,f),this._paused=!1,this.renderType=c,this._loadComplete=!1,this.isBooted=!1,this.isRunning=!1,this.raf=null,this.add=null,this.cache=null,this.input=null,this.load=null,this.math=null,this.net=null,this.sound=null,this.stage=null,this.time=null,this.tweens=null,this.world=null,this.physics=null,this.rnd=null,this.device=null,this.camera=null,this.canvas=null,this.context=null,this.debug=null,this.particles=null;var i=this;return this._onBoot=function(){return i.boot()},"complete"===document.readyState||"interactive"===document.readyState?window.setTimeout(this._onBoot,0):(document.addEventListener("DOMContentLoaded",this._onBoot,!1),window.addEventListener("load",this._onBoot,!1)),this},d.Game.prototype={boot:function(){this.isBooted||(document.body?(document.removeEventListener("DOMContentLoaded",this._onBoot),window.removeEventListener("load",this._onBoot),this.onPause=new d.Signal,this.onResume=new d.Signal,this.isBooted=!0,this.device=new d.Device,this.math=d.Math,this.rnd=new d.RandomDataGenerator([(Date.now()*Math.random()).toString()]),this.stage=new d.Stage(this,this.width,this.height),this.setUpRenderer(),this.world=new d.World(this),this.add=new d.GameObjectFactory(this),this.cache=new d.Cache(this),this.load=new d.Loader(this),this.time=new d.Time(this),this.tweens=new d.TweenManager(this),this.input=new d.Input(this),this.sound=new d.SoundManager(this),this.physics=new d.Physics.Arcade(this),this.particles=new d.Particles(this),this.plugins=new d.PluginManager(this,this),this.net=new d.Net(this),this.debug=new d.Utils.Debug(this),this.stage.boot(),this.world.boot(),this.input.boot(),this.sound.boot(),this.state.boot(),this.load.onLoadComplete.add(this.loadComplete,this),this.showDebugHeader(),this.isRunning=!0,this._loadComplete=!1,this.raf=new d.RequestAnimationFrame(this),this.raf.start()):window.setTimeout(this._onBoot,20))},showDebugHeader:function(){var a=d.DEV_VERSION,b="Canvas",c="HTML Audio";if(this.renderType==d.WEBGL?b="WebGL":this.renderType==d.HEADLESS&&(b="Headless"),this.device.webAudio&&(c="WebAudio"),this.device.chrome){var e=["%c %c %c Phaser v"+a+" - Renderer: "+b+" - Audio: "+c+" %c %c ","background: #00bff3","background: #0072bc","color: #ffffff; background: #003471","background: #0072bc","background: #00bff3"];console.log.apply(console,e)}else console.log("Phaser v"+a+" - Renderer: "+b+" - Audio: "+c)},setUpRenderer:function(){if(this.renderType===d.HEADLESS||this.renderType===d.CANVAS||this.renderType===d.AUTO&&this.device.webGL===!1){if(!this.device.canvas)throw new Error("Phaser.Game - cannot create Canvas or WebGL context, aborting.");this.renderType===d.AUTO&&(this.renderType=d.CANVAS),this.renderer=new c.CanvasRenderer(this.width,this.height,this.stage.canvas,this.transparent),d.Canvas.setSmoothingEnabled(this.renderer.context,this.antialias),this.canvas=this.renderer.view,this.context=this.renderer.context}else this.renderType=d.WEBGL,this.renderer=new c.WebGLRenderer(this.width,this.height,this.stage.canvas,this.transparent,this.antialias),this.canvas=this.renderer.view,this.context=null;d.Canvas.addToDOM(this.renderer.view,this.parent,!0),d.Canvas.setTouchAction(this.renderer.view)},loadComplete:function(){this._loadComplete=!0,this.state.loadComplete()},update:function(a){this.time.update(a),this._paused?(this.renderer.render(this.stage._stage),this.plugins.render(),this.state.render()):(this.plugins.preUpdate(),this.physics.preUpdate(),this.stage.update(),this.input.update(),this.tweens.update(),this.sound.update(),this.world.update(),this.particles.update(),this.state.update(),this.plugins.update(),this.world.postUpdate(),this.plugins.postUpdate(),this.renderType!==d.HEADLESS&&(this.renderer.render(this.stage._stage),this.plugins.render(),this.state.render(),this.plugins.postRender()))},destroy:function(){this.raf.stop(),this.input.destroy(),this.state.destroy(),this.state=null,this.cache=null,this.input=null,this.load=null,this.sound=null,this.stage=null,this.time=null,this.world=null,this.isBooted=!1}},Object.defineProperty(d.Game.prototype,"paused",{get:function(){return this._paused},set:function(a){a===!0?this._paused===!1&&(this._paused=!0,this.onPause.dispatch(this)):this._paused&&(this._paused=!1,this.onResume.dispatch(this))}}),d.Input=function(a){this.game=a,this.hitCanvas=null,this.hitContext=null},d.Input.MOUSE_OVERRIDES_TOUCH=0,d.Input.TOUCH_OVERRIDES_MOUSE=1,d.Input.MOUSE_TOUCH_COMBINE=2,d.Input.prototype={pollRate:0,_pollCounter:0,_oldPosition:null,_x:0,_y:0,disabled:!1,multiInputOverride:d.Input.MOUSE_TOUCH_COMBINE,position:null,speed:null,circle:null,scale:null,maxPointers:10,currentPointers:0,tapRate:200,doubleTapRate:300,holdRate:2e3,justPressedRate:200,justReleasedRate:200,recordPointerHistory:!1,recordRate:100,recordLimit:100,pointer1:null,pointer2:null,pointer3:null,pointer4:null,pointer5:null,pointer6:null,pointer7:null,pointer8:null,pointer9:null,pointer10:null,activePointer:null,mousePointer:null,mouse:null,keyboard:null,touch:null,mspointer:null,onDown:null,onUp:null,onTap:null,onHold:null,interactiveItems:new d.LinkedList,boot:function(){this.mousePointer=new d.Pointer(this.game,0),this.pointer1=new d.Pointer(this.game,1),this.pointer2=new d.Pointer(this.game,2),this.mouse=new d.Mouse(this.game),this.keyboard=new d.Keyboard(this.game),this.touch=new d.Touch(this.game),this.mspointer=new d.MSPointer(this.game),this.onDown=new d.Signal,this.onUp=new d.Signal,this.onTap=new d.Signal,this.onHold=new d.Signal,this.scale=new d.Point(1,1),this.speed=new d.Point,this.position=new d.Point,this._oldPosition=new d.Point,this.circle=new d.Circle(0,0,44),this.activePointer=this.mousePointer,this.currentPointers=0,this.hitCanvas=document.createElement("canvas"),this.hitCanvas.width=1,this.hitCanvas.height=1,this.hitContext=this.hitCanvas.getContext("2d"),this.mouse.start(),this.keyboard.start(),this.touch.start(),this.mspointer.start(),this.mousePointer.active=!0},destroy:function(){this.mouse.stop(),this.keyboard.stop(),this.touch.stop(),this.mspointer.stop()},addPointer:function(){for(var a=0,b=10;b>0;b--)null===this["pointer"+b]&&(a=b);return 0===a?(console.warn("You can only have 10 Pointer objects"),null):(this["pointer"+a]=new d.Pointer(this.game,a),this["pointer"+a])},update:function(){return this.pollRate>0&&this._pollCounter=b;b++)this["pointer"+b]&&this["pointer"+b].reset();this.currentPointers=0,this.game.stage.canvas.style.cursor="default",a===!0&&(this.onDown.dispose(),this.onUp.dispose(),this.onTap.dispose(),this.onHold.dispose(),this.onDown=new d.Signal,this.onUp=new d.Signal,this.onTap=new d.Signal,this.onHold=new d.Signal,this.interactiveItems.callAll("reset")),this._pollCounter=0}},resetSpeed:function(a,b){this._oldPosition.setTo(a,b),this.speed.setTo(0,0)},startPointer:function(a){if(this.maxPointers<10&&this.totalActivePointers==this.maxPointers)return null;if(this.pointer1.active===!1)return this.pointer1.start(a);if(this.pointer2.active===!1)return this.pointer2.start(a);for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].active===!1)return this["pointer"+b].start(a);return null},updatePointer:function(a){if(this.pointer1.active&&this.pointer1.identifier==a.identifier)return this.pointer1.move(a);if(this.pointer2.active&&this.pointer2.identifier==a.identifier)return this.pointer2.move(a);for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].active&&this["pointer"+b].identifier==a.identifier)return this["pointer"+b].move(a);return null},stopPointer:function(a){if(this.pointer1.active&&this.pointer1.identifier==a.identifier)return this.pointer1.stop(a);if(this.pointer2.active&&this.pointer2.identifier==a.identifier)return this.pointer2.stop(a);for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].active&&this["pointer"+b].identifier==a.identifier)return this["pointer"+b].stop(a);return null},getPointer:function(a){if(a=a||!1,this.pointer1.active==a)return this.pointer1;if(this.pointer2.active==a)return this.pointer2;for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].active==a)return this["pointer"+b];return null},getPointerFromIdentifier:function(a){if(this.pointer1.identifier==a)return this.pointer1;if(this.pointer2.identifier==a)return this.pointer2;for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].identifier==a)return this["pointer"+b];return null}},Object.defineProperty(d.Input.prototype,"x",{get:function(){return this._x},set:function(a){this._x=Math.floor(a)}}),Object.defineProperty(d.Input.prototype,"y",{get:function(){return this._y},set:function(a){this._y=Math.floor(a)}}),Object.defineProperty(d.Input.prototype,"pollLocked",{get:function(){return this.pollRate>0&&this._pollCounter=a;a++)this["pointer"+a]&&this["pointer"+a].active&&this.currentPointers++;return this.currentPointers}}),Object.defineProperty(d.Input.prototype,"worldX",{get:function(){return this.game.camera.view.x+this.x}}),Object.defineProperty(d.Input.prototype,"worldY",{get:function(){return this.game.camera.view.y+this.y}}),d.Key=function(a,b){this.game=a,this.isDown=!1,this.isUp=!1,this.altKey=!1,this.ctrlKey=!1,this.shiftKey=!1,this.timeDown=0,this.duration=0,this.timeUp=0,this.repeats=0,this.keyCode=b,this.onDown=new d.Signal,this.onUp=new d.Signal},d.Key.prototype={processKeyDown:function(a){this.altKey=a.altKey,this.ctrlKey=a.ctrlKey,this.shiftKey=a.shiftKey,this.isDown?(this.duration=a.timeStamp-this.timeDown,this.repeats++):(this.isDown=!0,this.isUp=!1,this.timeDown=a.timeStamp,this.duration=0,this.repeats=0,this.onDown.dispatch(this))},processKeyUp:function(a){this.isDown=!1,this.isUp=!0,this.timeUp=a.timeStamp,this.onUp.dispatch(this)},justPressed:function(a){return"undefined"==typeof a&&(a=250),this.isDown&&this.duration=this.game.input.holdRate&&((this.game.input.multiInputOverride==d.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==d.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==d.Input.TOUCH_OVERRIDES_MOUSE&&0===this.game.input.currentPointers)&&this.game.input.onHold.dispatch(this),this._holdSent=!0),this.game.input.recordPointerHistory&&this.game.time.now>=this._nextDrop&&(this._nextDrop=this.game.time.now+this.game.input.recordRate,this._history.push({x:this.position.x,y:this.position.y}),this._history.length>this.game.input.recordLimit&&this._history.shift()))},move:function(a){if(!this.game.input.pollLocked){if("undefined"!=typeof a.button&&(this.button=a.button),this.clientX=a.clientX,this.clientY=a.clientY,this.pageX=a.pageX,this.pageY=a.pageY,this.screenX=a.screenX,this.screenY=a.screenY,this.x=(this.pageX-this.game.stage.offset.x)*this.game.input.scale.x,this.y=(this.pageY-this.game.stage.offset.y)*this.game.input.scale.y,this.position.setTo(this.x,this.y),this.circle.x=this.x,this.circle.y=this.y,(this.game.input.multiInputOverride==d.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==d.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==d.Input.TOUCH_OVERRIDES_MOUSE&&0===this.game.input.currentPointers)&&(this.game.input.activePointer=this,this.game.input.x=this.x,this.game.input.y=this.y,this.game.input.position.setTo(this.game.input.x,this.game.input.y),this.game.input.circle.x=this.game.input.x,this.game.input.circle.y=this.game.input.y),this.game.paused)return this;if(null!==this.targetObject&&this.targetObject.isDragged===!0)return this.targetObject.update(this)===!1&&(this.targetObject=null),this;if(this._highestRenderOrderID=-1,this._highestRenderObject=null,this._highestInputPriorityID=-1,this.game.input.interactiveItems.total>0){var b=this.game.input.interactiveItems.next;do(b.pixelPerfect||b.priorityID>this._highestInputPriorityID||b.priorityID==this._highestInputPriorityID&&b.sprite.renderOrderID>this._highestRenderOrderID)&&b.checkPointerOver(this)&&(this._highestRenderOrderID=b.sprite.renderOrderID,this._highestInputPriorityID=b.priorityID,this._highestRenderObject=b),b=b.next;while(null!=b)}return null==this._highestRenderObject?this.targetObject&&(this.targetObject._pointerOutHandler(this),this.targetObject=null):null==this.targetObject?(this.targetObject=this._highestRenderObject,this._highestRenderObject._pointerOverHandler(this)):this.targetObject==this._highestRenderObject?this._highestRenderObject.update(this)===!1&&(this.targetObject=null):(this.targetObject._pointerOutHandler(this),this.targetObject=this._highestRenderObject,this.targetObject._pointerOverHandler(this)),this}},leave:function(a){this.withinGame=!1,this.move(a)},stop:function(a){if(this._stateReset)return a.preventDefault(),void 0;if(this.timeUp=this.game.time.now,(this.game.input.multiInputOverride==d.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==d.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==d.Input.TOUCH_OVERRIDES_MOUSE&&0===this.game.input.currentPointers)&&(this.game.input.onUp.dispatch(this,a),this.duration>=0&&this.duration<=this.game.input.tapRate&&(this.timeUp-this.previousTapTime0&&(this.active=!1),this.withinGame=!1,this.isDown=!1,this.isUp=!0,this.isMouse===!1&&this.game.input.currentPointers--,this.game.input.interactiveItems.total>0){var b=this.game.input.interactiveItems.next;do b&&b._releasedHandler(this),b=b.next;while(null!=b)}return this.targetObject&&this.targetObject._releasedHandler(this),this.targetObject=null,this},justPressed:function(a){return a=a||this.game.input.justPressedRate,this.isDown===!0&&this.timeDown+a>this.game.time.now},justReleased:function(a){return a=a||this.game.input.justReleasedRate,this.isUp===!0&&this.timeUp+a>this.game.time.now},reset:function(){this.isMouse===!1&&(this.active=!1),this.identifier=null,this.isDown=!1,this.isUp=!0,this.totalTouches=0,this._holdSent=!1,this._history.length=0,this._stateReset=!0,this.targetObject&&this.targetObject._releasedHandler(this),this.targetObject=null}},Object.defineProperty(d.Pointer.prototype,"duration",{get:function(){return this.isUp?-1:this.game.time.now-this.timeDown}}),Object.defineProperty(d.Pointer.prototype,"worldX",{get:function(){return this.game.world.camera.x+this.x}}),Object.defineProperty(d.Pointer.prototype,"worldY",{get:function(){return this.game.world.camera.y+this.y}}),d.Touch=function(a){this.game=a,this.disabled=!1,this.callbackContext=this.game,this.touchStartCallback=null,this.touchMoveCallback=null,this.touchEndCallback=null,this.touchEnterCallback=null,this.touchLeaveCallback=null,this.touchCancelCallback=null,this.preventDefault=!0,this.event=null,this._onTouchStart=null,this._onTouchMove=null,this._onTouchEnd=null,this._onTouchEnter=null,this._onTouchLeave=null,this._onTouchCancel=null,this._onTouchMove=null},d.Touch.prototype={start:function(){var a=this;this.game.device.touch&&(this._onTouchStart=function(b){return a.onTouchStart(b)},this._onTouchMove=function(b){return a.onTouchMove(b)},this._onTouchEnd=function(b){return a.onTouchEnd(b)},this._onTouchEnter=function(b){return a.onTouchEnter(b)},this._onTouchLeave=function(b){return a.onTouchLeave(b)},this._onTouchCancel=function(b){return a.onTouchCancel(b)},this.game.renderer.view.addEventListener("touchstart",this._onTouchStart,!1),this.game.renderer.view.addEventListener("touchmove",this._onTouchMove,!1),this.game.renderer.view.addEventListener("touchend",this._onTouchEnd,!1),this.game.renderer.view.addEventListener("touchenter",this._onTouchEnter,!1),this.game.renderer.view.addEventListener("touchleave",this._onTouchLeave,!1),this.game.renderer.view.addEventListener("touchcancel",this._onTouchCancel,!1))},consumeDocumentTouches:function(){this._documentTouchMove=function(a){a.preventDefault()},document.addEventListener("touchmove",this._documentTouchMove,!1)},onTouchStart:function(a){if(this.event=a,this.touchStartCallback&&this.touchStartCallback.call(this.callbackContext,a),!this.game.input.disabled&&!this.disabled){this.preventDefault&&a.preventDefault();for(var b=0;bc;c++)this._pointerData[c]={id:c,x:0,y:0,isDown:!1,isUp:!1,isOver:!1,isOut:!1,timeOver:0,timeOut:0,timeDown:0,timeUp:0,downDuration:0,isDragged:!1};this.snapOffset=new d.Point,this.enabled=!0,this.sprite.events&&null==this.sprite.events.onInputOver&&(this.sprite.events.onInputOver=new d.Signal,this.sprite.events.onInputOut=new d.Signal,this.sprite.events.onInputDown=new d.Signal,this.sprite.events.onInputUp=new d.Signal,this.sprite.events.onDragStart=new d.Signal,this.sprite.events.onDragStop=new d.Signal)}return this.sprite},reset:function(){this.enabled=!1;for(var a=0;10>a;a++)this._pointerData[a]={id:a,x:0,y:0,isDown:!1,isUp:!1,isOver:!1,isOut:!1,timeOver:0,timeOut:0,timeDown:0,timeUp:0,downDuration:0,isDragged:!1}},stop:function(){this.enabled!==!1&&(this.enabled=!1,this.game.input.interactiveItems.remove(this))},destroy:function(){this.enabled&&(this.enabled=!1,this.game.input.interactiveItems.remove(this),this.stop(),this.sprite=null)},pointerX:function(a){return a=a||0,this._pointerData[a].x},pointerY:function(a){return a=a||0,this._pointerData[a].y},pointerDown:function(a){return a=a||0,this._pointerData[a].isDown},pointerUp:function(a){return a=a||0,this._pointerData[a].isUp},pointerTimeDown:function(a){return a=a||0,this._pointerData[a].timeDown},pointerTimeUp:function(a){return a=a||0,this._pointerData[a].timeUp},pointerOver:function(a){if(this.enabled){if("undefined"!=typeof a)return this._pointerData[a].isOver;for(var b=0;10>b;b++)if(this._pointerData[b].isOver)return!0}return!1},pointerOut:function(a){if(this.enabled){if("undefined"!=typeof a)return this._pointerData[a].isOut;for(var b=0;10>b;b++)if(this._pointerData[b].isOut)return!0}return!1},pointerTimeOver:function(a){return a=a||0,this._pointerData[a].timeOver},pointerTimeOut:function(a){return a=a||0,this._pointerData[a].timeOut},pointerDragged:function(a){return a=a||0,this._pointerData[a].isDragged},checkPointerOver:function(a){return this.enabled===!1||this.sprite.visible===!1||this.sprite.group&&this.sprite.group.visible===!1?!1:(this.sprite.getLocalUnmodifiedPosition(this._tempPoint,a.x,a.y),this._tempPoint.x>=0&&this._tempPoint.x<=this.sprite.currentFrame.width&&this._tempPoint.y>=0&&this._tempPoint.y<=this.sprite.currentFrame.height?this.pixelPerfect?this.checkPixel(this._tempPoint.x,this._tempPoint.y):!0:void 0)},checkPixel:function(a,b){if(this.sprite.texture.baseTexture.source){this.game.input.hitContext.clearRect(0,0,1,1),a+=this.sprite.texture.frame.x,b+=this.sprite.texture.frame.y,this.game.input.hitContext.drawImage(this.sprite.texture.baseTexture.source,a,b,1,1,0,0,1,1);var c=this.game.input.hitContext.getImageData(0,0,1,1);if(c.data[3]>=this.pixelPerfectAlpha)return!0}return!1},update:function(a){return this.enabled===!1||this.sprite.visible===!1||this.sprite.group&&this.sprite.group.visible===!1?(this._pointerOutHandler(a),!1):this.draggable&&this._draggedPointerID==a.id?this.updateDrag(a):this._pointerData[a.id].isOver===!0?this.checkPointerOver(a)?(this._pointerData[a.id].x=a.x-this.sprite.x,this._pointerData[a.id].y=a.y-this.sprite.y,!0):(this._pointerOutHandler(a),!1):void 0},_pointerOverHandler:function(a){this._pointerData[a.id].isOver===!1&&(this._pointerData[a.id].isOver=!0,this._pointerData[a.id].isOut=!1,this._pointerData[a.id].timeOver=this.game.time.now,this._pointerData[a.id].x=a.x-this.sprite.x,this._pointerData[a.id].y=a.y-this.sprite.y,this.useHandCursor&&this._pointerData[a.id].isDragged===!1&&(this.game.stage.canvas.style.cursor="pointer"),this.sprite.events.onInputOver.dispatch(this.sprite,a))},_pointerOutHandler:function(a){this._pointerData[a.id].isOver=!1,this._pointerData[a.id].isOut=!0,this._pointerData[a.id].timeOut=this.game.time.now,this.useHandCursor&&this._pointerData[a.id].isDragged===!1&&(this.game.stage.canvas.style.cursor="default"),this.sprite&&this.sprite.events&&this.sprite.events.onInputOut.dispatch(this.sprite,a)},_touchedHandler:function(a){return this._pointerData[a.id].isDown===!1&&this._pointerData[a.id].isOver===!0&&(this._pointerData[a.id].isDown=!0,this._pointerData[a.id].isUp=!1,this._pointerData[a.id].timeDown=this.game.time.now,this.sprite.events.onInputDown.dispatch(this.sprite,a),this.draggable&&this.isDragged===!1&&this.startDrag(a),this.bringToTop&&this.sprite.bringToTop()),this.consumePointerEvent},_releasedHandler:function(a){this._pointerData[a.id].isDown&&a.isUp&&(this._pointerData[a.id].isDown=!1,this._pointerData[a.id].isUp=!0,this._pointerData[a.id].timeUp=this.game.time.now,this._pointerData[a.id].downDuration=this._pointerData[a.id].timeUp-this._pointerData[a.id].timeDown,this.checkPointerOver(a)?this.sprite.events.onInputUp.dispatch(this.sprite,a):this.useHandCursor&&(this.game.stage.canvas.style.cursor="default"),this.draggable&&this.isDragged&&this._draggedPointerID==a.id&&this.stopDrag(a))},updateDrag:function(a){return a.isUp?(this.stopDrag(a),!1):(this.allowHorizontalDrag&&(this.sprite.x=a.x+this._dragPoint.x+this.dragOffset.x),this.allowVerticalDrag&&(this.sprite.y=a.y+this._dragPoint.y+this.dragOffset.y),this.boundsRect&&this.checkBoundsRect(),this.boundsSprite&&this.checkBoundsSprite(),this.snapOnDrag&&(this.sprite.x=Math.round(this.sprite.x/this.snapX)*this.snapX,this.sprite.y=Math.round(this.sprite.y/this.snapY)*this.snapY),!0)},justOver:function(a,b){return a=a||0,b=b||500,this._pointerData[a].isOver&&this.overDuration(a)a;a++)this._pointerData[a].isDragged=!1;this.draggable=!1,this.isDragged=!1,this._draggedPointerID=-1},startDrag:function(a){this.isDragged=!0,this._draggedPointerID=a.id,this._pointerData[a.id].isDragged=!0,this.dragFromCenter?(this.sprite.centerOn(a.x,a.y),this._dragPoint.setTo(this.sprite.x-a.x,this.sprite.y-a.y)):this._dragPoint.setTo(this.sprite.x-a.x,this.sprite.y-a.y),this.updateDrag(a),this.bringToTop&&this.sprite.bringToTop(),this.sprite.events.onDragStart.dispatch(this.sprite,a)},stopDrag:function(a){this.isDragged=!1,this._draggedPointerID=-1,this._pointerData[a.id].isDragged=!1,this.snapOnRelease&&(this.sprite.x=Math.round(this.sprite.x/this.snapX)*this.snapX,this.sprite.y=Math.round(this.sprite.y/this.snapY)*this.snapY),this.sprite.events.onDragStop.dispatch(this.sprite,a),this.sprite.events.onInputUp.dispatch(this.sprite,a),this.checkPointerOver(a)===!1&&this._pointerOutHandler(a)},setDragLock:function(a,b){"undefined"==typeof a&&(a=!0),"undefined"==typeof b&&(b=!0),this.allowHorizontalDrag=a,this.allowVerticalDrag=b},enableSnap:function(a,b,c,d){"undefined"==typeof c&&(c=!0),"undefined"==typeof d&&(d=!1),this.snapX=a,this.snapY=b,this.snapOnDrag=c,this.snapOnRelease=d},disableSnap:function(){this.snapOnDrag=!1,this.snapOnRelease=!1},checkBoundsRect:function(){this.sprite.xthis.boundsRect.right&&(this.sprite.x=this.boundsRect.right-this.sprite.width),this.sprite.ythis.boundsRect.bottom&&(this.sprite.y=this.boundsRect.bottom-this.sprite.height)},checkBoundsSprite:function(){this.sprite.xthis.boundsSprite.x+this.boundsSprite.width&&(this.sprite.x=this.boundsSprite.x+this.boundsSprite.width-this.sprite.width),this.sprite.ythis.boundsSprite.y+this.boundsSprite.height&&(this.sprite.y=this.boundsSprite.y+this.boundsSprite.height-this.sprite.height)}},d.Events=function(a){this.parent=a,this.onAddedToGroup=new d.Signal,this.onRemovedFromGroup=new d.Signal,this.onKilled=new d.Signal,this.onRevived=new d.Signal,this.onOutOfBounds=new d.Signal,this.onInputOver=null,this.onInputOut=null,this.onInputDown=null,this.onInputUp=null,this.onDragStart=null,this.onDragStop=null,this.onAnimationStart=null,this.onAnimationComplete=null,this.onAnimationLoop=null},d.Events.prototype={destroy:function(){this.parent=null,this.onAddedToGroup.dispose(),this.onRemovedFromGroup.dispose(),this.onKilled.dispose(),this.onRevived.dispose(),this.onOutOfBounds.dispose(),this.onInputOver&&(this.onInputOver.dispose(),this.onInputOut.dispose(),this.onInputDown.dispose(),this.onInputUp.dispose(),this.onDragStart.dispose(),this.onDragStop.dispose()),this.onAnimationStart&&(this.onAnimationStart.dispose(),this.onAnimationComplete.dispose(),this.onAnimationLoop.dispose())}},d.GameObjectFactory=function(a){this.game=a,this.world=this.game.world},d.GameObjectFactory.prototype={existing:function(a){return this.world.add(a)},sprite:function(a,b,c,d){return this.world.create(a,b,c,d)},child:function(a,b,c,d,e){return a.create(b,c,d,e)},tween:function(a){return this.game.tweens.create(a)},group:function(a,b){return new d.Group(this.game,a,b)},audio:function(a,b,c,d){return this.game.sound.add(a,b,c,d)},tileSprite:function(a,b,c,e,f,g){return this.world.add(new d.TileSprite(this.game,a,b,c,e,f,g))},text:function(a,b,c,e){return this.world.add(new d.Text(this.game,a,b,c,e))},button:function(a,b,c,e,f,g,h,i){return this.world.add(new d.Button(this.game,a,b,c,e,f,g,h,i))},graphics:function(a,b){return this.world.add(new d.Graphics(this.game,a,b))},emitter:function(a,b,c){return this.game.particles.add(new d.Particles.Arcade.Emitter(this.game,a,b,c))},bitmapText:function(a,b,c,e){return this.world.add(new d.BitmapText(this.game,a,b,c,e))},tilemap:function(a){return new d.Tilemap(this.game,a)},tileset:function(a){return this.game.cache.getTileset(a)},tilemapLayer:function(a,b,c,e,f,g,h){return this.world.add(new d.TilemapLayer(this.game,a,b,c,e,f,g,h))},renderTexture:function(a,b,c){var e=new d.RenderTexture(this.game,a,b,c);return this.game.cache.addRenderTexture(a,e),e},bitmapData:function(a,b){return new d.BitmapData(this.game,a,b)},filter:function(a){var b=Array.prototype.splice.call(arguments,1),a=new d.Filter[a](this.game);return a.init.apply(a,b),a}},d.BitmapData=function(a,b,e){"undefined"==typeof b&&(b=256),"undefined"==typeof e&&(e=256),this.game=a,this.name="",this.width=b,this.height=e,this.canvas=d.Canvas.create(b,e),this.context=this.canvas.getContext("2d"),this.imageData=this.context.getImageData(0,0,b,e),this.pixels=this.imageData.data.buffer?this.imageData.data.buffer:this.imageData.data,this.baseTexture=new c.BaseTexture(this.canvas),this.texture=new c.Texture(this.baseTexture),this.textureFrame=new d.Frame(0,0,0,b,e,"bitmapData",a.rnd.uuid()),this.type=d.BITMAPDATA,this._dirty=!1},d.BitmapData.prototype={add:function(a){a.loadTexture(this)},addTo:function(a){for(var b=0;b=0&&a<=this.width&&b>=0&&b<=this.height&&(this.pixels[b*this.width+a]=f<<24|e<<16|d<<8|c,this.context.putImageData(this.imageData,0,0),this._dirty=!0)},setPixel:function(a,b,c,d,e){this.setPixel32(a,b,c,d,e,255)},getPixel:function(a,b){return a>=0&&a<=this.width&&b>=0&&b<=this.height?this.data32[b*this.width+a]:void 0},getPixel32:function(a,b){return a>=0&&a<=this.width&&b>=0&&b<=this.height?this.data32[b*this.width+a]:void 0},getPixels:function(a){return this.context.getImageData(a.x,a.y,a.width,a.height)},arc:function(a,b,c,d,e,f){return"undefined"==typeof f&&(f=!1),this._dirty=!0,this.context.arc(a,b,c,d,e,f),this},arcTo:function(a,b,c,d,e){return this._dirty=!0,this.context.arcTo(a,b,c,d,e),this},beginFill:function(a){return this.fillStyle(a),this},beginLinearGradientFill:function(a,b,c,d,e,f){for(var g=this.createLinearGradient(c,d,e,f),h=0,i=a.length;i>h;h++)g.addColorStop(b[h],a[h]);return this.fillStyle(g),this},beginLinearGradientStroke:function(a,b,c,d,e,f){for(var g=this.createLinearGradient(c,d,e,f),h=0,i=a.length;i>h;h++)g.addColorStop(b[h],a[h]);return this.strokeStyle(g),this},beginRadialGradientStroke:function(a,b,c,d,e,f,g,h){for(var i=this.createRadialGradient(c,d,e,f,g,h),j=0,k=a.length;k>j;j++)i.addColorStop(b[j],a[j]);return this.strokeStyle(i),this},beginPath:function(){return this.context.beginPath(),this},beginStroke:function(a){return this.strokeStyle(a),this},bezierCurveTo:function(a,b,c,d,e,f){return this._dirty=!0,this.context.bezierCurveTo(a,b,c,d,e,f),this},circle:function(a,b,c){return this.arc(a,b,c,0,2*Math.PI),this},clearRect:function(a,b,c,d){return this._dirty=!0,this.context.clearRect(a,b,c,d),this},clip:function(){return this._dirty=!0,this.context.clip(),this},closePath:function(){return this._dirty=!0,this.context.closePath(),this},createLinearGradient:function(a,b,c,d){return this.context.createLinearGradient(a,b,c,d)},createRadialGradient:function(a,b,c,d,e,f){return this.context.createRadialGradient(a,b,c,d,e,f)},ellipse:function(a,b,c,d){var e=.5522848,f=c/2*e,g=d/2*e,h=a+c,i=b+d,j=a+c/2,k=b+d/2;return this.moveTo(a,k),this.bezierCurveTo(a,k-g,j-f,b,j,b),this.bezierCurveTo(j+f,b,h,k-g,h,k),this.bezierCurveTo(h,k+g,j+f,i,j,i),this.bezierCurveTo(j-f,i,a,k+g,a,k),this},fill:function(){return this._dirty=!0,this.context.fill(),this},fillRect:function(a,b,c,d){return this._dirty=!0,this.context.fillRect(a,b,c,d),this},fillStyle:function(a){return this.context.fillStyle=a,this},font:function(a){return this.context.font=a,this},globalAlpha:function(a){return this.context.globalAlpha=a,this},globalCompositeOperation:function(a){return this.context.globalCompositeOperation=a,this},lineCap:function(a){return this.context.lineCap=a,this},lineDashOffset:function(a){return this.context.lineDashOffset=a,this},lineJoin:function(a){return this.context.lineJoin=a,this},lineWidth:function(a){return this.context.lineWidth=a,this},miterLimit:function(a){return this.context.miterLimit=a,this},lineTo:function(a,b){return this._dirty=!0,this.context.lineTo(a,b),this},moveTo:function(a,b){return this.context.moveTo(a,b),this},quadraticCurveTo:function(a,b,c,d){return this._dirty=!0,this.context.quadraticCurveTo(a,b,c,d),this},rect:function(a,b,c,d){return this._dirty=!0,this.context.rect(a,b,c,d),this},restore:function(){return this._dirty=!0,this.context.restore(),this},rotate:function(a){return this._dirty=!0,this.context.rotate(a),this},setStrokeStyle:function(a,b,c,d,e){return"undefined"==typeof a&&(a=1),"undefined"==typeof b&&(b="butt"),"undefined"==typeof c&&(c="miter"),"undefined"==typeof d&&(d=10),e=!1,this.lineWidth(a),this.lineCap(b),this.lineJoin(c),this.miterLimit(d),this},save:function(){return this._dirty=!0,this.context.save(),this},scale:function(a,b){return this._dirty=!0,this.context.scale(a,b),this},scrollPathIntoView:function(){return this._dirty=!0,this.context.scrollPathIntoView(),this},stroke:function(){return this._dirty=!0,this.context.stroke(),this},strokeRect:function(a,b,c,d){return this._dirty=!0,this.context.strokeRect(a,b,c,d),this},strokeStyle:function(a){return this.context.strokeStyle=a,this},render:function(){this._dirty&&(this.game.renderType==d.WEBGL&&c.texturesToUpdate.push(this.baseTexture),this._dirty=!1)}},d.BitmapData.prototype.mt=d.BitmapData.prototype.moveTo,d.BitmapData.prototype.lt=d.BitmapData.prototype.lineTo,d.BitmapData.prototype.at=d.BitmapData.prototype.arcTo,d.BitmapData.prototype.bt=d.BitmapData.prototype.bezierCurveTo,d.BitmapData.prototype.qt=d.BitmapData.prototype.quadraticCurveTo,d.BitmapData.prototype.a=d.BitmapData.prototype.arc,d.BitmapData.prototype.r=d.BitmapData.prototype.rect,d.BitmapData.prototype.cp=d.BitmapData.prototype.closePath,d.BitmapData.prototype.c=d.BitmapData.prototype.clear,d.BitmapData.prototype.f=d.BitmapData.prototype.beginFill,d.BitmapData.prototype.lf=d.BitmapData.prototype.beginLinearGradientFill,d.BitmapData.prototype.rf=d.BitmapData.prototype.beginRadialGradientFill,d.BitmapData.prototype.ef=d.BitmapData.prototype.endFill,d.BitmapData.prototype.ss=d.BitmapData.prototype.setStrokeStyle,d.BitmapData.prototype.s=d.BitmapData.prototype.beginStroke,d.BitmapData.prototype.ls=d.BitmapData.prototype.beginLinearGradientStroke,d.BitmapData.prototype.rs=d.BitmapData.prototype.beginRadialGradientStroke,d.BitmapData.prototype.dr=d.BitmapData.prototype.rect,d.BitmapData.prototype.dc=d.BitmapData.prototype.circle,d.BitmapData.prototype.de=d.BitmapData.prototype.ellipse,d.Sprite=function(a,b,e,f,g){b=b||0,e=e||0,f=f||null,g=g||null,this.game=a,this.exists=!0,this.alive=!0,this.group=null,this.name="",this.type=d.SPRITE,this.renderOrderID=-1,this.lifespan=0,this.events=new d.Events(this),this.animations=new d.AnimationManager(this),this.input=new d.InputHandler(this),this.key=f,this.currentFrame=null,f instanceof d.RenderTexture?(c.Sprite.call(this,f),this.currentFrame=this.game.cache.getTextureFrame(f.name)):f instanceof d.BitmapData?(c.Sprite.call(this,f.texture,f.textureFrame),this.currentFrame=f.textureFrame):f instanceof c.Texture?(c.Sprite.call(this,f),this.currentFrame=g):(null===f||"undefined"==typeof f?(f="__default",this.key=f):"string"==typeof f&&this.game.cache.checkImageKey(f)===!1&&(f="__missing",this.key=f),c.Sprite.call(this,c.TextureCache[f]),this.game.cache.isSpriteSheet(f)?(this.animations.loadFrameData(this.game.cache.getFrameData(f)),null!==g&&("string"==typeof g?this.frameName=g:this.frame=g)):this.currentFrame=this.game.cache.getFrame(f)),this.textureRegion=new d.Rectangle(this.texture.frame.x,this.texture.frame.y,this.texture.frame.width,this.texture.frame.height),this.anchor=new d.Point,this.x=b,this.y=e,this.position.x=b,this.position.y=e,this.world=new d.Point(b,e),this.autoCull=!1,this.scale=new d.Point(1,1),this._cache={dirty:!1,a00:-1,a01:-1,a02:-1,a10:-1,a11:-1,a12:-1,id:-1,i01:-1,i10:-1,idi:-1,left:null,right:null,top:null,bottom:null,prevX:b,prevY:e,x:-1,y:-1,scaleX:1,scaleY:1,width:this.currentFrame.sourceSizeW,height:this.currentFrame.sourceSizeH,halfWidth:Math.floor(this.currentFrame.sourceSizeW/2),halfHeight:Math.floor(this.currentFrame.sourceSizeH/2),calcWidth:-1,calcHeight:-1,frameID:-1,frameWidth:this.currentFrame.width,frameHeight:this.currentFrame.height,cameraVisible:!0,cropX:0,cropY:0,cropWidth:this.currentFrame.sourceSizeW,cropHeight:this.currentFrame.sourceSizeH},this.offset=new d.Point,this.center=new d.Point(b+Math.floor(this._cache.width/2),e+Math.floor(this._cache.height/2)),this.topLeft=new d.Point(b,e),this.topRight=new d.Point(b+this._cache.width,e),this.bottomRight=new d.Point(b+this._cache.width,e+this._cache.height),this.bottomLeft=new d.Point(b,e+this._cache.height),this.bounds=new d.Rectangle(b,e,this._cache.width,this._cache.height),this.body=new d.Physics.Arcade.Body(this),this.health=1,this.inWorld=d.Rectangle.intersects(this.bounds,this.game.world.bounds),this.inWorldThreshold=0,this.outOfBoundsKill=!1,this._outOfBoundsFired=!1,this.fixedToCamera=!1,this.cameraOffset=new d.Point,this.crop=new d.Rectangle(0,0,this._cache.width,this._cache.height),this.cropEnabled=!1,this.updateCache(),this.updateBounds() -},d.Sprite.prototype=Object.create(c.Sprite.prototype),d.Sprite.prototype.constructor=d.Sprite,d.Sprite.prototype.preUpdate=function(){return!this.exists||this.group&&!this.group.exists?(this.renderOrderID=-1,!1):this.lifespan>0&&(this.lifespan-=this.game.time.elapsed,this.lifespan<=0)?(this.kill(),!1):(this._cache.dirty=!1,this.visible&&(this.renderOrderID=this.game.world.currentRenderOrderID++),this.updateCache(),this.updateAnimation(),this.updateCrop(),(this._cache.dirty||this.world.x!==this._cache.prevX||this.world.y!==this._cache.prevY)&&this.updateBounds(),this.body&&this.body.preUpdate(),!0)},d.Sprite.prototype.updateCache=function(){this._cache.prevX=this.world.x,this._cache.prevY=this.world.y,this.fixedToCamera&&(this.x=this.game.camera.view.x+this.cameraOffset.x,this.y=this.game.camera.view.y+this.cameraOffset.y),this.world.setTo(this.game.camera.x+this.worldTransform[2],this.game.camera.y+this.worldTransform[5]),(this.worldTransform[1]!=this._cache.i01||this.worldTransform[3]!=this._cache.i10||this.worldTransform[0]!=this._cache.a00||this.worldTransform[41]!=this._cache.a11)&&(this._cache.a00=this.worldTransform[0],this._cache.a01=this.worldTransform[1],this._cache.a10=this.worldTransform[3],this._cache.a11=this.worldTransform[4],this._cache.i01=this.worldTransform[1],this._cache.i10=this.worldTransform[3],this._cache.scaleX=Math.sqrt(this._cache.a00*this._cache.a00+this._cache.a01*this._cache.a01),this._cache.scaleY=Math.sqrt(this._cache.a10*this._cache.a10+this._cache.a11*this._cache.a11),this._cache.a01*=-1,this._cache.a10*=-1,this._cache.id=1/(this._cache.a00*this._cache.a11+this._cache.a01*-this._cache.a10),this._cache.idi=1/(this._cache.a00*this._cache.a11+this._cache.i01*-this._cache.i10),this._cache.dirty=!0),this._cache.a02=this.worldTransform[2],this._cache.a12=this.worldTransform[5]},d.Sprite.prototype.updateAnimation=function(){(this.animations.update()||this.currentFrame&&this.currentFrame.uuid!=this._cache.frameID)&&(this._cache.frameID=this.currentFrame.uuid,this._cache.frameWidth=this.texture.frame.width,this._cache.frameHeight=this.texture.frame.height,this._cache.width=this.currentFrame.width,this._cache.height=this.currentFrame.height,this._cache.halfWidth=Math.floor(this._cache.width/2),this._cache.halfHeight=Math.floor(this._cache.height/2),this._cache.dirty=!0)},d.Sprite.prototype.updateCrop=function(){!this.cropEnabled||this.crop.width==this._cache.cropWidth&&this.crop.height==this._cache.cropHeight&&this.crop.x==this._cache.cropX&&this.crop.y==this._cache.cropY||(this.crop.floorAll(),this._cache.cropX=this.crop.x,this._cache.cropY=this.crop.y,this._cache.cropWidth=this.crop.width,this._cache.cropHeight=this.crop.height,this.texture.frame=this.crop,this.texture.width=this.crop.width,this.texture.height=this.crop.height,this.texture.updateFrame=!0,c.Texture.frameUpdates.push(this.texture))},d.Sprite.prototype.updateBounds=function(){this.offset.setTo(this._cache.a02-this.anchor.x*this.width,this._cache.a12-this.anchor.y*this.height),this.getLocalPosition(this.center,this.offset.x+this.width/2,this.offset.y+this.height/2),this.getLocalPosition(this.topLeft,this.offset.x,this.offset.y),this.getLocalPosition(this.topRight,this.offset.x+this.width,this.offset.y),this.getLocalPosition(this.bottomLeft,this.offset.x,this.offset.y+this.height),this.getLocalPosition(this.bottomRight,this.offset.x+this.width,this.offset.y+this.height),this._cache.left=d.Math.min(this.topLeft.x,this.topRight.x,this.bottomLeft.x,this.bottomRight.x),this._cache.right=d.Math.max(this.topLeft.x,this.topRight.x,this.bottomLeft.x,this.bottomRight.x),this._cache.top=d.Math.min(this.topLeft.y,this.topRight.y,this.bottomLeft.y,this.bottomRight.y),this._cache.bottom=d.Math.max(this.topLeft.y,this.topRight.y,this.bottomLeft.y,this.bottomRight.y),this.bounds.setTo(this._cache.left,this._cache.top,this._cache.right-this._cache.left,this._cache.bottom-this._cache.top),this.updateFrame=!0,this.inWorld===!1?(this.inWorld=d.Rectangle.intersects(this.bounds,this.game.world.bounds,this.inWorldThreshold),this.inWorld&&(this._outOfBoundsFired=!1)):(this.inWorld=d.Rectangle.intersects(this.bounds,this.game.world.bounds,this.inWorldThreshold),this.inWorld===!1&&(this.events.onOutOfBounds.dispatch(this),this._outOfBoundsFired=!0,this.outOfBoundsKill&&this.kill())),this._cache.cameraVisible=d.Rectangle.intersects(this.game.world.camera.screenView,this.bounds,0),this.autoCull&&(this.renderable=this._cache.cameraVisible),this.body&&this.body.updateBounds(this.center.x,this.center.y,this._cache.scaleX,this._cache.scaleY)},d.Sprite.prototype.getLocalPosition=function(a,b,c){return a.x=(this._cache.a11*this._cache.id*b+-this._cache.a01*this._cache.id*c+(this._cache.a12*this._cache.a01-this._cache.a02*this._cache.a11)*this._cache.id)*this.scale.x+this._cache.a02,a.y=(this._cache.a00*this._cache.id*c+-this._cache.a10*this._cache.id*b+(-this._cache.a12*this._cache.a00+this._cache.a02*this._cache.a10)*this._cache.id)*this.scale.y+this._cache.a12,a},d.Sprite.prototype.getLocalUnmodifiedPosition=function(a,b,c){return a.x=this._cache.a11*this._cache.idi*b+-this._cache.i01*this._cache.idi*c+(this._cache.a12*this._cache.i01-this._cache.a02*this._cache.a11)*this._cache.idi+this.anchor.x*this._cache.width,a.y=this._cache.a00*this._cache.idi*c+-this._cache.i10*this._cache.idi*b+(-this._cache.a12*this._cache.a00+this._cache.a02*this._cache.i10)*this._cache.idi+this.anchor.y*this._cache.height,a},d.Sprite.prototype.resetCrop=function(){this.crop=new d.Rectangle(0,0,this._cache.width,this._cache.height),this.texture.setFrame(this.crop),this.cropEnabled=!1},d.Sprite.prototype.postUpdate=function(){this.key instanceof d.BitmapData&&this.key._dirty&&this.key.render(),this.exists&&(this.body&&this.body.postUpdate(),this.fixedToCamera?(this._cache.x=this.game.camera.view.x+this.cameraOffset.x,this._cache.y=this.game.camera.view.y+this.cameraOffset.y):(this._cache.x=this.x,this._cache.y=this.y),this.world.setTo(this.game.camera.x+this.worldTransform[2],this.game.camera.y+this.worldTransform[5]),this.position.x=this._cache.x,this.position.y=this._cache.y)},d.Sprite.prototype.loadTexture=function(a,b){this.key=a,a instanceof d.RenderTexture?this.currentFrame=this.game.cache.getTextureFrame(a.name):a instanceof d.BitmapData?(this.setTexture(a.texture),this.currentFrame=a.textureFrame):a instanceof c.Texture?this.currentFrame=b:(("undefined"==typeof a||this.game.cache.checkImageKey(a)===!1)&&(a="__default",this.key=a),this.game.cache.isSpriteSheet(a)?(this.animations.loadFrameData(this.game.cache.getFrameData(a)),"undefined"!=typeof b&&("string"==typeof b?this.frameName=b:this.frame=b)):(this.currentFrame=this.game.cache.getFrame(a),this.setTexture(c.TextureCache[a])))},d.Sprite.prototype.centerOn=function(a,b){return this.x=a+(this.x-this.center.x),this.y=b+(this.y-this.center.y),this},d.Sprite.prototype.revive=function(a){return"undefined"==typeof a&&(a=1),this.alive=!0,this.exists=!0,this.visible=!0,this.health=a,this.events&&this.events.onRevived.dispatch(this),this},d.Sprite.prototype.kill=function(){return this.alive=!1,this.exists=!1,this.visible=!1,this.events&&this.events.onKilled.dispatch(this),this},d.Sprite.prototype.destroy=function(){this.group&&this.group.remove(this),this.input&&this.input.destroy(),this.events&&this.events.destroy(),this.animations&&this.animations.destroy(),this.alive=!1,this.exists=!1,this.visible=!1,this.game=null},d.Sprite.prototype.damage=function(a){return this.alive&&(this.health-=a,this.health<0&&this.kill()),this},d.Sprite.prototype.reset=function(a,b,c){return"undefined"==typeof c&&(c=1),this.x=a,this.y=b,this.position.x=this.x,this.position.y=this.y,this.alive=!0,this.exists=!0,this.visible=!0,this.renderable=!0,this._outOfBoundsFired=!1,this.health=c,this.body&&this.body.reset(),this},d.Sprite.prototype.bringToTop=function(){return this.group?this.group.bringToTop(this):this.game.world.bringToTop(this),this},d.Sprite.prototype.play=function(a,b,c,d){return this.animations?this.animations.play(a,b,c,d):void 0},Object.defineProperty(d.Sprite.prototype,"angle",{get:function(){return d.Math.wrapAngle(d.Math.radToDeg(this.rotation))},set:function(a){this.rotation=d.Math.degToRad(d.Math.wrapAngle(a))}}),Object.defineProperty(d.Sprite.prototype,"frame",{get:function(){return this.animations.frame},set:function(a){this.animations.frame=a}}),Object.defineProperty(d.Sprite.prototype,"frameName",{get:function(){return this.animations.frameName},set:function(a){this.animations.frameName=a}}),Object.defineProperty(d.Sprite.prototype,"inCamera",{get:function(){return this._cache.cameraVisible}}),Object.defineProperty(d.Sprite.prototype,"width",{get:function(){return this.scale.x*this.currentFrame.width},set:function(a){this.scale.x=a/this.currentFrame.width,this._cache.scaleX=a/this.currentFrame.width,this._width=a}}),Object.defineProperty(d.Sprite.prototype,"height",{get:function(){return this.scale.y*this.currentFrame.height},set:function(a){this.scale.y=a/this.currentFrame.height,this._cache.scaleY=a/this.currentFrame.height,this._height=a}}),Object.defineProperty(d.Sprite.prototype,"inputEnabled",{get:function(){return this.input.enabled},set:function(a){console.log("inputEnabled",a,this.input),a?this.input.enabled===!1&&this.input.start():this.input.enabled&&this.input.stop()}}),d.TileSprite=function(a,b,e,f,g,h,i){b=b||0,e=e||0,f=f||256,g=g||256,h=h||null,i=i||null,d.Sprite.call(this,a,b,e,h,i),this.texture=c.TextureCache[h],c.TilingSprite.call(this,this.texture,f,g),this.type=d.TILESPRITE,this.tileScale=new d.Point(1,1),this.tilePosition=new d.Point(0,0)},d.TileSprite.prototype=d.Utils.extend(!0,c.TilingSprite.prototype,d.Sprite.prototype),d.TileSprite.prototype.constructor=d.TileSprite,d.Text=function(a,b,e,f,g){b=b||0,e=e||0,f=f||"",g=g||"",this.game=a,this.exists=!0,this.alive=!0,this.group=null,this.name="",this.type=d.TEXT,this._text=f,this._style=g,c.Text.call(this,f,g),this.position.x=this.x=b,this.position.y=this.y=e,this.anchor=new d.Point,this.scale=new d.Point(1,1),this._cache={dirty:!1,a00:1,a01:0,a02:b,a10:0,a11:1,a12:e,id:1,x:-1,y:-1,scaleX:1,scaleY:1},this._cache.x=this.x,this._cache.y=this.y,this.renderable=!0},d.Text.prototype=Object.create(c.Text.prototype),d.Text.prototype.constructor=d.Text,d.Text.prototype.update=function(){this.exists&&(this._cache.dirty=!1,this._cache.x=this.x,this._cache.y=this.y,(this.position.x!=this._cache.x||this.position.y!=this._cache.y)&&(this.position.x=this._cache.x,this.position.y=this._cache.y,this._cache.dirty=!0))},d.Text.prototype.destroy=function(){this.group&&this.group.remove(this),this.canvas.parentNode?this.canvas.parentNode.removeChild(this.canvas):(this.canvas=null,this.context=null),this.exists=!1,this.group=null},Object.defineProperty(d.Text.prototype,"angle",{get:function(){return d.Math.radToDeg(this.rotation)},set:function(a){this.rotation=d.Math.degToRad(a)}}),Object.defineProperty(d.Text.prototype,"x",{get:function(){return this.position.x},set:function(a){this.position.x=a}}),Object.defineProperty(d.Text.prototype,"y",{get:function(){return this.position.y},set:function(a){this.position.y=a}}),Object.defineProperty(d.Text.prototype,"content",{get:function(){return this._text},set:function(a){a!==this._text&&(this._text=a,this.setText(a))}}),Object.defineProperty(d.Text.prototype,"font",{get:function(){return this._style},set:function(a){a!==this._style&&(this._style=a,this.setStyle(a))}}),d.BitmapText=function(a,b,e,f,g){b=b||0,e=e||0,f=f||"",g=g||"",this.game=a,this.exists=!0,this.alive=!0,this.group=null,this.name="",this.type=d.BITMAPTEXT,c.BitmapText.call(this,f,g),this.position.x=b,this.position.y=e,this.anchor=new d.Point,this.scale=new d.Point(1,1),this._cache={dirty:!1,a00:1,a01:0,a02:b,a10:0,a11:1,a12:e,id:1,x:-1,y:-1,scaleX:1,scaleY:1},this._cache.x=this.x,this._cache.y=this.y,this.renderable=!0},d.BitmapText.prototype=Object.create(c.BitmapText.prototype),d.BitmapText.prototype.constructor=d.BitmapText,d.BitmapText.prototype.update=function(){this.exists&&(this._cache.dirty=!1,this._cache.x=this.x,this._cache.y=this.y,(this.position.x!=this._cache.x||this.position.y!=this._cache.y)&&(this.position.x=this._cache.x,this.position.y=this._cache.y,this._cache.dirty=!0),this.pivot.x=this.anchor.x*this.width,this.pivot.y=this.anchor.y*this.height)},d.BitmapText.prototype.destroy=function(){this.group&&this.group.remove(this),this.canvas&&this.canvas.parentNode?this.canvas.parentNode.removeChild(this.canvas):(this.canvas=null,this.context=null),this.exists=!1,this.group=null},Object.defineProperty(d.BitmapText.prototype,"angle",{get:function(){return d.Math.radToDeg(this.rotation)},set:function(a){this.rotation=d.Math.degToRad(a)}}),Object.defineProperty(d.BitmapText.prototype,"x",{get:function(){return this.position.x},set:function(a){this.position.x=a}}),Object.defineProperty(d.BitmapText.prototype,"y",{get:function(){return this.position.y},set:function(a){this.position.y=a}}),d.Button=function(a,b,c,e,f,g,h,i,j){b=b||0,c=c||0,e=e||null,f=f||null,g=g||this,d.Sprite.call(this,a,b,c,e,i),this.type=d.BUTTON,this._onOverFrameName=null,this._onOutFrameName=null,this._onDownFrameName=null,this._onUpFrameName=null,this._onOverFrameID=null,this._onOutFrameID=null,this._onDownFrameID=null,this._onUpFrameID=null,this.onOverSound=null,this.onOutSound=null,this.onDownSound=null,this.onUpSound=null,this.onOverSoundMarker="",this.onOutSoundMarker="",this.onDownSoundMarker="",this.onUpSoundMarker="",this.onInputOver=new d.Signal,this.onInputOut=new d.Signal,this.onInputDown=new d.Signal,this.onInputUp=new d.Signal,this.freezeFrames=!1,this.forceOut=!0,this.setFrames(h,i,j),null!==f&&this.onInputUp.add(f,g),this.input.start(0,!0),this.events.onInputOver.add(this.onInputOverHandler,this),this.events.onInputOut.add(this.onInputOutHandler,this),this.events.onInputDown.add(this.onInputDownHandler,this),this.events.onInputUp.add(this.onInputUpHandler,this)},d.Button.prototype=Object.create(d.Sprite.prototype),d.Button.prototype=d.Utils.extend(!0,d.Button.prototype,d.Sprite.prototype,c.Sprite.prototype),d.Button.prototype.constructor=d.Button,d.Button.prototype.setFrames=function(a,b,c){null!==a&&("string"==typeof a?(this._onOverFrameName=a,this.input.pointerOver()&&(this.frameName=a)):(this._onOverFrameID=a,this.input.pointerOver()&&(this.frame=a))),null!==b&&("string"==typeof b?(this._onOutFrameName=b,this._onUpFrameName=b,this.input.pointerOver()===!1&&(this.frameName=b)):(this._onOutFrameID=b,this._onUpFrameID=b,this.input.pointerOver()===!1&&(this.frame=b))),null!==c&&("string"==typeof c?(this._onDownFrameName=c,this.input.pointerDown()&&(this.frameName=c)):(this._onDownFrameID=c,this.input.pointerDown()&&(this.frame=c)))},d.Button.prototype.setSounds=function(a,b,c,d,e,f,g,h){this.setOverSound(a,b),this.setOutSound(e,f),this.setUpSound(g,h),this.setDownSound(c,d)},d.Button.prototype.setOverSound=function(a,b){this.onOverSound=null,this.onOverSoundMarker="",a instanceof d.Sound&&(this.onOverSound=a),"string"==typeof b&&(this.onOverSoundMarker=b)},d.Button.prototype.setOutSound=function(a,b){this.onOutSound=null,this.onOutSoundMarker="",a instanceof d.Sound&&(this.onOutSound=a),"string"==typeof b&&(this.onOutSoundMarker=b)},d.Button.prototype.setUpSound=function(a,b){this.onUpSound=null,this.onUpSoundMarker="",a instanceof d.Sound&&(this.onUpSound=a),"string"==typeof b&&(this.onUpSoundMarker=b)},d.Button.prototype.setDownSound=function(a,b){this.onDownSound=null,this.onDownSoundMarker="",a instanceof d.Sound&&(this.onDownSound=a),"string"==typeof b&&(this.onDownSoundMarker=b)},d.Button.prototype.onInputOverHandler=function(a){this.freezeFrames===!1&&(null!=this._onOverFrameName?this.frameName=this._onOverFrameName:null!=this._onOverFrameID&&(this.frame=this._onOverFrameID)),this.onOverSound&&this.onOverSound.play(this.onOverSoundMarker),this.onInputOver&&this.onInputOver.dispatch(this,a)},d.Button.prototype.onInputOutHandler=function(a){this.freezeFrames===!1&&(null!=this._onOutFrameName?this.frameName=this._onOutFrameName:null!=this._onOutFrameID&&(this.frame=this._onOutFrameID)),this.onOutSound&&this.onOutSound.play(this.onOutSoundMarker),this.onInputOut&&this.onInputOut.dispatch(this,a)},d.Button.prototype.onInputDownHandler=function(a){this.freezeFrames===!1&&(null!=this._onDownFrameName?this.frameName=this._onDownFrameName:null!=this._onDownFrameID&&(this.frame=this._onDownFrameID)),this.onDownSound&&this.onDownSound.play(this.onDownSoundMarker),this.onInputDown&&this.onInputDown.dispatch(this,a)},d.Button.prototype.onInputUpHandler=function(a){this.freezeFrames===!1&&(null!=this._onUpFrameName?this.frameName=this._onUpFrameName:null!=this._onUpFrameID&&(this.frame=this._onUpFrameID)),this.onUpSound&&this.onUpSound.play(this.onUpSoundMarker),this.forceOut&&this.freezeFrames===!1&&(null!=this._onOutFrameName?this.frameName=this._onOutFrameName:null!=this._onOutFrameID&&(this.frame=this._onOutFrameID)),this.onInputUp&&this.onInputUp.dispatch(this,a)},d.Graphics=function(a,b,e){this.game=a,c.Graphics.call(this),this.type=d.GRAPHICS,this.position.x=b,this.position.y=e},d.Graphics.prototype=Object.create(c.Graphics.prototype),d.Graphics.prototype.constructor=d.Graphics,d.Graphics.prototype.destroy=function(){this.clear(),this.group&&this.group.remove(this),this.game=null},d.Graphics.prototype.drawPolygon=function(a){this.moveTo(a.points[0].x,a.points[0].y);for(var b=1;bh;h++)f[h].updateTransform();var j=a.__renderGroup;j?a==j.root?j.render(this.projection,this.glFramebuffer):j.renderSpecific(a,this.projection,this.glFramebuffer):(this.renderGroup||(this.renderGroup=new c.WebGLRenderGroup(e)),this.renderGroup.setRenderable(a),this.renderGroup.render(this.projection,this.glFramebuffer)),a.worldTransform=g},d.RenderTexture.prototype.renderCanvas=function(a,b,d){var e=a.children;a.worldTransform=c.mat3.create(),b&&(a.worldTransform[2]=b.x,a.worldTransform[5]=b.y);for(var f=0,g=e.length;g>f;f++)e[f].updateTransform();d&&this.renderer.context.clearRect(0,0,this.width,this.height),this.renderer.renderDisplayObject(a),this.renderer.context.setTransform(1,0,0,1,0,0)},d.Canvas={create:function(a,b){a=a||256,b=b||256;var c=document.createElement("canvas");return c.width=a,c.height=b,c.style.display="block",c},getOffset:function(a,b){b=b||new d.Point;var c=a.getBoundingClientRect(),e=a.clientTop||document.body.clientTop||0,f=a.clientLeft||document.body.clientLeft||0,g=window.pageYOffset||a.scrollTop||document.body.scrollTop,h=window.pageXOffset||a.scrollLeft||document.body.scrollLeft;return b.x=c.left+h-f,b.y=c.top+g-e,b},getAspectRatio:function(a){return a.width/a.height},setBackgroundColor:function(a,b){return b=b||"rgb(0,0,0)",a.style.backgroundColor=b,a},setTouchAction:function(a,b){return b=b||"none",a.style.msTouchAction=b,a.style["ms-touch-action"]=b,a.style["touch-action"]=b,a},setUserSelect:function(a,b){return b=b||"none",a.style["-webkit-touch-callout"]=b,a.style["-webkit-user-select"]=b,a.style["-khtml-user-select"]=b,a.style["-moz-user-select"]=b,a.style["-ms-user-select"]=b,a.style["user-select"]=b,a.style["-webkit-tap-highlight-color"]="rgba(0, 0, 0, 0)",a},addToDOM:function(a,b,c){var d;return"undefined"==typeof c&&(c=!0),b&&("string"==typeof b?d=document.getElementById(b):"object"==typeof b&&1===b.nodeType&&(d=b),c&&(d.style.overflow="hidden")),d||(d=document.body),d.appendChild(a),a},setTransform:function(a,b,c,d,e,f,g){return a.setTransform(d,f,g,e,b,c),a},setSmoothingEnabled:function(a,b){return a.imageSmoothingEnabled=b,a.mozImageSmoothingEnabled=b,a.oImageSmoothingEnabled=b,a.webkitImageSmoothingEnabled=b,a.msImageSmoothingEnabled=b,a},setImageRenderingCrisp:function(a){return a.style["image-rendering"]="crisp-edges",a.style["image-rendering"]="-moz-crisp-edges",a.style["image-rendering"]="-webkit-optimize-contrast",a.style.msInterpolationMode="nearest-neighbor",a},setImageRenderingBicubic:function(a){return a.style["image-rendering"]="auto",a.style.msInterpolationMode="bicubic",a}},d.StageScaleMode=function(a,b,c){this.game=a,this.width=b,this.height=c,this.minWidth=null,this.maxWidth=null,this.minHeight=null,this.maxHeight=null,this._startHeight=0,this.forceLandscape=!1,this.forcePortrait=!1,this.incorrectOrientation=!1,this.pageAlignHorizontally=!1,this.pageAlignVertically=!1,this._width=0,this._height=0,this.maxIterations=5,this.orientationSprite=null,this.enterLandscape=new d.Signal,this.enterPortrait=new d.Signal,this.enterIncorrectOrientation=new d.Signal,this.leaveIncorrectOrientation=new d.Signal,this.hasResized=new d.Signal,this.orientation=window.orientation?window.orientation:window.outerWidth>window.outerHeight?90:0,this.scaleFactor=new d.Point(1,1),this.scaleFactorInversed=new d.Point(1,1),this.margin=new d.Point(0,0),this.aspectRatio=0,this.event=null;var e=this;window.addEventListener("orientationchange",function(a){return e.checkOrientation(a)},!1),window.addEventListener("resize",function(a){return e.checkResize(a)},!1),document.addEventListener("webkitfullscreenchange",function(a){return e.fullScreenChange(a)},!1),document.addEventListener("mozfullscreenchange",function(a){return e.fullScreenChange(a)},!1),document.addEventListener("fullscreenchange",function(a){return e.fullScreenChange(a)},!1)},d.StageScaleMode.EXACT_FIT=0,d.StageScaleMode.NO_SCALE=1,d.StageScaleMode.SHOW_ALL=2,d.StageScaleMode.prototype={startFullScreen:function(a){if(!this.isFullScreen){"undefined"!=typeof a&&d.Canvas.setSmoothingEnabled(this.game.context,a);var b=this.game.canvas;this._width=this.width,this._height=this.height,console.log("startFullScreen",this._width,this._height),b.requestFullScreen?b.requestFullScreen():b.mozRequestFullScreen?b.mozRequestFullScreen():b.webkitRequestFullScreen&&b.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}},stopFullScreen:function(){document.cancelFullScreen?document.cancelFullScreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitCancelFullScreen&&document.webkitCancelFullScreen()},fullScreenChange:function(a){this.event=a,this.isFullScreen?(this.game.stage.canvas.style.width="100%",this.game.stage.canvas.style.height="100%",this.setMaximum(),this.game.input.scale.setTo(this.game.width/this.width,this.game.height/this.height),this.aspectRatio=this.width/this.height,this.scaleFactor.x=this.game.width/this.width,this.scaleFactor.y=this.game.height/this.height):(this.game.stage.canvas.style.width=this.game.width+"px",this.game.stage.canvas.style.height=this.game.height+"px",this.width=this._width,this.height=this._height,this.game.input.scale.setTo(this.game.width/this.width,this.game.height/this.height),this.aspectRatio=this.width/this.height,this.scaleFactor.x=this.game.width/this.width,this.scaleFactor.y=this.game.height/this.height)},forceOrientation:function(a,b,d){"undefined"==typeof b&&(b=!1),this.forceLandscape=a,this.forcePortrait=b,"undefined"!=typeof d&&((null==d||this.game.cache.checkImageKey(d)===!1)&&(d="__default"),this.orientationSprite=new c.Sprite(c.TextureCache[d]),this.orientationSprite.anchor.x=.5,this.orientationSprite.anchor.y=.5,this.orientationSprite.position.x=this.game.width/2,this.orientationSprite.position.y=this.game.height/2,this.checkOrientationState(),this.incorrectOrientation?(this.orientationSprite.visible=!0,this.game.world.visible=!1):(this.orientationSprite.visible=!1,this.game.world.visible=!0),this.game.stage._stage.addChild(this.orientationSprite))},checkOrientationState:function(){this.incorrectOrientation?(this.forceLandscape&&window.innerWidth>window.innerHeight||this.forcePortrait&&window.innerHeight>window.innerWidth)&&(this.game.paused=!1,this.incorrectOrientation=!1,this.leaveIncorrectOrientation.dispatch(),this.orientationSprite&&(this.orientationSprite.visible=!1,this.game.world.visible=!0),this.refresh()):(this.forceLandscape&&window.innerWidthwindow.outerHeight?90:0,this.isLandscape?this.enterLandscape.dispatch(this.orientation,!0,!1):this.enterPortrait.dispatch(this.orientation,!1,!0),this.game.stage.scaleMode!==d.StageScaleMode.NO_SCALE&&this.refresh(),this.checkOrientationState()},refresh:function(){if(this.game.device.iPad===!1&&this.game.device.webApp===!1&&this.game.device.desktop===!1&&(this.game.device.android&&this.game.device.chrome===!1?window.scrollTo(0,1):window.scrollTo(0,0)),null==this._check&&this.maxIterations>0){this._iterations=this.maxIterations;var a=this;this._check=window.setInterval(function(){return a.setScreenSize()},10),this.setScreenSize()}},setScreenSize:function(a){"undefined"==typeof a&&(a=!1),this.game.device.iPad===!1&&this.game.device.webApp===!1&&this.game.device.desktop===!1&&(this.game.device.android&&this.game.device.chrome===!1?window.scrollTo(0,1):window.scrollTo(0,0)),this._iterations--,(a||window.innerHeight>this._startHeight||this._iterations<0)&&(document.documentElement.style.minHeight=window.innerHeight+"px",this.incorrectOrientation===!0?this.setMaximum():this.game.stage.scaleMode==d.StageScaleMode.EXACT_FIT?this.setExactFit():this.game.stage.scaleMode==d.StageScaleMode.SHOW_ALL&&this.setShowAll(),this.setSize(),clearInterval(this._check),this._check=null)},setSize:function(){this.incorrectOrientation===!1&&(this.maxWidth&&this.width>this.maxWidth&&(this.width=this.maxWidth),this.maxHeight&&this.height>this.maxHeight&&(this.height=this.maxHeight),this.minWidth&&this.widththis.maxWidth?this.maxWidth:a,this.height=this.maxHeight&&b>this.maxHeight?this.maxHeight:b}},Object.defineProperty(d.StageScaleMode.prototype,"isFullScreen",{get:function(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement}}),Object.defineProperty(d.StageScaleMode.prototype,"isPortrait",{get:function(){return 0===this.orientation||180==this.orientation}}),Object.defineProperty(d.StageScaleMode.prototype,"isLandscape",{get:function(){return 90===this.orientation||-90===this.orientation}}),d.Device=function(){this.patchAndroidClearRectBug=!1,this.desktop=!1,this.iOS=!1,this.cocoonJS=!1,this.android=!1,this.chromeOS=!1,this.linux=!1,this.macOS=!1,this.windows=!1,this.canvas=!1,this.file=!1,this.fileSystem=!1,this.localStorage=!1,this.webGL=!1,this.worker=!1,this.touch=!1,this.mspointer=!1,this.css3D=!1,this.pointerLock=!1,this.typedArray=!1,this.arora=!1,this.chrome=!1,this.epiphany=!1,this.firefox=!1,this.ie=!1,this.ieVersion=0,this.mobileSafari=!1,this.midori=!1,this.opera=!1,this.safari=!1,this.webApp=!1,this.audioData=!1,this.webAudio=!1,this.ogg=!1,this.opus=!1,this.mp3=!1,this.wav=!1,this.m4a=!1,this.webm=!1,this.iPhone=!1,this.iPhone4=!1,this.iPad=!1,this.pixelRatio=0,this.littleEndian=!1,this._checkAudio(),this._checkBrowser(),this._checkCSS3D(),this._checkDevice(),this._checkFeatures(),this._checkOS() -},d.Device.prototype={_checkOS:function(){var a=navigator.userAgent;/Android/.test(a)?this.android=!0:/CrOS/.test(a)?this.chromeOS=!0:/iP[ao]d|iPhone/i.test(a)?this.iOS=!0:/Linux/.test(a)?this.linux=!0:/Mac OS/.test(a)?this.macOS=!0:/Windows/.test(a)&&(this.windows=!0),(this.windows||this.macOS||this.linux)&&(this.desktop=!0)},_checkFeatures:function(){this.canvas=!!window.CanvasRenderingContext2D;try{this.localStorage=!!localStorage.getItem}catch(a){this.localStorage=!1}this.file=!!(window.File&&window.FileReader&&window.FileList&&window.Blob),this.fileSystem=!!window.requestFileSystem,this.webGL=function(){try{var a=document.createElement("canvas");return!!window.WebGLRenderingContext&&(a.getContext("webgl")||a.getContext("experimental-webgl"))}catch(b){return!1}}(),this.webGL=null===this.webGL||this.webGL===!1?!1:!0,this.worker=!!window.Worker,("ontouchstart"in document.documentElement||window.navigator.maxTouchPoints&&window.navigator.maxTouchPoints>1)&&(this.touch=!0),(window.navigator.msPointerEnabled||window.navigator.pointerEnabled)&&(this.mspointer=!0),this.pointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document},_checkBrowser:function(){var a=navigator.userAgent;/Arora/.test(a)?this.arora=!0:/Chrome/.test(a)?this.chrome=!0:/Epiphany/.test(a)?this.epiphany=!0:/Firefox/.test(a)?this.firefox=!0:/Mobile Safari/.test(a)?this.mobileSafari=!0:/MSIE (\d+\.\d+);/.test(a)?(this.ie=!0,this.ieVersion=parseInt(RegExp.$1,10)):/Midori/.test(a)?this.midori=!0:/Opera/.test(a)?this.opera=!0:/Safari/.test(a)&&(this.safari=!0),navigator.standalone&&(this.webApp=!0),navigator.isCocoonJS&&(this.cocoonJS=!0)},_checkAudio:function(){this.audioData=!!window.Audio,this.webAudio=!(!window.webkitAudioContext&&!window.AudioContext);var a=document.createElement("audio"),b=!1;try{(b=!!a.canPlayType)&&(a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,"")&&(this.ogg=!0),a.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/,"")&&(this.opus=!0),a.canPlayType("audio/mpeg;").replace(/^no$/,"")&&(this.mp3=!0),a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,"")&&(this.wav=!0),(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;").replace(/^no$/,""))&&(this.m4a=!0),a.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,"")&&(this.webm=!0))}catch(c){}},_checkDevice:function(){this.pixelRatio=window.devicePixelRatio||1,this.iPhone=-1!=navigator.userAgent.toLowerCase().indexOf("iphone"),this.iPhone4=2==this.pixelRatio&&this.iPhone,this.iPad=-1!=navigator.userAgent.toLowerCase().indexOf("ipad"),"undefined"!=typeof Int8Array?(this.littleEndian=new Int8Array(new Int16Array([1]).buffer)[0]>0,this.typedArray=!0):(this.littleEndian=!1,this.typedArray=!1)},_checkCSS3D:function(){var a,b=document.createElement("p"),c={webkitTransform:"-webkit-transform",OTransform:"-o-transform",msTransform:"-ms-transform",MozTransform:"-moz-transform",transform:"transform"};document.body.insertBefore(b,null);for(var d in c)void 0!==b.style[d]&&(b.style[d]="translate3d(1px,1px,1px)",a=window.getComputedStyle(b).getPropertyValue(c[d]));document.body.removeChild(b),this.css3D=void 0!==a&&a.length>0&&"none"!==a},canPlayAudio:function(a){return"mp3"==a&&this.mp3?!0:"ogg"==a&&(this.ogg||this.opus)?!0:"m4a"==a&&this.m4a?!0:"wav"==a&&this.wav?!0:"webm"==a&&this.webm?!0:!1},isConsoleOpen:function(){return window.console&&window.console.firebug?!0:window.console?(console.profile(),console.profileEnd(),console.clear&&console.clear(),console.profiles.length>0):!1}},d.RequestAnimationFrame=function(a){this.game=a,this.isRunning=!1;for(var b=["ms","moz","webkit","o"],c=0;c>>0,b-=d,b*=d,d=b>>>0,b-=d,d+=4294967296*b;return 2.3283064365386963e-10*(d>>>0)},integer:function(){return 4294967296*this.rnd.apply(this)},frac:function(){return this.rnd.apply(this)+1.1102230246251565e-16*(0|2097152*this.rnd.apply(this))},real:function(){return this.integer()+this.frac()},integerInRange:function(a,b){return Math.floor(this.realInRange(a,b))},realInRange:function(a,b){return this.frac()*(b-a)+a},normal:function(){return 1-2*this.frac()},uuid:function(){var a="",b="";for(b=a="";a++<36;b+=~a%5|4&3*a?(15^a?8^this.frac()*(20^a?16:4):4).toString(16):"-");return b},pick:function(a){return a[this.integerInRange(0,a.length)]},weightedPick:function(a){return a[~~(Math.pow(this.frac(),2)*a.length)]},timestamp:function(a,b){return this.realInRange(a||9466848e5,b||1577862e6)},angle:function(){return this.integerInRange(-180,180)}},d.Math={PI2:2*Math.PI,fuzzyEqual:function(a,b,c){return"undefined"==typeof c&&(c=1e-4),Math.abs(a-b)a},fuzzyGreaterThan:function(a,b,c){return"undefined"==typeof c&&(c=1e-4),a>b-c},fuzzyCeil:function(a,b){return"undefined"==typeof b&&(b=1e-4),Math.ceil(a-b)},fuzzyFloor:function(a,b){return"undefined"==typeof b&&(b=1e-4),Math.floor(a+b)},average:function(){for(var a=[],b=0;b0?Math.floor(a):Math.ceil(a)},shear:function(a){return a%1},snapTo:function(a,b,c){return"undefined"==typeof c&&(c=0),0===b?a:(a-=c,a=b*Math.round(a/b),c+a)},snapToFloor:function(a,b,c){return"undefined"==typeof c&&(c=0),0===b?a:(a-=c,a=b*Math.floor(a/b),c+a)},snapToCeil:function(a,b,c){return"undefined"==typeof c&&(c=0),0===b?a:(a-=c,a=b*Math.ceil(a/b),c+a)},snapToInArray:function(a,b,c){if("undefined"==typeof c&&(c=!0),c&&b.sort(),a=f-a?f:e},roundTo:function(a,b,c){"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=10);var d=Math.pow(c,-b);return Math.round(a*d)/d},floorTo:function(a,b,c){"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=10);var d=Math.pow(c,-b);return Math.floor(a*d)/d},ceilTo:function(a,b,c){"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=10);var d=Math.pow(c,-b);return Math.ceil(a*d)/d},interpolateFloat:function(a,b,c){return(b-a)*c+a},angleBetween:function(a,b,c,d){return Math.atan2(d-b,c-a)},normalizeAngle:function(a,b){"undefined"==typeof b&&(b=!0);var c=b?Math.PI:180;return this.wrap(a,-c,c)},nearestAngleBetween:function(a,b,c){"undefined"==typeof c&&(c=!0);var d=c?Math.PI:180;return a=this.normalizeAngle(a,c),b=this.normalizeAngle(b,c),-d/2>a&&b>d/2&&(a+=2*d),-d/2>b&&a>d/2&&(b+=2*d),b-a},interpolateAngles:function(a,b,c,d,e){return"undefined"==typeof d&&(d=!0),"undefined"==typeof e&&(e=null),a=this.normalizeAngle(a,d),b=this.normalizeAngleToAnother(b,a,d),"function"==typeof e?e(c,a,b-a,1):this.interpolateFloat(a,b,c)},chanceRoll:function(a){return"undefined"==typeof a&&(a=50),0>=a?!1:a>=100?!0:100*Math.random()>=a?!1:!0},numberArray:function(a,b){for(var c=[],d=a;b>=d;d++)c.push(d);return c},maxAdd:function(a,b,c){return a+=b,a>c&&(a=c),a},minSub:function(a,b,c){return a-=b,c>a&&(a=c),a},wrap:function(a,b,c){var d=c-b;if(0>=d)return 0;var e=(a-b)%d;return 0>e&&(e+=d),e+b},wrapValue:function(a,b,c){var d;return a=Math.abs(a),b=Math.abs(b),c=Math.abs(c),d=(a+b)%c},randomSign:function(){return Math.random()>.5?1:-1},isOdd:function(a){return 1&a},isEven:function(a){return 1&a?!1:!0},max:function(){for(var a=1,b=0,c=arguments.length;c>a;a++)arguments[b]a;a++)arguments[a]c?d=c:b>a&&(d=b),d},linearInterpolation:function(a,b){var c=a.length-1,d=c*b,e=Math.floor(d);return 0>b?this.linear(a[0],a[1],d):b>1?this.linear(a[c],a[c-1],c-d):this.linear(a[e],a[e+1>c?c:e+1],d-e)},bezierInterpolation:function(a,b){for(var c=0,d=a.length-1,e=0;d>=e;e++)c+=Math.pow(1-b,d-e)*Math.pow(b,e)*a[e]*this.bernstein(d,e);return c},catmullRomInterpolation:function(a,b){var c=a.length-1,d=c*b,e=Math.floor(d);return a[0]===a[c]?(0>b&&(e=Math.floor(d=c*(1+b))),this.catmullRom(a[(e-1+c)%c],a[e],a[(e+1)%c],a[(e+2)%c],d-e)):0>b?a[0]-(this.catmullRom(a[0],a[0],a[1],a[1],-d)-a[0]):b>1?a[c]-(this.catmullRom(a[c],a[c],a[c-1],a[c-1],d-c)-a[c]):this.catmullRom(a[e?e-1:0],a[e],a[e+1>c?c:e+1],a[e+2>c?c:e+2],d-e)},linear:function(a,b,c){return(b-a)*c+a},bernstein:function(a,b){return this.factorial(a)/this.factorial(b)/this.factorial(a-b)},catmullRom:function(a,b,c,d,e){var f=.5*(c-a),g=.5*(d-b),h=e*e,i=e*h;return(2*b-2*c+f+g)*i+(-3*b+3*c-2*f-g)*h+f*e+b},difference:function(a,b){return Math.abs(a-b)},getRandom:function(a,b,c){if("undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=0),null!=a){var d=c;if((0===d||d>a.length-b)&&(d=a.length-b),d>0)return a[b+Math.floor(Math.random()*d)]}return null},floor:function(a){var b=0|a;return a>0?b:b!=a?b-1:b},ceil:function(a){var b=0|a;return a>0?b!=a?b+1:b:b},sinCosGenerator:function(a,b,c,d){"undefined"==typeof b&&(b=1),"undefined"==typeof c&&(c=1),"undefined"==typeof d&&(d=1);for(var e=b,f=c,g=d*Math.PI/a,h=[],i=[],j=0;a>j;j++)f-=e*g,e+=f*g,h[j]=f,i[j]=e;return{sin:i,cos:h,length:a}},shift:function(a){var b=a.shift();return a.push(b),b},shuffleArray:function(a){for(var b=a.length-1;b>0;b--){var c=Math.floor(Math.random()*(b+1)),d=a[b];a[b]=a[c],a[c]=d}return a},distance:function(a,b,c,d){var e=a-c,f=b-d;return Math.sqrt(e*e+f*f)},distanceRounded:function(a,b,c,e){return Math.round(d.Math.distance(a,b,c,e))},clamp:function(a,b,c){return b>a?b:a>c?c:a},clampBottom:function(a,b){return b>a?b:a},within:function(a,b,c){return Math.abs(a-b)<=c},mapLinear:function(a,b,c,d,e){return d+(a-b)*(e-d)/(c-b)},smoothstep:function(a,b,c){return b>=a?0:a>=c?1:(a=(a-b)/(c-b),a*a*(3-2*a))},smootherstep:function(a,b,c){return b>=a?0:a>=c?1:(a=(a-b)/(c-b),a*a*a*(a*(6*a-15)+10))},sign:function(a){return 0>a?-1:a>0?1:0},degToRad:function(){var a=Math.PI/180;return function(b){return b*a}}(),radToDeg:function(){var a=180/Math.PI;return function(b){return b*a}}()},d.QuadTree=function(a,b,c,d,e,f,g,h){this.physicsManager=a,this.ID=a.quadTreeID,a.quadTreeID++,this.maxObjects=f||10,this.maxLevels=g||4,this.level=h||0,this.bounds={x:Math.round(b),y:Math.round(c),width:d,height:e,subWidth:Math.floor(d/2),subHeight:Math.floor(e/2),right:Math.round(b)+Math.floor(d/2),bottom:Math.round(c)+Math.floor(e/2)},this.objects=[],this.nodes=[]},d.QuadTree.prototype={split:function(){this.level++,this.nodes[0]=new d.QuadTree(this.physicsManager,this.bounds.right,this.bounds.y,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level),this.nodes[1]=new d.QuadTree(this.physicsManager,this.bounds.x,this.bounds.y,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level),this.nodes[2]=new d.QuadTree(this.physicsManager,this.bounds.x,this.bounds.bottom,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level),this.nodes[3]=new d.QuadTree(this.physicsManager,this.bounds.right,this.bounds.bottom,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level)},insert:function(a){var b,c=0;if(null!=this.nodes[0]&&(b=this.getIndex(a),-1!==b))return this.nodes[b].insert(a),void 0;if(this.objects.push(a),this.objects.length>this.maxObjects&&this.levelthis.bounds.bottom&&(b=2):a.x>this.bounds.right&&(a.ythis.bounds.bottom&&(b=3)),b},retrieve:function(a){var b=this.objects;return a.body.quadTreeIndex=this.getIndex(a.body),a.body.quadTreeIDs.push(this.ID),this.nodes[0]&&(-1!==a.body.quadTreeIndex?b=b.concat(this.nodes[a.body.quadTreeIndex].retrieve(a)):(b=b.concat(this.nodes[0].retrieve(a)),b=b.concat(this.nodes[1].retrieve(a)),b=b.concat(this.nodes[2].retrieve(a)),b=b.concat(this.nodes[3].retrieve(a)))),b},clear:function(){this.objects=[];for(var a=0,b=this.nodes.length;b>a;a++)this.nodes[a]&&(this.nodes[a].clear(),delete this.nodes[a])}},d.Circle=function(a,b,c){a=a||0,b=b||0,c=c||0,this.x=a,this.y=b,this._diameter=c,this._radius=c>0?.5*c:0},d.Circle.prototype={circumference:function(){return 2*Math.PI*this._radius},setTo:function(a,b,c){return this.x=a,this.y=b,this._diameter=c,this._radius=.5*c,this},copyFrom:function(a){return this.setTo(a.x,a.y,a.diameter)},copyTo:function(a){return a.x=this.x,a.y=this.y,a.diameter=this._diameter,a},distance:function(a,b){return"undefined"==typeof b&&(b=!1),b?d.Math.distanceRound(this.x,this.y,a.x,a.y):d.Math.distance(this.x,this.y,a.x,a.y)},clone:function(a){return"undefined"==typeof a&&(a=new d.Circle),a.setTo(this.x,this.y,this.diameter)},contains:function(a,b){return d.Circle.contains(this,a,b)},circumferencePoint:function(a,b,c){return d.Circle.circumferencePoint(this,a,b,c)},offset:function(a,b){return this.x+=a,this.y+=b,this},offsetPoint:function(a){return this.offset(a.x,a.y)},toString:function(){return"[{Phaser.Circle (x="+this.x+" y="+this.y+" diameter="+this.diameter+" radius="+this.radius+")}]"}},Object.defineProperty(d.Circle.prototype,"diameter",{get:function(){return this._diameter},set:function(a){a>0&&(this._diameter=a,this._radius=.5*a)}}),Object.defineProperty(d.Circle.prototype,"radius",{get:function(){return this._radius},set:function(a){a>0&&(this._radius=a,this._diameter=2*a)}}),Object.defineProperty(d.Circle.prototype,"left",{get:function(){return this.x-this._radius},set:function(a){a>this.x?(this._radius=0,this._diameter=0):this.radius=this.x-a}}),Object.defineProperty(d.Circle.prototype,"right",{get:function(){return this.x+this._radius},set:function(a){athis.y?(this._radius=0,this._diameter=0):this.radius=this.y-a}}),Object.defineProperty(d.Circle.prototype,"bottom",{get:function(){return this.y+this._radius},set:function(a){a0?Math.PI*this._radius*this._radius:0}}),Object.defineProperty(d.Circle.prototype,"empty",{get:function(){return 0===this._diameter},set:function(a){a===!0&&this.setTo(0,0,0)}}),d.Circle.contains=function(a,b,c){if(b>=a.left&&b<=a.right&&c>=a.top&&c<=a.bottom){var d=(a.x-b)*(a.x-b),e=(a.y-c)*(a.y-c);return d+e<=a.radius*a.radius}return!1},d.Circle.equals=function(a,b){return a.x==b.x&&a.y==b.y&&a.diameter==b.diameter},d.Circle.intersects=function(a,b){return d.Math.distance(a.x,a.y,b.x,b.y)<=a.radius+b.radius},d.Circle.circumferencePoint=function(a,b,c,e){return"undefined"==typeof c&&(c=!1),"undefined"==typeof e&&(e=new d.Point),c===!0&&(b=d.Math.radToDeg(b)),e.x=a.x+a.radius*Math.cos(b),e.y=a.y+a.radius*Math.sin(b),e},d.Circle.intersectsRectangle=function(a,b){var c=Math.abs(a.x-b.x-b.halfWidth),d=b.halfWidth+a.radius;if(c>d)return!1;var e=Math.abs(a.y-b.y-b.halfHeight),f=b.halfHeight+a.radius;if(e>f)return!1;if(c<=b.halfWidth||e<=b.halfHeight)return!0;var g=c-b.halfWidth,h=e-b.halfHeight,i=g*g,j=h*h,k=a.radius*a.radius;return k>=i+j},d.Point=function(a,b){a=a||0,b=b||0,this.x=a,this.y=b},d.Point.prototype={copyFrom:function(a){return this.setTo(a.x,a.y)},invert:function(){return this.setTo(this.y,this.x)},setTo:function(a,b){return this.x=a,this.y=b,this},add:function(a,b){return this.x+=a,this.y+=b,this},subtract:function(a,b){return this.x-=a,this.y-=b,this},multiply:function(a,b){return this.x*=a,this.y*=b,this},divide:function(a,b){return this.x/=a,this.y/=b,this},clampX:function(a,b){return this.x=d.Math.clamp(this.x,a,b),this},clampY:function(a,b){return this.y=d.Math.clamp(this.y,a,b),this},clamp:function(a,b){return this.x=d.Math.clamp(this.x,a,b),this.y=d.Math.clamp(this.y,a,b),this},clone:function(a){return"undefined"==typeof a&&(a=new d.Point),a.setTo(this.x,this.y)},copyTo:function(a){return a.x=this.x,a.y=this.y,a},distance:function(a,b){return d.Point.distance(this,a,b)},equals:function(a){return a.x==this.x&&a.y==this.y},rotate:function(a,b,c,e,f){return d.Point.rotate(this,a,b,c,e,f)},getMagnitude:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},setMagnitude:function(a){return this.normalize().multiply(a,a)},normalize:function(){if(!this.isZero()){var a=this.getMagnitude();this.x/=a,this.y/=a}return this},isZero:function(){return 0===this.x&&0===this.y},toString:function(){return"[{Point (x="+this.x+" y="+this.y+")}]"}},d.Point.add=function(a,b,c){return"undefined"==typeof c&&(c=new d.Point),c.x=a.x+b.x,c.y=a.y+b.y,c},d.Point.subtract=function(a,b,c){return"undefined"==typeof c&&(c=new d.Point),c.x=a.x-b.x,c.y=a.y-b.y,c},d.Point.multiply=function(a,b,c){return"undefined"==typeof c&&(c=new d.Point),c.x=a.x*b.x,c.y=a.y*b.y,c},d.Point.divide=function(a,b,c){return"undefined"==typeof c&&(c=new d.Point),c.x=a.x/b.x,c.y=a.y/b.y,c},d.Point.equals=function(a,b){return a.x==b.x&&a.y==b.y},d.Point.distance=function(a,b,c){return"undefined"==typeof c&&(c=!1),c?d.Math.distanceRound(a.x,a.y,b.x,b.y):d.Math.distance(a.x,a.y,b.x,b.y)},d.Point.rotate=function(a,b,c,e,f,g){return f=f||!1,g=g||null,f&&(e=d.Math.degToRad(e)),null===g&&(g=Math.sqrt((b-a.x)*(b-a.x)+(c-a.y)*(c-a.y))),a.setTo(b+g*Math.cos(e),c+g*Math.sin(e))},d.Rectangle=function(a,b,c,d){a=a||0,b=b||0,c=c||0,d=d||0,this.x=a,this.y=b,this.width=c,this.height=d},d.Rectangle.prototype={offset:function(a,b){return this.x+=a,this.y+=b,this},offsetPoint:function(a){return this.offset(a.x,a.y)},setTo:function(a,b,c,d){return this.x=a,this.y=b,this.width=c,this.height=d,this},floor:function(){this.x=Math.floor(this.x),this.y=Math.floor(this.y)},floorAll:function(){this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.width=Math.floor(this.width),this.height=Math.floor(this.height)},copyFrom:function(a){return this.setTo(a.x,a.y,a.width,a.height)},copyTo:function(a){return a.x=this.x,a.y=this.y,a.width=this.width,a.height=this.height,a},inflate:function(a,b){return d.Rectangle.inflate(this,a,b)},size:function(a){return d.Rectangle.size(this,a)},clone:function(a){return d.Rectangle.clone(this,a)},contains:function(a,b){return d.Rectangle.contains(this,a,b)},containsRect:function(a){return d.Rectangle.containsRect(this,a)},equals:function(a){return d.Rectangle.equals(this,a)},intersection:function(a,b){return d.Rectangle.intersection(this,a,b)},intersects:function(a,b){return d.Rectangle.intersects(this,a,b)},intersectsRaw:function(a,b,c,e,f){return d.Rectangle.intersectsRaw(this,a,b,c,e,f)},union:function(a,b){return d.Rectangle.union(this,a,b)},toString:function(){return"[{Rectangle (x="+this.x+" y="+this.y+" width="+this.width+" height="+this.height+" empty="+this.empty+")}]"}},Object.defineProperty(d.Rectangle.prototype,"halfWidth",{get:function(){return Math.round(this.width/2)}}),Object.defineProperty(d.Rectangle.prototype,"halfHeight",{get:function(){return Math.round(this.height/2)}}),Object.defineProperty(d.Rectangle.prototype,"bottom",{get:function(){return this.y+this.height},set:function(a){this.height=a<=this.y?0:this.y-a}}),Object.defineProperty(d.Rectangle.prototype,"bottomRight",{get:function(){return new d.Point(this.right,this.bottom)},set:function(a){this.right=a.x,this.bottom=a.y}}),Object.defineProperty(d.Rectangle.prototype,"left",{get:function(){return this.x},set:function(a){this.width=a>=this.right?0:this.right-a,this.x=a}}),Object.defineProperty(d.Rectangle.prototype,"right",{get:function(){return this.x+this.width},set:function(a){this.width=a<=this.x?0:this.x+a}}),Object.defineProperty(d.Rectangle.prototype,"volume",{get:function(){return this.width*this.height}}),Object.defineProperty(d.Rectangle.prototype,"perimeter",{get:function(){return 2*this.width+2*this.height}}),Object.defineProperty(d.Rectangle.prototype,"centerX",{get:function(){return this.x+this.halfWidth},set:function(a){this.x=a-this.halfWidth}}),Object.defineProperty(d.Rectangle.prototype,"centerY",{get:function(){return this.y+this.halfHeight},set:function(a){this.y=a-this.halfHeight}}),Object.defineProperty(d.Rectangle.prototype,"top",{get:function(){return this.y},set:function(a){a>=this.bottom?(this.height=0,this.y=a):this.height=this.bottom-a}}),Object.defineProperty(d.Rectangle.prototype,"topLeft",{get:function(){return new d.Point(this.x,this.y)},set:function(a){this.x=a.x,this.y=a.y}}),Object.defineProperty(d.Rectangle.prototype,"empty",{get:function(){return!this.width||!this.height},set:function(a){a===!0&&this.setTo(0,0,0,0)}}),d.Rectangle.inflate=function(a,b,c){return a.x-=b,a.width+=2*b,a.y-=c,a.height+=2*c,a},d.Rectangle.inflatePoint=function(a,b){return d.Rectangle.inflate(a,b.x,b.y)},d.Rectangle.size=function(a,b){return"undefined"==typeof b&&(b=new d.Point),b.setTo(a.width,a.height)},d.Rectangle.clone=function(a,b){return"undefined"==typeof b&&(b=new d.Rectangle),b.setTo(a.x,a.y,a.width,a.height)},d.Rectangle.contains=function(a,b,c){return b>=a.x&&b<=a.right&&c>=a.y&&c<=a.bottom},d.Rectangle.containsRaw=function(a,b,c,d,e,f){return e>=a&&a+c>=e&&f>=b&&b+d>=f},d.Rectangle.containsPoint=function(a,b){return d.Rectangle.contains(a,b.x,b.y)},d.Rectangle.containsRect=function(a,b){return a.volume>b.volume?!1:a.x>=b.x&&a.y>=b.y&&a.right<=b.right&&a.bottom<=b.bottom},d.Rectangle.equals=function(a,b){return a.x==b.x&&a.y==b.y&&a.width==b.width&&a.height==b.height},d.Rectangle.intersection=function(a,b,c){return c=c||new d.Rectangle,d.Rectangle.intersects(a,b)&&(c.x=Math.max(a.x,b.x),c.y=Math.max(a.y,b.y),c.width=Math.min(a.right,b.right)-c.x,c.height=Math.min(a.bottom,b.bottom)-c.y),c},d.Rectangle.intersects=function(a,b){return a.xa.right+f||ca.bottom+f||e1){if(a&&a==this.decodeURI(e[0]))return this.decodeURI(e[1]);b[this.decodeURI(e[0])]=this.decodeURI(e[1])}}return b},decodeURI:function(a){return decodeURIComponent(a.replace(/\+/g," "))}},d.TweenManager=function(a){this.game=a,this._tweens=[],this._add=[],this.game.onPause.add(this.pauseAll,this),this.game.onResume.add(this.resumeAll,this)},d.TweenManager.prototype={REVISION:"11dev",getAll:function(){return this._tweens},removeAll:function(){this._tweens=[]},add:function(a){this._add.push(a)},create:function(a){return new d.Tween(a,this.game)},remove:function(a){var b=this._tweens.indexOf(a);-1!==b&&(this._tweens[b].pendingDelete=!0)},update:function(){if(0===this._tweens.length&&0===this._add.length)return!1;for(var a=0,b=this._tweens.length;b>a;)this._tweens[a].update(this.game.time.now)?a++:(this._tweens.splice(a,1),b--);return this._add.length>0&&(this._tweens=this._tweens.concat(this._add),this._add.length=0),!0},isTweening:function(a){return this._tweens.some(function(b){return b._object===a})},pauseAll:function(){for(var a=this._tweens.length-1;a>=0;a--)this._tweens[a].pause()},resumeAll:function(){for(var a=this._tweens.length-1;a>=0;a--)this._tweens[a].resume()}},d.Tween=function(a,b){this._object=a,this.game=b,this._manager=this.game.tweens,this._valuesStart={},this._valuesEnd={},this._valuesStartRepeat={},this._duration=1e3,this._repeat=0,this._yoyo=!1,this._reversed=!1,this._delayTime=0,this._startTime=null,this._easingFunction=d.Easing.Linear.None,this._interpolationFunction=d.Math.linearInterpolation,this._chainedTweens=[],this._onStartCallback=null,this._onStartCallbackFired=!1,this._onUpdateCallback=null,this._onCompleteCallback=null,this._pausedTime=0,this.pendingDelete=!1;for(var c in a)this._valuesStart[c]=parseFloat(a[c],10);this.onStart=new d.Signal,this.onComplete=new d.Signal,this.isRunning=!1},d.Tween.prototype={to:function(a,b,c,d,e,f,g){b=b||1e3,c=c||null,d=d||!1,e=e||0,f=f||0,g=g||!1;var h;return this._parent?(h=this._manager.create(this._object),this._lastChild.chain(h),this._lastChild=h):(h=this,this._parent=this,this._lastChild=this),h._repeat=f,h._duration=b,h._valuesEnd=a,null!==c&&(h._easingFunction=c),e>0&&(h._delayTime=e),h._yoyo=g,d?this.start():this},start:function(){if(null!==this.game&&null!==this._object){this._manager.add(this),this.onStart.dispatch(this._object),this.isRunning=!0,this._onStartCallbackFired=!1,this._startTime=this.game.time.now+this._delayTime;for(var a in this._valuesEnd){if(this._valuesEnd[a]instanceof Array){if(0===this._valuesEnd[a].length)continue;this._valuesEnd[a]=[this._object[a]].concat(this._valuesEnd[a])}this._valuesStart[a]=this._object[a],this._valuesStart[a]instanceof Array==!1&&(this._valuesStart[a]*=1),this._valuesStartRepeat[a]=this._valuesStart[a]||0}return this}},stop:function(){return this.isRunning=!1,this._manager.remove(this),this},delay:function(a){return this._delayTime=a,this},repeat:function(a){return this._repeat=a,this},yoyo:function(a){return this._yoyo=a,this},easing:function(a){return this._easingFunction=a,this},interpolation:function(a){return this._interpolationFunction=a,this},chain:function(){return this._chainedTweens=arguments,this},loop:function(){return this._lastChild.chain(this),this},onStartCallback:function(a){return this._onStartCallback=a,this},onUpdateCallback:function(a){return this._onUpdateCallback=a,this},onCompleteCallback:function(a){return this._onCompleteCallback=a,this},pause:function(){this._paused=!0,this._pausedTime=this.game.time.now},resume:function(){this._paused=!1,this._startTime+=this.game.time.now-this._pausedTime},update:function(a){if(this.pendingDelete)return!1;if(this._paused||a1?1:c;var d=this._easingFunction(c);for(b in this._valuesEnd){var e=this._valuesStart[b]||0,f=this._valuesEnd[b];f instanceof Array?this._object[b]=this._interpolationFunction(f,d):("string"==typeof f&&(f=e+parseFloat(f,10)),"number"==typeof f&&(this._object[b]=e+(f-e)*d))}if(null!==this._onUpdateCallback&&this._onUpdateCallback.call(this._object,d),1==c){if(this._repeat>0){isFinite(this._repeat)&&this._repeat--;for(b in this._valuesStartRepeat){if("string"==typeof this._valuesEnd[b]&&(this._valuesStartRepeat[b]=this._valuesStartRepeat[b]+parseFloat(this._valuesEnd[b],10)),this._yoyo){var g=this._valuesStartRepeat[b];this._valuesStartRepeat[b]=this._valuesEnd[b],this._valuesEnd[b]=g,this._reversed=!this._reversed}this._valuesStart[b]=this._valuesStartRepeat[b]}return this._startTime=a+this._delayTime,this.onComplete.dispatch(this._object),null!==this._onCompleteCallback&&this._onCompleteCallback.call(this._object),!0}this.isRunning=!1,this.onComplete.dispatch(this._object),null!==this._onCompleteCallback&&this._onCompleteCallback.call(this._object);for(var h=0,i=this._chainedTweens.length;i>h;h++)this._chainedTweens[h].start(a);return!1}return!0}},d.Easing={Linear:{None:function(a){return a}},Quadratic:{In:function(a){return a*a},Out:function(a){return a*(2-a)},InOut:function(a){return(a*=2)<1?.5*a*a:-.5*(--a*(a-2)-1)}},Cubic:{In:function(a){return a*a*a},Out:function(a){return--a*a*a+1},InOut:function(a){return(a*=2)<1?.5*a*a*a:.5*((a-=2)*a*a+2)}},Quartic:{In:function(a){return a*a*a*a},Out:function(a){return 1- --a*a*a*a},InOut:function(a){return(a*=2)<1?.5*a*a*a*a:-.5*((a-=2)*a*a*a-2)}},Quintic:{In:function(a){return a*a*a*a*a},Out:function(a){return--a*a*a*a*a+1},InOut:function(a){return(a*=2)<1?.5*a*a*a*a*a:.5*((a-=2)*a*a*a*a+2)}},Sinusoidal:{In:function(a){return 1-Math.cos(a*Math.PI/2)},Out:function(a){return Math.sin(a*Math.PI/2)},InOut:function(a){return.5*(1-Math.cos(Math.PI*a))}},Exponential:{In:function(a){return 0===a?0:Math.pow(1024,a-1)},Out:function(a){return 1===a?1:1-Math.pow(2,-10*a)},InOut:function(a){return 0===a?0:1===a?1:(a*=2)<1?.5*Math.pow(1024,a-1):.5*(-Math.pow(2,-10*(a-1))+2)}},Circular:{In:function(a){return 1-Math.sqrt(1-a*a)},Out:function(a){return Math.sqrt(1- --a*a)},InOut:function(a){return(a*=2)<1?-.5*(Math.sqrt(1-a*a)-1):.5*(Math.sqrt(1-(a-=2)*a)+1)}},Elastic:{In:function(a){var b,c=.1,d=.4;return 0===a?0:1===a?1:(!c||1>c?(c=1,b=d/4):b=d*Math.asin(1/c)/(2*Math.PI),-(c*Math.pow(2,10*(a-=1))*Math.sin((a-b)*2*Math.PI/d)))},Out:function(a){var b,c=.1,d=.4;return 0===a?0:1===a?1:(!c||1>c?(c=1,b=d/4):b=d*Math.asin(1/c)/(2*Math.PI),c*Math.pow(2,-10*a)*Math.sin((a-b)*2*Math.PI/d)+1)},InOut:function(a){var b,c=.1,d=.4;return 0===a?0:1===a?1:(!c||1>c?(c=1,b=d/4):b=d*Math.asin(1/c)/(2*Math.PI),(a*=2)<1?-.5*c*Math.pow(2,10*(a-=1))*Math.sin((a-b)*2*Math.PI/d):.5*c*Math.pow(2,-10*(a-=1))*Math.sin((a-b)*2*Math.PI/d)+1)}},Back:{In:function(a){var b=1.70158;return a*a*((b+1)*a-b) -},Out:function(a){var b=1.70158;return--a*a*((b+1)*a+b)+1},InOut:function(a){var b=2.5949095;return(a*=2)<1?.5*a*a*((b+1)*a-b):.5*((a-=2)*a*((b+1)*a+b)+2)}},Bounce:{In:function(a){return 1-d.Easing.Bounce.Out(1-a)},Out:function(a){return 1/2.75>a?7.5625*a*a:2/2.75>a?7.5625*(a-=1.5/2.75)*a+.75:2.5/2.75>a?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375},InOut:function(a){return.5>a?.5*d.Easing.Bounce.In(2*a):.5*d.Easing.Bounce.Out(2*a-1)+.5}}},d.Time=function(a){this.game=a,this._started=0,this._timeLastSecond=0,this._pauseStarted=0,this.physicsElapsed=0,this.time=0,this.pausedTime=0,this.now=0,this.elapsed=0,this.fps=0,this.fpsMin=1e3,this.fpsMax=0,this.msMin=1e3,this.msMax=0,this.frames=0,this.pauseDuration=0,this.timeToCall=0,this.lastTime=0,this.game.onPause.add(this.gamePaused,this),this.game.onResume.add(this.gameResumed,this),this._justResumed=!1},d.Time.prototype={update:function(a){this.now=a,this._justResumed&&(this.time=this.now,this._justResumed=!1),this.timeToCall=this.game.math.max(0,16-(a-this.lastTime)),this.elapsed=this.now-this.time,this.msMin=this.game.math.min(this.msMin,this.elapsed),this.msMax=this.game.math.max(this.msMax,this.elapsed),this.frames++,this.now>this._timeLastSecond+1e3&&(this.fps=Math.round(1e3*this.frames/(this.now-this._timeLastSecond)),this.fpsMin=this.game.math.min(this.fpsMin,this.fps),this.fpsMax=this.game.math.max(this.fpsMax,this.fps),this._timeLastSecond=this.now,this.frames=0),this.time=this.now,this.lastTime=a+this.timeToCall,this.physicsElapsed=1*(this.elapsed/1e3),this.physicsElapsed>1&&(this.physicsElapsed=1),this.game.paused&&(this.pausedTime=this.now-this._pauseStarted)},gamePaused:function(){this._pauseStarted=this.now},gameResumed:function(){this.time=Date.now(),this.pauseDuration=this.pausedTime,this._justResumed=!0},totalElapsedSeconds:function(){return.001*(this.now-this._started)},elapsedSince:function(a){return this.now-a},elapsedSecondsSince:function(a){return.001*(this.now-a)},reset:function(){this._started=this.now}},d.Timer=function(a){this.game=a,this._started=0,this._timeLastSecond=0,this.running=!1,this.events=[],this.onEvent=new d.Signal},d.Timer.prototype={add:function(a){this.events.push({delay:a,dispatched:!1,args:Array.prototype.splice.call(arguments,1)})},start:function(){this._started=this.game.time.now,this.running=!0},stop:function(){this.running=!1,this.events.length=0},update:function(){if(this.running)for(var a=this.seconds(),b=0,c=this.events.length;c>b;b++)this.events[b].dispatched===!1&&a>=this.events[b].delay&&(this.events[b].dispatched=!0,this.onEvent.dispatch.apply(this,this.events[b].args))},seconds:function(){return.001*(this.game.time.now-this._started)}},d.AnimationManager=function(a){this.sprite=a,this.game=a.game,this.currentFrame=null,this.updateIfVisible=!0,this.isLoaded=!1,this._frameData=null,this._anims={},this._outputFrames=[]},d.AnimationManager.prototype={loadFrameData:function(a){this._frameData=a,this.frame=0,this.isLoaded=!0},add:function(a,b,e,f,g){return null==this._frameData?(console.warn("No FrameData available for Phaser.Animation "+a),void 0):(e=e||60,"undefined"==typeof f&&(f=!1),"undefined"==typeof g&&(g=b&&"number"==typeof b[0]?!0:!1),null==this.sprite.events.onAnimationStart&&(this.sprite.events.onAnimationStart=new d.Signal,this.sprite.events.onAnimationComplete=new d.Signal,this.sprite.events.onAnimationLoop=new d.Signal),this._outputFrames.length=0,this._frameData.getFrameIndexes(b,g,this._outputFrames),this._anims[a]=new d.Animation(this.game,this.sprite,a,this._frameData,this._outputFrames,e,f),this.currentAnim=this._anims[a],this.currentFrame=this.currentAnim.currentFrame,this.sprite.setTexture(c.TextureCache[this.currentFrame.uuid]),this._anims[a])},validateFrames:function(a,b){"undefined"==typeof b&&(b=!0);for(var c=0;cthis._frameData.total)return!1}else if(this._frameData.checkFrameName(a[c])===!1)return!1;return!0},play:function(a,b,c,d){if(this._anims[a]){if(this.currentAnim!=this._anims[a])return this.currentAnim=this._anims[a],this.currentAnim.paused=!1,this.currentAnim.play(b,c,d);if(this.currentAnim.isPlaying===!1)return this.currentAnim.paused=!1,this.currentAnim.play(b,c,d)}},stop:function(a,b){"undefined"==typeof b&&(b=!1),"string"==typeof a?this._anims[a]&&(this.currentAnim=this._anims[a],this.currentAnim.stop(b)):this.currentAnim&&this.currentAnim.stop(b)},update:function(){return this.updateIfVisible&&this.sprite.visible===!1?!1:this.currentAnim&&this.currentAnim.update()===!0?(this.currentFrame=this.currentAnim.currentFrame,this.sprite.currentFrame=this.currentFrame,!0):!1},getAnimation:function(a){return"string"==typeof a&&this._anims[a]?this._anims[a]:!1},refreshFrame:function(){this.sprite.currentFrame=this.currentFrame,this.sprite.setTexture(c.TextureCache[this.currentFrame.uuid])},destroy:function(){this._anims={},this._frameData=null,this._frameIndex=0,this.currentAnim=null,this.currentFrame=null}},Object.defineProperty(d.AnimationManager.prototype,"frameData",{get:function(){return this._frameData}}),Object.defineProperty(d.AnimationManager.prototype,"frameTotal",{get:function(){return this._frameData?this._frameData.total:-1}}),Object.defineProperty(d.AnimationManager.prototype,"paused",{get:function(){return this.currentAnim.isPaused},set:function(a){this.currentAnim.paused=a}}),Object.defineProperty(d.AnimationManager.prototype,"frame",{get:function(){return this.currentFrame?this._frameIndex:void 0},set:function(a){"number"==typeof a&&this._frameData&&null!==this._frameData.getFrame(a)&&(this.currentFrame=this._frameData.getFrame(a),this._frameIndex=a,this.sprite.currentFrame=this.currentFrame,this.sprite.setTexture(c.TextureCache[this.currentFrame.uuid]))}}),Object.defineProperty(d.AnimationManager.prototype,"frameName",{get:function(){return this.currentFrame?this.currentFrame.name:void 0},set:function(a){"string"==typeof a&&this._frameData&&null!==this._frameData.getFrameByName(a)?(this.currentFrame=this._frameData.getFrameByName(a),this._frameIndex=this.currentFrame.index,this.sprite.currentFrame=this.currentFrame,this.sprite.setTexture(c.TextureCache[this.currentFrame.uuid])):console.warn("Cannot set frameName: "+a)}}),d.Animation=function(a,b,c,d,e,f,g){this.game=a,this._parent=b,this._frameData=d,this.name=c,this._frames=[],this._frames=this._frames.concat(e),this.delay=1e3/f,this.looped=g,this.killOnComplete=!1,this.isFinished=!1,this.isPlaying=!1,this.isPaused=!1,this._pauseStartTime=0,this._frameIndex=0,this._frameDiff=0,this._frameSkip=1,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex])},d.Animation.prototype={play:function(a,b,d){return"number"==typeof a&&(this.delay=1e3/a),"boolean"==typeof b&&(this.looped=b),"undefined"!=typeof d&&(this.killOnComplete=d),this.isPlaying=!0,this.isFinished=!1,this.paused=!1,this._timeLastFrame=this.game.time.now,this._timeNextFrame=this.game.time.now+this.delay,this._frameIndex=0,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this._parent.setTexture(c.TextureCache[this.currentFrame.uuid]),this._parent.events&&this._parent.events.onAnimationStart.dispatch(this._parent,this),this},restart:function(){this.isPlaying=!0,this.isFinished=!1,this.paused=!1,this._timeLastFrame=this.game.time.now,this._timeNextFrame=this.game.time.now+this.delay,this._frameIndex=0,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex])},stop:function(a){"undefined"==typeof a&&(a=!1),this.isPlaying=!1,this.isFinished=!0,this.paused=!1,a&&(this.currentFrame=this._frameData.getFrame(this._frames[0]))},update:function(){return this.isPaused?!1:this.isPlaying===!0&&this.game.time.now>=this._timeNextFrame?(this._frameSkip=1,this._frameDiff=this.game.time.now-this._timeNextFrame,this._timeLastFrame=this.game.time.now,this._frameDiff>this.delay&&(this._frameSkip=Math.floor(this._frameDiff/this.delay),this._frameDiff-=this._frameSkip*this.delay),this._timeNextFrame=this.game.time.now+(this.delay-this._frameDiff),this._frameIndex+=this._frameSkip,this._frameIndex>=this._frames.length?this.looped?(this._frameIndex%=this._frames.length,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.currentFrame&&this._parent.setTexture(c.TextureCache[this.currentFrame.uuid]),this._parent.events.onAnimationLoop.dispatch(this._parent,this)):this.onComplete():(this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.currentFrame&&this._parent.setTexture(c.TextureCache[this.currentFrame.uuid])),!0):!1},destroy:function(){this.game=null,this._parent=null,this._frames=null,this._frameData=null,this.currentFrame=null,this.isPlaying=!1},onComplete:function(){this.isPlaying=!1,this.isFinished=!0,this.paused=!1,this._parent.events&&this._parent.events.onAnimationComplete.dispatch(this._parent,this),this.killOnComplete&&this._parent.kill()}},Object.defineProperty(d.Animation.prototype,"paused",{get:function(){return this.isPaused},set:function(a){this.isPaused=a,a?this._pauseStartTime=this.game.time.now:this.isPlaying&&(this._timeNextFrame=this.game.time.now+this.delay)}}),Object.defineProperty(d.Animation.prototype,"frameTotal",{get:function(){return this._frames.length}}),Object.defineProperty(d.Animation.prototype,"frame",{get:function(){return null!==this.currentFrame?this.currentFrame.index:this._frameIndex},set:function(a){this.currentFrame=this._frameData.getFrame(a),null!==this.currentFrame&&(this._frameIndex=a,this._parent.setTexture(c.TextureCache[this.currentFrame.uuid]))}}),d.Animation.generateFrameNames=function(a,b,c,e,f){"undefined"==typeof e&&(e="");var g=[],h="";if(c>b)for(var i=b;c>=i;i++)h="number"==typeof f?d.Utils.pad(i.toString(),f,"0",1):i.toString(),h=a+h+e,g.push(h);else for(var i=b;i>=c;i--)h="number"==typeof f?d.Utils.pad(i.toString(),f,"0",1):i.toString(),h=a+h+e,g.push(h);return g},d.Frame=function(a,b,c,e,f,g,h){this.index=a,this.x=b,this.y=c,this.width=e,this.height=f,this.name=g,this.uuid=h,this.centerX=Math.floor(e/2),this.centerY=Math.floor(f/2),this.distance=d.Math.distance(0,0,e,f),this.rotated=!1,this.rotationDirection="cw",this.trimmed=!1,this.sourceSizeW=e,this.sourceSizeH=f,this.spriteSourceSizeX=0,this.spriteSourceSizeY=0,this.spriteSourceSizeW=0,this.spriteSourceSizeH=0},d.Frame.prototype={setTrim:function(a,b,c,d,e,f,g){this.trimmed=a,a&&(this.width=b,this.height=c,this.sourceSizeW=b,this.sourceSizeH=c,this.centerX=Math.floor(b/2),this.centerY=Math.floor(c/2),this.spriteSourceSizeX=d,this.spriteSourceSizeY=e,this.spriteSourceSizeW=f,this.spriteSourceSizeH=g)}},d.FrameData=function(){this._frames=[],this._frameNames=[]},d.FrameData.prototype={addFrame:function(a){return a.index=this._frames.length,this._frames.push(a),""!==a.name&&(this._frameNames[a.name]=a.index),a},getFrame:function(a){return this._frames.length>a?this._frames[a]:null},getFrameByName:function(a){return"number"==typeof this._frameNames[a]?this._frames[this._frameNames[a]]:null},checkFrameName:function(a){return null==this._frameNames[a]?!1:!0},getFrameRange:function(a,b,c){"undefined"==typeof c&&(c=[]);for(var d=a;b>=d;d++)c.push(this._frames[d]);return c},getFrames:function(a,b,c){if("undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=[]),"undefined"==typeof a||0===a.length)for(var d=0;dd;d++)b?c.push(this.getFrame(a[d])):c.push(this.getFrameByName(a[d]));return c},getFrameIndexes:function(a,b,c){if("undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=[]),"undefined"==typeof a||0===a.length)for(var d=0,e=this._frames.length;e>d;d++)c.push(this._frames[d].index);else for(var d=0,e=a.length;e>d;d++)b?c.push(a[d]):this.getFrameByName(a[d])&&c.push(this.getFrameByName(a[d]).index);return c}},Object.defineProperty(d.FrameData.prototype,"total",{get:function(){return this._frames.length}}),d.AnimationParser={spriteSheet:function(a,b,e,f,g){var h=a.cache.getImage(b);if(null==h)return null;var i=h.width,j=h.height;0>=e&&(e=Math.floor(-i/Math.min(-1,e))),0>=f&&(f=Math.floor(-j/Math.min(-1,f)));var k=Math.round(i/e),l=Math.round(j/f),m=k*l;if(-1!==g&&(m=g),0===i||0===j||e>i||f>j||0===m)return console.warn("Phaser.AnimationParser.spriteSheet: width/height zero or width/height < given frameWidth/frameHeight"),null;for(var n=new d.FrameData,o=0,p=0,q=0;m>q;q++){var r=a.rnd.uuid();n.addFrame(new d.Frame(q,o,p,e,f,"",r)),c.TextureCache[r]=new c.Texture(c.BaseTextureCache[b],{x:o,y:p,width:e,height:f}),o+=e,o===i&&(o=0,p+=f)}return n},JSONData:function(a,b,e){if(!b.frames)return console.warn("Phaser.AnimationParser.JSONData: Invalid Texture Atlas JSON given, missing 'frames' array"),console.log(b),void 0;for(var f,g=new d.FrameData,h=b.frames,i=0;i tag"),void 0;for(var f,g,h,i,j,k,l,m,n,o,p,q,r=new d.FrameData,s=b.getElementsByTagName("SubTexture"),t=0;t0)for(var c=0;c0)for(var c=0;c0?(this._fileIndex=0,this._progressChunk=100/this._fileList.length,this.loadFile()):(this.progress=100,this.hasLoaded=!0,this.onLoadComplete.dispatch()))},loadFile:function(){if(!this._fileList[this._fileIndex])return console.warn("Phaser.Loader loadFile invalid index "+this._fileIndex),void 0;var a=this._fileList[this._fileIndex],b=this;switch(a.type){case"image":case"spritesheet":case"textureatlas":case"bitmapfont":case"tileset":a.data=new Image,a.data.name=a.key,a.data.onload=function(){return b.fileComplete(b._fileIndex)},a.data.onerror=function(){return b.fileError(b._fileIndex)},a.data.crossOrigin=this.crossOrigin,a.data.src=this.baseURL+a.url;break;case"audio":a.url=this.getAudioURL(a.url),null!==a.url?this.game.sound.usingWebAudio?(this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="arraybuffer",this._xhr.onload=function(){return b.fileComplete(b._fileIndex)},this._xhr.onerror=function(){return b.fileError(b._fileIndex)},this._xhr.send()):this.game.sound.usingAudioTag&&(this.game.sound.touchLocked?(a.data=new Audio,a.data.name=a.key,a.data.preload="auto",a.data.src=this.baseURL+a.url,this.fileComplete(this._fileIndex)):(a.data=new Audio,a.data.name=a.key,a.data.onerror=function(){return b.fileError(b._fileIndex)},a.data.preload="auto",a.data.src=this.baseURL+a.url,a.data.addEventListener("canplaythrough",d.GAMES[this.game.id].load.fileComplete(this._fileIndex),!1),a.data.load())):this.fileError(this._fileIndex);break;case"tilemap":if(this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="text",a.format===d.Tilemap.TILED_JSON)this._xhr.onload=function(){return b.jsonLoadComplete(b._fileIndex)};else{if(a.format!==d.Tilemap.CSV)throw new Error("Phaser.Loader. Invalid Tilemap format: "+a.format);this._xhr.onload=function(){return b.csvLoadComplete(b._fileIndex)}}this._xhr.onerror=function(){return b.dataLoadError(b._fileIndex)},this._xhr.send();break;case"text":this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="text",this._xhr.onload=function(){return b.fileComplete(b._fileIndex)},this._xhr.onerror=function(){return b.fileError(b._fileIndex)},this._xhr.send();break;case"script":this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="text",this._xhr.onload=function(){return b.fileComplete(b._fileIndex)},this._xhr.onerror=function(){return b.fileError(b._fileIndex)},this._xhr.send()}},getAudioURL:function(a){var b;"string"==typeof a&&(a=[a]);for(var c=0;c100&&(this.progress=100),null!==this.preloadSprite&&(0===this.preloadSprite.direction?this.preloadSprite.crop.width=Math.floor(this.preloadSprite.width/100*this.progress):this.preloadSprite.crop.height=Math.floor(this.preloadSprite.height/100*this.progress),this.preloadSprite.sprite.crop=this.preloadSprite.crop),this.onFileComplete.dispatch(this.progress,this._fileList[a].key,b,this.totalLoadedFiles(),this._fileList.length),this.totalQueuedFiles()>0?(this._fileIndex++,this.loadFile()):(this.hasLoaded=!0,this.isLoading=!1,this.removeAll(),this.onLoadComplete.dispatch())},totalLoadedFiles:function(){for(var a=0,b=0;b tag"),void 0;var e=c.TextureCache[d],f={},g=b.getElementsByTagName("info")[0],h=b.getElementsByTagName("common")[0];f.font=g.attributes.getNamedItem("face").nodeValue,f.size=parseInt(g.attributes.getNamedItem("size").nodeValue,10),f.lineHeight=parseInt(h.attributes.getNamedItem("lineHeight").nodeValue,10),f.chars={};for(var i=b.getElementsByTagName("char"),j=0;j=this.durationMS&&(this.usingWebAudio?this.loop?(this.onLoop.dispatch(this),""===this.currentMarker?(this.currentTime=0,this.startTime=this.game.time.now):this.play(this.currentMarker,0,this.volume,!0,!0)):this.stop():this.loop?(this.onLoop.dispatch(this),this.play(this.currentMarker,0,this.volume,!0,!0)):this.stop()))},play:function(a,b,c,d,e){if(a=a||"",b=b||0,"undefined"==typeof c&&(c=this._volume),"undefined"==typeof d&&(d=!1),"undefined"==typeof e&&(e=!0),this.isPlaying!==!0||e!==!1||this.override!==!1){if(this.isPlaying&&this.override&&(this.usingWebAudio?"undefined"==typeof this._sound.stop?this._sound.noteOff(0):this._sound.stop(0):this.usingAudioTag&&(this._sound.pause(),this._sound.currentTime=0)),this.currentMarker=a,""!==a){if(!this.markers[a])return console.warn("Phaser.Sound.play: audio marker "+a+" doesn't exist"),void 0;this.position=this.markers[a].start,this.volume=this.markers[a].volume,this.loop=this.markers[a].loop,this.duration=this.markers[a].duration,this.durationMS=this.markers[a].durationMS,this._tempMarker=a,this._tempPosition=this.position,this._tempVolume=this.volume,this._tempLoop=this.loop}else this.position=b,this.volume=c,this.loop=d,this.duration=0,this.durationMS=0,this._tempMarker=a,this._tempPosition=b,this._tempVolume=c,this._tempLoop=d;this.usingWebAudio?this.game.cache.isSoundDecoded(this.key)?(null==this._buffer&&(this._buffer=this.game.cache.getSoundData(this.key)),this._sound=this.context.createBufferSource(),this._sound.buffer=this._buffer,this.externalNode?this._sound.connect(this.externalNode.input):this._sound.connect(this.gainNode),this.totalDuration=this._sound.buffer.duration,0===this.duration&&(this.duration=this.totalDuration,this.durationMS=1e3*this.totalDuration),this.loop&&""===a&&(this._sound.loop=!0),"undefined"==typeof this._sound.start?this._sound.noteGrainOn(0,this.position,this.duration):this._sound.start(0,this.position,this.duration),this.isPlaying=!0,this.startTime=this.game.time.now,this.currentTime=0,this.stopTime=this.startTime+this.durationMS,this.onPlay.dispatch(this)):(this.pendingPlayback=!0,this.game.cache.getSound(this.key)&&this.game.cache.getSound(this.key).isDecoding===!1&&this.game.sound.decode(this.key,this)):this.game.cache.getSound(this.key)&&this.game.cache.getSound(this.key).locked?(this.game.cache.reloadSound(this.key),this.pendingPlayback=!0):this._sound&&4==this._sound.readyState?(this._sound.play(),this.totalDuration=this._sound.duration,0===this.duration&&(this.duration=this.totalDuration,this.durationMS=1e3*this.totalDuration),this._sound.currentTime=this.position,this._sound.muted=this._muted,this._sound.volume=this._muted?0:this._volume,this.isPlaying=!0,this.startTime=this.game.time.now,this.currentTime=0,this.stopTime=this.startTime+this.durationMS,this.onPlay.dispatch(this)):this.pendingPlayback=!0}},restart:function(a,b,c,d){a=a||"",b=b||0,c=c||1,"undefined"==typeof d&&(d=!1),this.play(a,b,c,d,!0)},pause:function(){this.isPlaying&&this._sound&&(this.stop(),this.isPlaying=!1,this.paused=!0,this.pausedPosition=this.currentTime,this.pausedTime=this.game.time.now,this.onPause.dispatch(this))},resume:function(){if(this.paused&&this._sound){if(this.usingWebAudio){var a=this.position+this.pausedPosition/1e3;this._sound=this.context.createBufferSource(),this._sound.buffer=this._buffer,this._sound.connect(this.gainNode),"undefined"==typeof this._sound.start?this._sound.noteGrainOn(0,a,this.duration):this._sound.start(0,a,this.duration)}else this._sound.play();this.isPlaying=!0,this.paused=!1,this.startTime+=this.game.time.now-this.pausedTime,this.onResume.dispatch(this)}},stop:function(){this.isPlaying&&this._sound&&(this.usingWebAudio?"undefined"==typeof this._sound.stop?this._sound.noteOff(0):this._sound.stop(0):this.usingAudioTag&&(this._sound.pause(),this._sound.currentTime=0)),this.isPlaying=!1;var a=this.currentMarker;this.currentMarker="",this.onStop.dispatch(this,a)}},Object.defineProperty(d.Sound.prototype,"isDecoding",{get:function(){return this.game.cache.getSound(this.key).isDecoding}}),Object.defineProperty(d.Sound.prototype,"isDecoded",{get:function(){return this.game.cache.isSoundDecoded(this.key)}}),Object.defineProperty(d.Sound.prototype,"mute",{get:function(){return this._muted},set:function(a){a=a||null,a?(this._muted=!0,this.usingWebAudio?(this._muteVolume=this.gainNode.gain.value,this.gainNode.gain.value=0):this.usingAudioTag&&this._sound&&(this._muteVolume=this._sound.volume,this._sound.volume=0)):(this._muted=!1,this.usingWebAudio?this.gainNode.gain.value=this._muteVolume:this.usingAudioTag&&this._sound&&(this._sound.volume=this._muteVolume)),this.onMute.dispatch(this)}}),Object.defineProperty(d.Sound.prototype,"volume",{get:function(){return this._volume},set:function(a){this.usingWebAudio?(this._volume=a,this.gainNode.gain.value=a):this.usingAudioTag&&this._sound&&a>=0&&1>=a&&(this._volume=a,this._sound.volume=a)}}),d.SoundManager=function(a){this.game=a,this.onSoundDecode=new d.Signal,this._muted=!1,this._unlockSource=null,this._volume=1,this._sounds=[],this.context=null,this.usingWebAudio=!0,this.usingAudioTag=!1,this.noAudio=!1,this.connectToMaster=!0,this.touchLocked=!1,this.channels=32},d.SoundManager.prototype={boot:function(){if(this.game.device.iOS&&this.game.device.webAudio===!1&&(this.channels=1),this.game.device.iOS||window.PhaserGlobal&&window.PhaserGlobal.fakeiOSTouchLock?(this.game.input.touch.callbackContext=this,this.game.input.touch.touchStartCallback=this.unlock,this.game.input.mouse.callbackContext=this,this.game.input.mouse.mouseDownCallback=this.unlock,this.touchLocked=!0):this.touchLocked=!1,window.PhaserGlobal){if(window.PhaserGlobal.disableAudio===!0)return this.usingWebAudio=!1,this.noAudio=!0,void 0;if(window.PhaserGlobal.disableWebAudio===!0)return this.usingWebAudio=!1,this.usingAudioTag=!0,this.noAudio=!1,void 0}window.AudioContext?this.context=new window.AudioContext:window.webkitAudioContext?this.context=new window.webkitAudioContext:window.Audio?(this.usingWebAudio=!1,this.usingAudioTag=!0):(this.usingWebAudio=!1,this.noAudio=!0),null!==this.context&&(this.masterGain="undefined"==typeof this.context.createGain?this.context.createGainNode():this.context.createGain(),this.masterGain.gain.value=1,this.masterGain.connect(this.context.destination))},unlock:function(){if(this.touchLocked!==!1)if(this.game.device.webAudio===!1||window.PhaserGlobal&&window.PhaserGlobal.disableWebAudio===!0)this.touchLocked=!1,this._unlockSource=null,this.game.input.touch.callbackContext=null,this.game.input.touch.touchStartCallback=null,this.game.input.mouse.callbackContext=null,this.game.input.mouse.mouseDownCallback=null;else{var a=this.context.createBuffer(1,1,22050);this._unlockSource=this.context.createBufferSource(),this._unlockSource.buffer=a,this._unlockSource.connect(this.context.destination),this._unlockSource.noteOn(0)}},stopAll:function(){for(var a=0;a255)return d.Color.getColor(255,255,255);if(a>b)return d.Color.getColor(255,255,255);var e=a+Math.round(Math.random()*(b-a)),f=a+Math.round(Math.random()*(b-a)),g=a+Math.round(Math.random()*(b-a));return d.Color.getColor32(c,e,f,g)},getRGB:function(a){return{alpha:a>>>24,red:255&a>>16,green:255&a>>8,blue:255&a}},getWebRGB:function(a){var b=(a>>>24)/255,c=255&a>>16,d=255&a>>8,e=255&a;return"rgba("+c.toString()+","+d.toString()+","+e.toString()+","+b.toString()+")"},getAlpha:function(a){return a>>>24},getAlphaFloat:function(a){return(a>>>24)/255},getRed:function(a){return 255&a>>16},getGreen:function(a){return 255&a>>8},getBlue:function(a){return 255&a}},d.Physics={},d.Physics.Arcade=function(a){this.game=a,this.gravity=new d.Point,this.bounds=new d.Rectangle(0,0,a.world.width,a.world.height),this.maxObjects=10,this.maxLevels=4,this.OVERLAP_BIAS=4,this.quadTree=new d.QuadTree(this,this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height,this.maxObjects,this.maxLevels),this.quadTreeID=0,this._bounds1=new d.Rectangle,this._bounds2=new d.Rectangle,this._overlap=0,this._maxOverlap=0,this._velocity1=0,this._velocity2=0,this._newVelocity1=0,this._newVelocity2=0,this._average=0,this._mapData=[],this._mapTiles=0,this._result=!1,this._total=0,this._angle=0,this._dx=0,this._dy=0},d.Physics.Arcade.prototype={updateMotion:function(a){this._velocityDelta=60*.5*(this.computeVelocity(0,a,a.angularVelocity,a.angularAcceleration,a.angularDrag,a.maxAngular)-a.angularVelocity)*this.game.time.physicsElapsed,a.angularVelocity+=this._velocityDelta,a.rotation+=a.angularVelocity*this.game.time.physicsElapsed,a.angularVelocity+=this._velocityDelta,this._velocityDelta=60*.5*(this.computeVelocity(1,a,a.velocity.x,a.acceleration.x,a.drag.x,a.maxVelocity.x)-a.velocity.x)*this.game.time.physicsElapsed,a.velocity.x+=this._velocityDelta,a.x+=a.velocity.x*this.game.time.physicsElapsed,a.velocity.x+=this._velocityDelta,this._velocityDelta=60*.5*(this.computeVelocity(2,a,a.velocity.y,a.acceleration.y,a.drag.y,a.maxVelocity.y)-a.velocity.y)*this.game.time.physicsElapsed,a.velocity.y+=this._velocityDelta,a.y+=a.velocity.y*this.game.time.physicsElapsed,a.velocity.y+=this._velocityDelta},computeVelocity:function(a,b,c,d,e,f){return f=f||1e4,1==a&&b.allowGravity?c+=this.gravity.x+b.gravity.x:2==a&&b.allowGravity&&(c+=this.gravity.y+b.gravity.y),0!==d?c+=d*this.game.time.physicsElapsed:0!==e&&(this._drag=e*this.game.time.physicsElapsed,c-this._drag>0?c-=this._drag:c+this._drag<0?c+=this._drag:c=0),c>f?c=f:-f>c&&(c=-f),c},preUpdate:function(){this.quadTree.clear(),this.quadTreeID=0,this.quadTree=new d.QuadTree(this,this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height,this.maxObjects,this.maxLevels)},postUpdate:function(){this.quadTree.clear()},overlap:function(a,b,c,e,f){return c=c||null,e=e||null,f=f||c,this._result=!1,this._total=0,a&&b&&a.exists&&b.exists&&(a.type==d.SPRITE?b.type==d.SPRITE?this.overlapSpriteVsSprite(a,b,c,e,f):(b.type==d.GROUP||b.type==d.EMITTER)&&this.overlapSpriteVsGroup(a,b,c,e,f):a.type==d.GROUP?b.type==d.SPRITE?this.overlapSpriteVsGroup(b,a,c,e,f):(b.type==d.GROUP||b.type==d.EMITTER)&&this.overlapGroupVsGroup(a,b,c,e,f):a.type==d.EMITTER&&(b.type==d.SPRITE?this.overlapSpriteVsGroup(b,a,c,e,f):(b.type==d.GROUP||b.type==d.EMITTER)&&this.overlapGroupVsGroup(a,b,c,e,f))),this._total>0},overlapSpriteVsSprite:function(a,b,c,e,f){this._result=d.Rectangle.intersects(a.body,b.body),this._result&&(e?e.call(f,a,b)&&(this._total++,c&&c.call(f,a,b)):(this._total++,c&&c.call(f,a,b)))},overlapSpriteVsGroup:function(a,b,c,e,f){if(0!==b.length){this._potentials=this.quadTree.retrieve(a);for(var g=0,h=this._potentials.length;h>g;g++)this._potentials[g].sprite.group==b&&(this._result=d.Rectangle.intersects(a.body,this._potentials[g]),this._result&&e&&(this._result=e.call(f,a,this._potentials[g].sprite)),this._result&&(this._total++,c&&c.call(f,a,this._potentials[g].sprite)))}},overlapGroupVsGroup:function(a,b,c,d,e){if(0!==a.length&&0!==b.length&&a._container.first._iNext){var f=a._container.first._iNext;do f.exists&&this.overlapSpriteVsGroup(f,b,c,d,e),f=f._iNext;while(f!=a._container.last._iNext)}},collide:function(a,b,c,e,f){return c=c||null,e=e||null,f=f||c,this._result=!1,this._total=0,a&&b&&a.exists&&b.exists&&(a.type==d.SPRITE?b.type==d.SPRITE?this.collideSpriteVsSprite(a,b,c,e,f):b.type==d.GROUP||b.type==d.EMITTER?this.collideSpriteVsGroup(a,b,c,e,f):b.type==d.TILEMAPLAYER&&this.collideSpriteVsTilemapLayer(a,b,c,e,f):a.type==d.GROUP?b.type==d.SPRITE?this.collideSpriteVsGroup(b,a,c,e,f):b.type==d.GROUP||b.type==d.EMITTER?this.collideGroupVsGroup(a,b,c,e,f):b.type==d.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,b,c,e,f):a.type==d.TILEMAPLAYER?b.type==d.SPRITE?this.collideSpriteVsTilemapLayer(b,a,c,e,f):(b.type==d.GROUP||b.type==d.EMITTER)&&this.collideGroupVsTilemapLayer(b,a,c,e,f):a.type==d.EMITTER&&(b.type==d.SPRITE?this.collideSpriteVsGroup(b,a,c,e,f):b.type==d.GROUP||b.type==d.EMITTER?this.collideGroupVsGroup(a,b,c,e,f):b.type==d.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,b,c,e,f))),this._total>0},collideSpriteVsTilemapLayer:function(a,b,c,d,e){if(this._mapData=b.getTiles(a.body.x,a.body.y,a.body.width,a.body.height,!0),0!==this._mapData.length)for(var f=0;ff;f++)this._potentials[f].sprite.group==b&&(this.separate(a.body,this._potentials[f]),this._result&&d&&(this._result=d.call(e,a,this._potentials[f].sprite)),this._result&&(this._total++,c&&c.call(e,a,this._potentials[f].sprite)))}},collideGroupVsGroup:function(a,b,c,d,e){if(0!==a.length&&0!==b.length&&a._container.first._iNext){var f=a._container.first._iNext;do f.exists&&this.collideSpriteVsGroup(f,b,c,d,e),f=f._iNext;while(f!=a._container.last._iNext)}},separate:function(a,b){this._result=this.separateX(a,b)||this.separateY(a,b)},separateX:function(a,b){return a.immovable&&b.immovable?!1:(this._overlap=0,d.Rectangle.intersects(a,b)&&(this._maxOverlap=a.deltaAbsX()+b.deltaAbsX()+this.OVERLAP_BIAS,0===a.deltaX()&&0===b.deltaX()?(a.embedded=!0,b.embedded=!0):a.deltaX()>b.deltaX()?(this._overlap=a.x+a.width-b.x,this._overlap>this._maxOverlap||a.allowCollision.right===!1||b.allowCollision.left===!1?this._overlap=0:(a.touching.right=!0,b.touching.left=!0)):a.deltaX()this._maxOverlap||a.allowCollision.left===!1||b.allowCollision.right===!1?this._overlap=0:(a.touching.left=!0,b.touching.right=!0)),0!==this._overlap)?(a.overlapX=this._overlap,b.overlapX=this._overlap,a.customSeparateX||b.customSeparateX?!0:(this._velocity1=a.velocity.x,this._velocity2=b.velocity.x,a.immovable||b.immovable?a.immovable?b.immovable||(b.x+=this._overlap,b.velocity.x=this._velocity1-this._velocity2*b.bounce.x):(a.x=a.x-this._overlap,a.velocity.x=this._velocity2-this._velocity1*a.bounce.x):(this._overlap*=.5,a.x=a.x-this._overlap,b.x+=this._overlap,this._newVelocity1=Math.sqrt(this._velocity2*this._velocity2*b.mass/a.mass)*(this._velocity2>0?1:-1),this._newVelocity2=Math.sqrt(this._velocity1*this._velocity1*a.mass/b.mass)*(this._velocity1>0?1:-1),this._average=.5*(this._newVelocity1+this._newVelocity2),this._newVelocity1-=this._average,this._newVelocity2-=this._average,a.velocity.x=this._average+this._newVelocity1*a.bounce.x,b.velocity.x=this._average+this._newVelocity2*b.bounce.x),a.updateHulls(),b.updateHulls(),!0)):!1)},separateY:function(a,b){return a.immovable&&b.immovable?!1:(this._overlap=0,d.Rectangle.intersects(a,b)&&(this._maxOverlap=a.deltaAbsY()+b.deltaAbsY()+this.OVERLAP_BIAS,0===a.deltaY()&&0===b.deltaY()?(a.embedded=!0,b.embedded=!0):a.deltaY()>b.deltaY()?(this._overlap=a.y+a.height-b.y,this._overlap>this._maxOverlap||a.allowCollision.down===!1||b.allowCollision.up===!1?this._overlap=0:(a.touching.down=!0,b.touching.up=!0)):a.deltaY()this._maxOverlap||a.allowCollision.up===!1||b.allowCollision.down===!1?this._overlap=0:(a.touching.up=!0,b.touching.down=!0)),0!==this._overlap)?(a.overlapY=this._overlap,b.overlapY=this._overlap,a.customSeparateY||b.customSeparateY?!0:(this._velocity1=a.velocity.y,this._velocity2=b.velocity.y,a.immovable||b.immovable?a.immovable?b.immovable||(b.y+=this._overlap,b.velocity.y=this._velocity1-this._velocity2*b.bounce.y,a.sprite.active&&a.moves&&a.deltaY()b.deltaY()&&(a.x+=b.x-b.lastX)):(this._overlap*=.5,a.y=a.y-this._overlap,b.y+=this._overlap,this._newVelocity1=Math.sqrt(this._velocity2*this._velocity2*b.mass/a.mass)*(this._velocity2>0?1:-1),this._newVelocity2=Math.sqrt(this._velocity1*this._velocity1*a.mass/b.mass)*(this._velocity1>0?1:-1),this._average=.5*(this._newVelocity1+this._newVelocity2),this._newVelocity1-=this._average,this._newVelocity2-=this._average,a.velocity.y=this._average+this._newVelocity1*a.bounce.y,b.velocity.y=this._average+this._newVelocity2*b.bounce.y),a.updateHulls(),b.updateHulls(),!0)):!1)},separateTile:function(a,b){return this._result=this.separateTileX(a,b,!0)||this.separateTileY(a,b,!0),this._result},separateTileX:function(a,b,c){return a.immovable||0===a.deltaX()||d.Rectangle.intersects(a.hullX,b)===!1?!1:(this._overlap=0,a.deltaX()<0?(this._overlap=b.right-a.hullX.x,a.allowCollision.left===!1||b.tile.collideRight===!1?this._overlap=0:a.touching.left=!0):(this._overlap=a.hullX.right-b.x,a.allowCollision.right===!1||b.tile.collideLeft===!1?this._overlap=0:a.touching.right=!0),0!==this._overlap?(c&&(a.x=a.deltaX()<0?a.x+this._overlap:a.x-this._overlap,a.velocity.x=0===a.bounce.x?0:-a.velocity.x*a.bounce.x,a.updateHulls()),!0):!1)},separateTileY:function(a,b,c){return a.immovable||0===a.deltaY()||d.Rectangle.intersects(a.hullY,b)===!1?!1:(this._overlap=0,a.deltaY()<0?(this._overlap=b.bottom-a.hullY.y,a.allowCollision.up===!1||b.tile.collideDown===!1?this._overlap=0:a.touching.up=!0):(this._overlap=a.hullY.bottom-b.y,a.allowCollision.down===!1||b.tile.collideUp===!1?this._overlap=0:a.touching.down=!0),0!==this._overlap?(c&&(a.y=a.deltaY()<0?a.y+this._overlap:a.y-this._overlap,a.velocity.y=0===a.bounce.y?0:-a.velocity.y*a.bounce.y,a.updateHulls()),!0):!1)},moveToObject:function(a,b,c,d){return"undefined"==typeof c&&(c=60),"undefined"==typeof d&&(d=0),this._angle=Math.atan2(b.y-a.y,b.x-a.x),d>0&&(c=this.distanceBetween(a,b)/(d/1e3)),a.body.velocity.x=Math.cos(this._angle)*c,a.body.velocity.y=Math.sin(this._angle)*c,this._angle},moveToPointer:function(a,b,c,d){return"undefined"==typeof b&&(b=60),c=c||this.game.input.activePointer,"undefined"==typeof d&&(d=0),this._angle=this.angleToPointer(a,c),d>0&&(b=this.distanceToPointer(a,c)/(d/1e3)),a.body.velocity.x=Math.cos(this._angle)*b,a.body.velocity.y=Math.sin(this._angle)*b,this._angle},moveToXY:function(a,b,c,d,e){return"undefined"==typeof d&&(d=60),"undefined"==typeof e&&(e=0),this._angle=Math.atan2(c-a.y,b-a.x),e>0&&(d=this.distanceToXY(a,b,c)/(e/1e3)),a.body.velocity.x=Math.cos(this._angle)*d,a.body.velocity.y=Math.sin(this._angle)*d,this._angle},velocityFromAngle:function(a,b,c){return"undefined"==typeof b&&(b=60),c=c||new d.Point,c.setTo(Math.cos(this.game.math.degToRad(a))*b,Math.sin(this.game.math.degToRad(a))*b)},velocityFromRotation:function(a,b,c){return"undefined"==typeof b&&(b=60),c=c||new d.Point,c.setTo(Math.cos(a)*b,Math.sin(a)*b)},accelerationFromRotation:function(a,b,c){return"undefined"==typeof b&&(b=60),c=c||new d.Point,c.setTo(Math.cos(a)*b,Math.sin(a)*b)},accelerateToObject:function(a,b,c,d,e){return"undefined"==typeof c&&(c=60),"undefined"==typeof d&&(d=1e3),"undefined"==typeof e&&(e=1e3),this._angle=this.angleBetween(a,b),a.body.acceleration.setTo(Math.cos(this._angle)*c,Math.sin(this._angle)*c),a.body.maxVelocity.setTo(d,e),this._angle},accelerateToPointer:function(a,b,c,d,e){return"undefined"==typeof c&&(c=60),"undefined"==typeof b&&(b=this.game.input.activePointer),"undefined"==typeof d&&(d=1e3),"undefined"==typeof e&&(e=1e3),this._angle=this.angleToPointer(a,b),a.body.acceleration.setTo(Math.cos(this._angle)*c,Math.sin(this._angle)*c),a.body.maxVelocity.setTo(d,e),this._angle},accelerateToXY:function(a,b,c,d,e,f){return"undefined"==typeof d&&(d=60),"undefined"==typeof e&&(e=1e3),"undefined"==typeof f&&(f=1e3),this._angle=this.angleToXY(a,b,c),a.body.acceleration.setTo(Math.cos(this._angle)*d,Math.sin(this._angle)*d),a.body.maxVelocity.setTo(e,f),this._angle},distanceBetween:function(a,b){return this._dx=a.x-b.x,this._dy=a.y-b.y,Math.sqrt(this._dx*this._dx+this._dy*this._dy)},distanceToXY:function(a,b,c){return this._dx=a.x-b,this._dy=a.y-c,Math.sqrt(this._dx*this._dx+this._dy*this._dy)},distanceToPointer:function(a,b){return b=b||this.game.input.activePointer,this._dx=a.x-b.x,this._dy=a.y-b.y,Math.sqrt(this._dx*this._dx+this._dy*this._dy)},angleBetween:function(a,b){return this._dx=b.x-a.x,this._dy=b.y-a.y,Math.atan2(this._dy,this._dx)},angleToXY:function(a,b,c){return this._dx=b-a.x,this._dy=c-a.y,Math.atan2(this._dy,this._dx)},angleToPointer:function(a,b){return b=b||this.game.input.activePointer,this._dx=b.worldX-a.x,this._dy=b.worldY-a.y,Math.atan2(this._dy,this._dx)}},d.Physics.Arcade.Body=function(a){this.sprite=a,this.game=a.game,this.offset=new d.Point,this.x=a.x,this.y=a.y,this.preX=a.x,this.preY=a.y,this.preRotation=a.angle,this.screenX=a.x,this.screenY=a.y,this.sourceWidth=a.currentFrame.sourceSizeW,this.sourceHeight=a.currentFrame.sourceSizeH,this.width=a.currentFrame.sourceSizeW,this.height=a.currentFrame.sourceSizeH,this.halfWidth=Math.floor(a.currentFrame.sourceSizeW/2),this.halfHeight=Math.floor(a.currentFrame.sourceSizeH/2),this.center=new d.Point(this.x+this.halfWidth,this.y+this.halfHeight),this._sx=a.scale.x,this._sy=a.scale.y,this.velocity=new d.Point,this.acceleration=new d.Point,this.drag=new d.Point,this.gravity=new d.Point,this.bounce=new d.Point,this.maxVelocity=new d.Point(1e4,1e4),this.angularVelocity=0,this.angularAcceleration=0,this.angularDrag=0,this.maxAngular=1e3,this.mass=1,this.skipQuadTree=!1,this.quadTreeIDs=[],this.quadTreeIndex=-1,this.allowCollision={none:!1,any:!0,up:!0,down:!0,left:!0,right:!0},this.touching={none:!0,up:!1,down:!1,left:!1,right:!1},this.wasTouching={none:!0,up:!1,down:!1,left:!1,right:!1},this.facing=d.NONE,this.immovable=!1,this.moves=!0,this.rotation=0,this.allowRotation=!0,this.allowGravity=!0,this.customSeparateX=!1,this.customSeparateY=!1,this.overlapX=0,this.overlapY=0,this.hullX=new d.Rectangle,this.hullY=new d.Rectangle,this.embedded=!1,this.collideWorldBounds=!1},d.Physics.Arcade.Body.prototype={updateBounds:function(a,b,c,d){(c!=this._sx||d!=this._sy)&&(this.width=this.sourceWidth*c,this.height=this.sourceHeight*d,this.halfWidth=Math.floor(this.width/2),this.halfHeight=Math.floor(this.height/2),this._sx=c,this._sy=d,this.center.setTo(this.x+this.halfWidth,this.y+this.halfHeight))},preUpdate:function(){this.wasTouching.none=this.touching.none,this.wasTouching.up=this.touching.up,this.wasTouching.down=this.touching.down,this.wasTouching.left=this.touching.left,this.wasTouching.right=this.touching.right,this.touching.none=!0,this.touching.up=!1,this.touching.down=!1,this.touching.left=!1,this.touching.right=!1,this.embedded=!1,this.screenX=this.sprite.worldTransform[2]-this.sprite.anchor.x*this.width+this.offset.x,this.screenY=this.sprite.worldTransform[5]-this.sprite.anchor.y*this.height+this.offset.y,this.preX=this.sprite.world.x-this.sprite.anchor.x*this.width+this.offset.x,this.preY=this.sprite.world.y-this.sprite.anchor.y*this.height+this.offset.y,this.preRotation=this.sprite.angle,this.x=this.preX,this.y=this.preY,this.rotation=this.preRotation,this.moves&&(this.game.physics.updateMotion(this),this.collideWorldBounds&&this.checkWorldBounds(),this.updateHulls()),this.skipQuadTree===!1&&this.allowCollision.none===!1&&this.sprite.visible&&this.sprite.alive&&(this.quadTreeIDs=[],this.quadTreeIndex=-1,this.game.physics.quadTree.insert(this))},postUpdate:function(){this.deltaX()<0?this.facing=d.LEFT:this.deltaX()>0&&(this.facing=d.RIGHT),this.deltaY()<0?this.facing=d.UP:this.deltaY()>0&&(this.facing=d.DOWN),(0!==this.deltaX()||0!==this.deltaY())&&(this.sprite.x+=this.deltaX(),this.sprite.y+=this.deltaY(),this.center.setTo(this.x+this.halfWidth,this.y+this.halfHeight)),this.allowRotation&&(this.sprite.angle+=this.deltaZ())},updateHulls:function(){this.hullX.setTo(this.x,this.preY,this.width,this.height),this.hullY.setTo(this.preX,this.y,this.width,this.height)},checkWorldBounds:function(){this.xthis.game.world.bounds.right&&(this.x=this.game.world.bounds.right-this.width,this.velocity.x*=-this.bounce.x),this.ythis.game.world.bounds.bottom&&(this.y=this.game.world.bounds.bottom-this.height,this.velocity.y*=-this.bounce.y)},setSize:function(a,b,c,d){c=c||this.offset.x,d=d||this.offset.y,this.sourceWidth=a,this.sourceHeight=b,this.width=this.sourceWidth*this._sx,this.height=this.sourceHeight*this._sy,this.halfWidth=Math.floor(this.width/2),this.halfHeight=Math.floor(this.height/2),this.offset.setTo(c,d),this.center.setTo(this.x+this.halfWidth,this.y+this.halfHeight)},reset:function(){this.velocity.setTo(0,0),this.acceleration.setTo(0,0),this.angularVelocity=0,this.angularAcceleration=0,this.preX=this.sprite.world.x-this.sprite.anchor.x*this.width+this.offset.x,this.preY=this.sprite.world.y-this.sprite.anchor.y*this.height+this.offset.y,this.preRotation=this.sprite.angle,this.x=this.preX,this.y=this.preY,this.rotation=this.preRotation,this.center.setTo(this.x+this.halfWidth,this.y+this.halfHeight)},deltaAbsX:function(){return this.deltaX()>0?this.deltaX():-this.deltaX()},deltaAbsY:function(){return this.deltaY()>0?this.deltaY():-this.deltaY()},deltaX:function(){return this.x-this.preX},deltaY:function(){return this.y-this.preY},deltaZ:function(){return this.rotation-this.preRotation}},Object.defineProperty(d.Physics.Arcade.Body.prototype,"bottom",{get:function(){return this.y+this.height},set:function(a){this.height=a<=this.y?0:this.y-a}}),Object.defineProperty(d.Physics.Arcade.Body.prototype,"right",{get:function(){return this.x+this.width},set:function(a){this.width=a<=this.x?0:this.x+a}}),d.Particles=function(a){this.game=a,this.emitters={},this.ID=0},d.Particles.prototype={add:function(a){return this.emitters[a.name]=a,a},remove:function(a){delete this.emitters[a.name]},update:function(){for(var a in this.emitters)this.emitters[a].exists&&this.emitters[a].update()}},d.Particles.Arcade={},d.Particles.Arcade.Emitter=function(a,b,c,e){this.maxParticles=e||50,d.Group.call(this,a),this.name="emitter"+this.game.particles.ID++,this.type=d.EMITTER,this.x=0,this.y=0,this.width=1,this.height=1,this.minParticleSpeed=new d.Point(-100,-100),this.maxParticleSpeed=new d.Point(100,100),this.minParticleScale=1,this.maxParticleScale=1,this.minRotation=-360,this.maxRotation=360,this.gravity=2,this.particleClass=null,this.particleDrag=new d.Point,this.angularDrag=0,this.frequency=100,this.lifespan=2e3,this.bounce=new d.Point,this._quantity=0,this._timer=0,this._counter=0,this._explode=!0,this.on=!1,this.exists=!0,this.emitX=b,this.emitY=c},d.Particles.Arcade.Emitter.prototype=Object.create(d.Group.prototype),d.Particles.Arcade.Emitter.prototype.constructor=d.Particles.Arcade.Emitter,d.Particles.Arcade.Emitter.prototype.update=function(){if(this.on)if(this._explode){this._counter=0;do this.emitParticle(),this._counter++;while(this._counter=this._timer&&(this.emitParticle(),this._counter++,this._quantity>0&&this._counter>=this._quantity&&(this.on=!1),this._timer=this.game.time.now+this.frequency)},d.Particles.Arcade.Emitter.prototype.makeParticles=function(a,b,c,e,f){"undefined"==typeof b&&(b=0),c=c||this.maxParticles,e=e||0,"undefined"==typeof f&&(f=!1);for(var g,h=0,i=a,j=0;c>h;)null==this.particleClass&&("object"==typeof a&&(i=this.game.rnd.pick(a)),"object"==typeof b&&(j=this.game.rnd.pick(b)),g=new d.Sprite(this.game,0,0,i,j)),e>0?(g.body.allowCollision.any=!0,g.body.allowCollision.none=!1):g.body.allowCollision.none=!0,g.body.collideWorldBounds=f,g.exists=!1,g.visible=!1,g.anchor.setTo(.5,.5),this.add(g),h++;return this},d.Particles.Arcade.Emitter.prototype.kill=function(){this.on=!1,this.alive=!1,this.exists=!1},d.Particles.Arcade.Emitter.prototype.revive=function(){this.alive=!0,this.exists=!0},d.Particles.Arcade.Emitter.prototype.start=function(a,b,c,d){"boolean"!=typeof a&&(a=!0),b=b||0,c=c||250,d=d||0,this.revive(),this.visible=!0,this.on=!0,this._explode=a,this.lifespan=b,this.frequency=c,a?this._quantity=d:this._quantity+=d,this._counter=0,this._timer=this.game.time.now+c},d.Particles.Arcade.Emitter.prototype.emitParticle=function(){var a=this.getFirstExists(!1);if(null!=a){if(this.width>1||this.height>1?a.reset(this.game.rnd.integerInRange(this.left,this.right),this.game.rnd.integerInRange(this.top,this.bottom)):a.reset(this.emitX,this.emitY),a.lifespan=this.lifespan,a.body.bounce.setTo(this.bounce.x,this.bounce.y),a.body.velocity.x=this.minParticleSpeed.x!=this.maxParticleSpeed.x?this.game.rnd.integerInRange(this.minParticleSpeed.x,this.maxParticleSpeed.x):this.minParticleSpeed.x,a.body.velocity.y=this.minParticleSpeed.y!=this.maxParticleSpeed.y?this.game.rnd.integerInRange(this.minParticleSpeed.y,this.maxParticleSpeed.y):this.minParticleSpeed.y,a.body.gravity.y=this.gravity,a.body.angularVelocity=this.minRotation!=this.maxRotation?this.game.rnd.integerInRange(this.minRotation,this.maxRotation):this.minRotation,1!==this.minParticleScale||1!==this.maxParticleScale){var b=this.game.rnd.realInRange(this.minParticleScale,this.maxParticleScale);a.scale.setTo(b,b)}a.body.drag.x=this.particleDrag.x,a.body.drag.y=this.particleDrag.y,a.body.angularDrag=this.angularDrag}},d.Particles.Arcade.Emitter.prototype.setSize=function(a,b){this.width=a,this.height=b},d.Particles.Arcade.Emitter.prototype.setXSpeed=function(a,b){a=a||0,b=b||0,this.minParticleSpeed.x=a,this.maxParticleSpeed.x=b},d.Particles.Arcade.Emitter.prototype.setYSpeed=function(a,b){a=a||0,b=b||0,this.minParticleSpeed.y=a,this.maxParticleSpeed.y=b},d.Particles.Arcade.Emitter.prototype.setRotation=function(a,b){a=a||0,b=b||0,this.minRotation=a,this.maxRotation=b},d.Particles.Arcade.Emitter.prototype.at=function(a){this.emitX=a.center.x,this.emitY=a.center.y},Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"alpha",{get:function(){return this._container.alpha},set:function(a){this._container.alpha=a}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"visible",{get:function(){return this._container.visible},set:function(a){this._container.visible=a}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"x",{get:function(){return this.emitX},set:function(a){this.emitX=a}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"y",{get:function(){return this.emitY},set:function(a){this.emitY=a}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"left",{get:function(){return Math.floor(this.x-this.width/2)}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"right",{get:function(){return Math.floor(this.x+this.width/2)}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"top",{get:function(){return Math.floor(this.y-this.height/2)}}),Object.defineProperty(d.Particles.Arcade.Emitter.prototype,"bottom",{get:function(){return Math.floor(this.y+this.height/2)}}),d.Tile=function(a,b,c,d,e,f){this.tileset=a,this.index=b,this.width=e,this.height=f,this.x=c,this.y=d,this.mass=1,this.collideNone=!0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.separateX=!0,this.separateY=!0,this.collisionCallback=null,this.collisionCallbackContext=this},d.Tile.prototype={setCollisionCallback:function(a,b){this.collisionCallbackContext=b,this.collisionCallback=a},destroy:function(){this.tileset=null},setCollision:function(a,b,c,d){this.collideLeft=a,this.collideRight=b,this.collideUp=c,this.collideDown=d,this.collideNone=a||b||c||d?!1:!0},resetCollision:function(){this.collideNone=!0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1}},Object.defineProperty(d.Tile.prototype,"bottom",{get:function(){return this.y+this.height}}),Object.defineProperty(d.Tile.prototype,"right",{get:function(){return this.x+this.width}}),d.Tilemap=function(a,b){this.game=a,this.layers=null,"string"==typeof b?(this.key=b,this.layers=a.cache.getTilemapData(b).layers,this.calculateIndexes()):this.layers=[],this.currentLayer=0,this.debugMap=[],this.dirty=!1,this._results=[],this._tempA=0,this._tempB=0},d.Tilemap.CSV=0,d.Tilemap.TILED_JSON=1,d.Tilemap.prototype={create:function(a,b,c){for(var e=[],f=0;c>f;f++){e[f]=[];for(var g=0;b>g;g++)e[f][g]=0}this.layers.push({name:a,width:b,height:c,alpha:1,visible:!0,tileMargin:0,tileSpacing:0,format:d.Tilemap.CSV,data:e,indexes:[]}),this.currentLayer=this.layers.length-1,this.dirty=!0},calculateIndexes:function(){for(var a=0;a=0&&b=0&&c=0&&a=0&&b=0&&a=0&&b=0&&b=0&&ca&&(a=0),0>b&&(b=0),c>this.layers[e].width&&(c=this.layers[e].width),d>this.layers[e].height&&(d=this.layers[e].height),this._results.length=0,this._results.push({x:a,y:b,width:c,height:d,layer:e});for(var f=b;b+d>f;f++)for(var g=a;a+c>g;g++)this._results.push({x:g,y:f,index:this.layers[e].data[f][g]});return this._results},paste:function(a,b,c,d){if("undefined"==typeof a&&(a=0),"undefined"==typeof b&&(b=0),"undefined"==typeof d&&(d=this.currentLayer),c&&!(c.length<2)){for(var e=c[1].x-a,f=c[1].y-b,g=1;g1?this.debugMap[this.layers[this.currentLayer].data[c][d]]?b.push("background: "+this.debugMap[this.layers[this.currentLayer].data[c][d]]):b.push("background: #ffffff"):b.push("background: rgb(0, 0, 0)");a+="\n"}b[0]=a,console.log.apply(console,b)},destroy:function(){this.removeAllLayers(),this.game=null}},d.TilemapLayer=function(a,b,e,f,g,h,i,j){this.game=a,this.canvas=d.Canvas.create(f,g),this.context=this.canvas.getContext("2d"),this.baseTexture=new c.BaseTexture(this.canvas),this.texture=new c.Texture(this.baseTexture),this.textureFrame=new d.Frame(0,0,0,f,g,"tilemaplayer",a.rnd.uuid()),d.Sprite.call(this,this.game,b,e,this.texture,this.textureFrame),this.type=d.TILEMAPLAYER,this.fixedToCamera=!0,this.tileset=null,this.tileWidth=0,this.tileHeight=0,this.tileMargin=0,this.tileSpacing=0,this.widthInPixels=0,this.heightInPixels=0,this.renderWidth=f,this.renderHeight=g,this._ga=1,this._dx=0,this._dy=0,this._dw=0,this._dh=0,this._tx=0,this._ty=0,this._tw=0,this._th=0,this._tl=0,this._maxX=0,this._maxY=0,this._startX=0,this._startY=0,this._results=[],this._x=0,this._y=0,this._prevX=0,this._prevY=0,this.scrollFactorX=1,this.scrollFactorY=1,this.tilemap=null,this.layer=null,this.index=0,this.dirty=!0,(h instanceof d.Tileset||"string"==typeof h)&&this.updateTileset(h),i instanceof d.Tilemap&&this.updateMapData(i,j)},d.TilemapLayer.prototype=Object.create(d.Sprite.prototype),d.TilemapLayer.prototype=d.Utils.extend(!0,d.TilemapLayer.prototype,d.Sprite.prototype,c.Sprite.prototype),d.TilemapLayer.prototype.constructor=d.TilemapLayer,d.TilemapLayer.prototype.update=function(){this.scrollX=this.game.camera.x*this.scrollFactorX,this.scrollY=this.game.camera.y*this.scrollFactorY,this.render()},d.TilemapLayer.prototype.resizeWorld=function(){this.game.world.setBounds(0,0,this.widthInPixels,this.heightInPixels)},d.TilemapLayer.prototype.updateTileset=function(a){if(a instanceof d.Tileset)this.tileset=a;else{if("string"!=typeof a)return;this.tileset=this.game.cache.getTileset("tiles")}this.tileWidth=this.tileset.tileWidth,this.tileHeight=this.tileset.tileHeight,this.tileMargin=this.tileset.tileMargin,this.tileSpacing=this.tileset.tileSpacing,this.updateMax()},d.TilemapLayer.prototype.updateMapData=function(a,b){"undefined"==typeof b&&(b=0),a instanceof d.Tilemap&&(this.tilemap=a,this.layer=this.tilemap.layers[b],this.index=b,this.updateMax(),this.tilemap.dirty=!0)},d.TilemapLayer.prototype._fixX=function(a){if(1===this.scrollFactorX)return a;var b=a-this._x/this.scrollFactorX;return this._x+b},d.TilemapLayer.prototype._unfixX=function(a){if(1===this.scrollFactorX)return a;var b=a-this._x;return this._x/this.scrollFactorX+b},d.TilemapLayer.prototype._fixY=function(a){if(1===this.scrollFactorY)return a;var b=a-this._y/this.scrollFactorY;return this._y+b},d.TilemapLayer.prototype._unfixY=function(a){if(1===this.scrollFactorY)return a;var b=a-this._y;return this._y/this.scrollFactorY+b},d.TilemapLayer.prototype.getTileX=function(a){var b=this.tileWidth*this.scale.x;return this.game.math.snapToFloor(this._fixX(a),b)/b},d.TilemapLayer.prototype.getTileY=function(a){var b=this.tileHeight*this.scale.y;return this.game.math.snapToFloor(this._fixY(a),b)/b},d.TilemapLayer.prototype.getTileXY=function(a,b,c){return c.x=this.getTileX(a),c.y=this.getTileY(b),c},d.TilemapLayer.prototype.getTiles=function(a,b,c,d,e){if(null!==this.tilemap){"undefined"==typeof e&&(e=!1),0>a&&(a=0),0>b&&(b=0),a=this._fixX(a),b=this._fixY(b),c>this.widthInPixels&&(c=this.widthInPixels),d>this.heightInPixels&&(d=this.heightInPixels);var f=this.tileWidth*this.scale.x,g=this.tileHeight*this.scale.y;this._tx=this.game.math.snapToFloor(a,f)/f,this._ty=this.game.math.snapToFloor(b,g)/g,this._tw=(this.game.math.snapToCeil(c,f)+f)/f,this._th=(this.game.math.snapToCeil(d,g)+g)/g,this._results=[];for(var h=0,i=null,j=0,k=0,l=this._ty;lthis.layer.width&&(this._maxX=this.layer.width),this._maxY>this.layer.height&&(this._maxY=this.layer.height),this.widthInPixels=this.layer.width*this.tileWidth,this.heightInPixels=this.layer.height*this.tileHeight),this.dirty=!0},d.TilemapLayer.prototype.render=function(){if(this.tilemap&&this.tilemap.dirty&&(this.dirty=!0),this.dirty&&this.tileset&&this.tilemap&&this.visible){this._prevX=this._dx,this._prevY=this._dy,this._dx=-(this._x-this._startX*this.tileWidth),this._dy=-(this._y-this._startY*this.tileHeight),this._tx=this._dx,this._ty=this._dy,this.context.clearRect(0,0,this.canvas.width,this.canvas.height);for(var a=this._startY;a0?this.deltaX():-this.deltaX()},d.TilemapLayer.prototype.deltaAbsY=function(){return this.deltaY()>0?this.deltaY():-this.deltaY()},d.TilemapLayer.prototype.deltaX=function(){return this._dx-this._prevX},d.TilemapLayer.prototype.deltaY=function(){return this._dy-this._prevY},Object.defineProperty(d.TilemapLayer.prototype,"scrollX",{get:function(){return this._x},set:function(a){a!==this._x&&a>=0&&this.layer&&(this._x=a,this._x>this.widthInPixels-this.renderWidth&&(this._x=this.widthInPixels-this.renderWidth),this._startX=this.game.math.floor(this._x/this.tileWidth),this._startX<0&&(this._startX=0),this._startX+this._maxX>this.layer.width&&(this._startX=this.layer.width-this._maxX),this.dirty=!0)}}),Object.defineProperty(d.TilemapLayer.prototype,"scrollY",{get:function(){return this._y},set:function(a){a!==this._y&&a>=0&&this.layer&&(this._y=a,this._y>this.heightInPixels-this.renderHeight&&(this._y=this.heightInPixels-this.renderHeight),this._startY=this.game.math.floor(this._y/this.tileHeight),this._startY<0&&(this._startY=0),this._startY+this._maxY>this.layer.height&&(this._startY=this.layer.height-this._maxY),this.dirty=!0)}}),d.TilemapParser={tileset:function(a,b,c,e,f,g,h){var i=a.cache.getTilesetImage(b);if(null==i)return null;var j=i.width,k=i.height;0>=c&&(c=Math.floor(-j/Math.min(-1,c))),0>=e&&(e=Math.floor(-k/Math.min(-1,e)));var l=Math.round(j/c),m=Math.round(k/e),n=l*m;if(-1!==f&&(n=f),0===j||0===k||c>j||e>k||0===n)return console.warn("Phaser.TilemapParser.tileSet: width/height zero or width/height < given tileWidth/tileHeight"),null;for(var o=g,p=g,q=new d.Tileset(i,b,c,e,g,h),r=0;n>r;r++)q.addTile(new d.Tile(q,r,o,p,c,e)),o+=c+h,o===j&&(o=g,p+=e+h);return q},parse:function(a,b,c){return c===d.Tilemap.CSV?this.parseCSV(b):c===d.Tilemap.TILED_JSON?this.parseTiledJSON(b):void 0},parseCSV:function(a){a=a.trim();for(var b=[],c=a.split("\n"),d=c.length,e=0,f=0;fa)for(var g=a;b>=g;g++)this.tiles[g].setCollision(c,d,e,f)},setCollision:function(a,b,c,d,e){this.tiles[a]&&this.tiles[a].setCollision(b,c,d,e)}},Object.defineProperty(d.Tileset.prototype,"total",{get:function(){return this.tiles.length}}),c.CanvasRenderer.prototype.render=function(a){c.texturesToUpdate.length=0,c.texturesToDestroy.length=0,c.visibleCount++,a.updateTransform(),this.context.setTransform(1,0,0,1,0,0),this.context.clearRect(0,0,this.width,this.height),this.renderDisplayObject(a),c.Texture.frameUpdates.length>0&&(c.Texture.frameUpdates.length=0)},c.CanvasRenderer.prototype.renderDisplayObject=function(a){var b=a.last._iNext;a=a.first;do if(a.visible)if(a.renderable&&0!==a.alpha){if(a instanceof c.Sprite)a.texture.frame&&(this.context.globalAlpha=a.worldAlpha,a.texture.trimmed?this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2]+a.texture.trim.x,a.worldTransform[5]+a.texture.trim.y):this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2],a.worldTransform[5]),this.context.drawImage(a.texture.baseTexture.source,a.texture.frame.x,a.texture.frame.y,a.texture.frame.width,a.texture.frame.height,a.anchor.x*-a.texture.frame.width,a.anchor.y*-a.texture.frame.height,a.texture.frame.width,a.texture.frame.height));else if(a instanceof c.Strip)this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2],a.worldTransform[5]),this.renderStrip(a);else if(a instanceof c.TilingSprite)this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2],a.worldTransform[5]),this.renderTilingSprite(a);else if(a instanceof c.CustomRenderable)a.renderCanvas(this);else if(a instanceof c.Graphics)this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2],a.worldTransform[5]),c.CanvasGraphics.renderGraphics(a,this.context);else if(a instanceof c.FilterBlock)if(a.open){this.context.save();var d=a.mask.alpha,e=a.mask.worldTransform;this.context.setTransform(e[0],e[3],e[1],e[4],e[2],e[5]),a.mask.worldAlpha=.5,this.context.worldAlpha=0,c.CanvasGraphics.renderGraphicsMask(a.mask,this.context),this.context.clip(),a.mask.worldAlpha=d}else this.context.restore();a=a._iNext}else a=a._iNext;else a=a.last._iNext;while(a!=b)},c.WebGLBatch.prototype.update=function(){for(var a,b,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=0,s=this.head;s;){if(s.vcount===c.visibleCount){if(b=s.texture.frame.width,d=s.texture.frame.height,e=s.anchor.x,f=s.anchor.y,g=b*(1-e),h=b*-e,i=d*(1-f),j=d*-f,k=8*r,a=s.worldTransform,l=a[0],m=a[3],n=a[1],o=a[4],p=a[2],q=a[5],s.texture.trimmed&&(p+=s.texture.trim.x,q+=s.texture.trim.y),this.verticies[k+0]=l*h+n*j+p,this.verticies[k+1]=o*j+m*h+q,this.verticies[k+2]=l*g+n*j+p,this.verticies[k+3]=o*j+m*g+q,this.verticies[k+4]=l*g+n*i+p,this.verticies[k+5]=o*i+m*g+q,this.verticies[k+6]=l*h+n*i+p,this.verticies[k+7]=o*i+m*h+q,s.updateFrame||s.texture.updateFrame){this.dirtyUVS=!0;var t=s.texture,u=t.frame,v=t.baseTexture.width,w=t.baseTexture.height;this.uvs[k+0]=u.x/v,this.uvs[k+1]=u.y/w,this.uvs[k+2]=(u.x+u.width)/v,this.uvs[k+3]=u.y/w,this.uvs[k+4]=(u.x+u.width)/v,this.uvs[k+5]=(u.y+u.height)/w,this.uvs[k+6]=u.x/v,this.uvs[k+7]=(u.y+u.height)/w,s.updateFrame=!1}if(s.cacheAlpha!=s.worldAlpha){s.cacheAlpha=s.worldAlpha;var x=4*r;this.colors[x]=this.colors[x+1]=this.colors[x+2]=this.colors[x+3]=s.worldAlpha,this.dirtyColors=!0}}else k=8*r,this.verticies[k+0]=0,this.verticies[k+1]=0,this.verticies[k+2]=0,this.verticies[k+3]=0,this.verticies[k+4]=0,this.verticies[k+5]=0,this.verticies[k+6]=0,this.verticies[k+7]=0;r++,s=s.__next}},d}); \ No newline at end of file +/*! Phaser v1.1.4 | (c) 2013 Photon Storm Ltd. */ +!function(a,b){"function"==typeof define&&define.amd?define(b):"object"==typeof exports?module.exports=b():a.Phaser=b()}(this,function(){function a(){return b.Matrix="undefined"!=typeof Float32Array?Float32Array:Array,b.Matrix}var b=b||{},c=c||{VERSION:"1.1.4",DEV_VERSION:"1.1.4",GAMES:[],AUTO:0,CANVAS:1,WEBGL:2,HEADLESS:3,SPRITE:0,BUTTON:1,BULLET:2,GRAPHICS:3,TEXT:4,TILESPRITE:5,BITMAPTEXT:6,GROUP:7,RENDERTEXTURE:8,TILEMAP:9,TILEMAPLAYER:10,EMITTER:11,POLYGON:12,BITMAPDATA:13,CANVAS_FILTER:14,WEBGL_FILTER:15,NONE:0,LEFT:1,RIGHT:2,UP:3,DOWN:4,CANVAS_PX_ROUND:!1,CANVAS_CLEAR_RECT:!0};b.InteractionManager=function(){},c.Utils={shuffle:function(a){for(var b=a.length-1;b>0;b--){var c=Math.floor(Math.random()*(b+1)),d=a[b];a[b]=a[c],a[c]=d}return a},pad:function(a,b,c,d){if("undefined"==typeof b)var b=0;if("undefined"==typeof c)var c=" ";if("undefined"==typeof d)var d=3;var e=0;if(b+1>=a.length)switch(d){case 1:a=Array(b+1-a.length).join(c)+a;break;case 3:var f=Math.ceil((e=b-a.length)/2),g=e-f;a=Array(g+1).join(c)+a+Array(f+1).join(c);break;default:a+=Array(b+1-a.length).join(c)}return a},isPlainObject:function(a){if("object"!=typeof a||a.nodeType||a===a.window)return!1;try{if(a.constructor&&!hasOwn.call(a.constructor.prototype,"isPrototypeOf"))return!1}catch(b){return!1}return!0},extend:function(){var a,b,d,e,f,g,h=arguments[0]||{},i=1,j=arguments.length,k=!1;for("boolean"==typeof h&&(k=h,h=arguments[1]||{},i=2),j===i&&(h=this,--i);j>i;i++)if(null!=(a=arguments[i]))for(b in a)d=h[b],e=a[b],h!==e&&(k&&e&&(c.Utils.isPlainObject(e)||(f=Array.isArray(e)))?(f?(f=!1,g=d&&Array.isArray(d)?d:[]):g=d&&c.Utils.isPlainObject(d)?d:{},h[b]=c.Utils.extend(k,g,e)):void 0!==e&&(h[b]=e));return h}},b.hex2rgb=function(a){return[(255&a>>16)/255,(255&a>>8)/255,(255&a)/255]},"function"!=typeof Function.prototype.bind&&(Function.prototype.bind=function(){var a=Array.prototype.slice;return function(b){function c(){var f=e.concat(a.call(arguments));d.apply(this instanceof c?this:b,f)}var d=this,e=a.call(arguments,1);if("function"!=typeof d)throw new TypeError;return c.prototype=function f(a){return a&&(f.prototype=a),this instanceof f?void 0:new f}(d.prototype),c}}()),Array.isArray||(Array.isArray=function(a){return"[object Array]"==Object.prototype.toString.call(a)}),a(),b.mat3={},b.mat3.create=function(){var a=new b.Matrix(9);return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=1,a[5]=0,a[6]=0,a[7]=0,a[8]=1,a},b.mat3.identity=function(a){return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=1,a[5]=0,a[6]=0,a[7]=0,a[8]=1,a},b.mat4={},b.mat4.create=function(){var a=new b.Matrix(16);return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=1,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1,a},b.mat3.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],f=a[2],g=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],m=b[0],n=b[1],o=b[2],p=b[3],q=b[4],r=b[5],s=b[6],t=b[7],u=b[8];return c[0]=m*d+n*g+o*j,c[1]=m*e+n*h+o*k,c[2]=m*f+n*i+o*l,c[3]=p*d+q*g+r*j,c[4]=p*e+q*h+r*k,c[5]=p*f+q*i+r*l,c[6]=s*d+t*g+u*j,c[7]=s*e+t*h+u*k,c[8]=s*f+t*i+u*l,c},b.mat3.clone=function(a){var c=new b.Matrix(9);return c[0]=a[0],c[1]=a[1],c[2]=a[2],c[3]=a[3],c[4]=a[4],c[5]=a[5],c[6]=a[6],c[7]=a[7],c[8]=a[8],c},b.mat3.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[5];return a[1]=a[3],a[2]=a[6],a[3]=c,a[5]=a[7],a[6]=d,a[7]=e,a}return b[0]=a[0],b[1]=a[3],b[2]=a[6],b[3]=a[1],b[4]=a[4],b[5]=a[7],b[6]=a[2],b[7]=a[5],b[8]=a[8],b},b.mat3.toMat4=function(a,c){return c||(c=b.mat4.create()),c[15]=1,c[14]=0,c[13]=0,c[12]=0,c[11]=0,c[10]=a[8],c[9]=a[7],c[8]=a[6],c[7]=0,c[6]=a[5],c[5]=a[4],c[4]=a[3],c[3]=0,c[2]=a[2],c[1]=a[1],c[0]=a[0],c},b.mat4.create=function(){var a=new b.Matrix(16);return a[0]=1,a[1]=0,a[2]=0,a[3]=0,a[4]=0,a[5]=1,a[6]=0,a[7]=0,a[8]=0,a[9]=0,a[10]=1,a[11]=0,a[12]=0,a[13]=0,a[14]=0,a[15]=1,a},b.mat4.transpose=function(a,b){if(!b||a===b){var c=a[1],d=a[2],e=a[3],f=a[6],g=a[7],h=a[11];return a[1]=a[4],a[2]=a[8],a[3]=a[12],a[4]=c,a[6]=a[9],a[7]=a[13],a[8]=d,a[9]=f,a[11]=a[14],a[12]=e,a[13]=g,a[14]=h,a}return b[0]=a[0],b[1]=a[4],b[2]=a[8],b[3]=a[12],b[4]=a[1],b[5]=a[5],b[6]=a[9],b[7]=a[13],b[8]=a[2],b[9]=a[6],b[10]=a[10],b[11]=a[14],b[12]=a[3],b[13]=a[7],b[14]=a[11],b[15]=a[15],b},b.mat4.multiply=function(a,b,c){c||(c=a);var d=a[0],e=a[1],f=a[2],g=a[3],h=a[4],i=a[5],j=a[6],k=a[7],l=a[8],m=a[9],n=a[10],o=a[11],p=a[12],q=a[13],r=a[14],s=a[15],t=b[0],u=b[1],v=b[2],w=b[3];return c[0]=t*d+u*h+v*l+w*p,c[1]=t*e+u*i+v*m+w*q,c[2]=t*f+u*j+v*n+w*r,c[3]=t*g+u*k+v*o+w*s,t=b[4],u=b[5],v=b[6],w=b[7],c[4]=t*d+u*h+v*l+w*p,c[5]=t*e+u*i+v*m+w*q,c[6]=t*f+u*j+v*n+w*r,c[7]=t*g+u*k+v*o+w*s,t=b[8],u=b[9],v=b[10],w=b[11],c[8]=t*d+u*h+v*l+w*p,c[9]=t*e+u*i+v*m+w*q,c[10]=t*f+u*j+v*n+w*r,c[11]=t*g+u*k+v*o+w*s,t=b[12],u=b[13],v=b[14],w=b[15],c[12]=t*d+u*h+v*l+w*p,c[13]=t*e+u*i+v*m+w*q,c[14]=t*f+u*j+v*n+w*r,c[15]=t*g+u*k+v*o+w*s,c},b.Point=function(a,b){this.x=a||0,this.y=b||0},b.Point.prototype.clone=function(){return new b.Point(this.x,this.y)},b.Point.prototype.constructor=b.Point,b.Rectangle=function(a,b,c,d){this.x=a||0,this.y=b||0,this.width=c||0,this.height=d||0},b.Rectangle.prototype.clone=function(){return new b.Rectangle(this.x,this.y,this.width,this.height)},b.Rectangle.prototype.contains=function(a,b){if(this.width<=0||this.height<=0)return!1;var c=this.x;if(a>=c&&a<=c+this.width){var d=this.y;if(b>=d&&b<=d+this.height)return!0}return!1},b.Rectangle.prototype.constructor=b.Rectangle,b.Polygon=function(a){if(a instanceof Array||(a=Array.prototype.slice.call(arguments)),"number"==typeof a[0]){for(var c=[],d=0,e=a.length;e>d;d+=2)c.push(new b.Point(a[d],a[d+1]));a=c}this.points=a},b.Polygon.prototype.clone=function(){for(var a=[],c=0;cb!=i>b&&(h-f)*(b-g)/(i-g)+f>a;j&&(c=!c)}return c},b.Polygon.prototype.constructor=b.Polygon,b.DisplayObject=function(){this.last=this,this.first=this,this.position=new b.Point,this.scale=new b.Point(1,1),this.pivot=new b.Point(0,0),this.rotation=0,this.alpha=1,this.visible=!0,this.hitArea=null,this.buttonMode=!1,this.renderable=!1,this.parent=null,this.stage=null,this.worldAlpha=1,this._interactive=!1,this.defaultCursor="pointer",this.worldTransform=b.mat3.create(),this.localTransform=b.mat3.create(),this.color=[],this.dynamic=!0,this._sr=0,this._cr=1,this.filterArea=new b.Rectangle(0,0,1,1)},b.DisplayObject.prototype.constructor=b.DisplayObject,b.DisplayObject.prototype.setInteractive=function(a){this.interactive=a},Object.defineProperty(b.DisplayObject.prototype,"interactive",{get:function(){return this._interactive},set:function(a){this._interactive=a,this.stage&&(this.stage.dirty=!0)}}),Object.defineProperty(b.DisplayObject.prototype,"mask",{get:function(){return this._mask},set:function(a){a?this._mask?(a.start=this._mask.start,a.end=this._mask.end):(this.addFilter(a),a.renderable=!1):(this.removeFilter(this._mask),this._mask.renderable=!0),this._mask=a}}),Object.defineProperty(b.DisplayObject.prototype,"filters",{get:function(){return this._filters},set:function(a){if(a){this._filters&&this.removeFilter(this._filters),this.addFilter(a);for(var b=[],c=0;c=0&&b<=this.children.length))throw new Error(a+" The index "+b+" supplied is out of bounds "+this.children.length);if(void 0!==a.parent&&a.parent.removeChild(a),a.parent=this,this.stage){var c=a;do c.interactive&&(this.stage.dirty=!0),c.stage=this.stage,c=c._iNext;while(c)}var d,e,f=a.first,g=a.last;if(b===this.children.length){e=this.last;for(var h=this,i=this.last;h;)h.last===i&&(h.last=a.last),h=h.parent}else e=0===b?this:this.children[b-1].last;d=e._iNext,d&&(d._iPrev=g,g._iNext=d),f._iPrev=e,e._iNext=f,this.children.splice(b,0,a),this.__renderGroup&&(a.__renderGroup&&a.__renderGroup.removeDisplayObjectAndChildren(a),this.__renderGroup.addDisplayObjectAndChildren(a))},b.DisplayObjectContainer.prototype.swapChildren=function(a,b){if(a!==b){var c=this.children.indexOf(a),d=this.children.indexOf(b);if(0>c||0>d)throw new Error("swapChildren: Both the supplied DisplayObjects must be a child of the caller.");this.removeChild(a),this.removeChild(b),d>c?(this.addChildAt(b,c),this.addChildAt(a,d)):(this.addChildAt(a,d),this.addChildAt(b,c))}},b.DisplayObjectContainer.prototype.getChildAt=function(a){if(a>=0&&aa;a++)this.children[a].updateTransform()}},b.blendModes={},b.blendModes.NORMAL=0,b.blendModes.SCREEN=1,b.Sprite=function(a){b.DisplayObjectContainer.call(this),this.anchor=new b.Point,this.texture=a,this.blendMode=b.blendModes.NORMAL,this._width=0,this._height=0,a.baseTexture.hasLoaded?this.updateFrame=!0:(this.onTextureUpdateBind=this.onTextureUpdate.bind(this),this.texture.addEventListener("update",this.onTextureUpdateBind)),this.renderable=!0},b.Sprite.prototype=Object.create(b.DisplayObjectContainer.prototype),b.Sprite.prototype.constructor=b.Sprite,Object.defineProperty(b.Sprite.prototype,"width",{get:function(){return this.scale.x*this.texture.frame.width},set:function(a){this.scale.x=a/this.texture.frame.width,this._width=a}}),Object.defineProperty(b.Sprite.prototype,"height",{get:function(){return this.scale.y*this.texture.frame.height},set:function(a){this.scale.y=a/this.texture.frame.height,this._height=a}}),b.Sprite.prototype.setTexture=function(a){this.texture.baseTexture!==a.baseTexture?(this.textureChange=!0,this.texture=a,this.__renderGroup&&this.__renderGroup.updateTexture(this)):this.texture=a,this.updateFrame=!0},b.Sprite.prototype.onTextureUpdate=function(){this._width&&(this.scale.x=this._width/this.texture.frame.width),this._height&&(this.scale.y=this._height/this.texture.frame.height),this.updateFrame=!0},b.Sprite.fromFrame=function(a){var c=b.TextureCache[a];if(!c)throw new Error('The frameId "'+a+'" does not exist in the texture cache'+this);return new b.Sprite(c)},b.Sprite.fromImage=function(a){var c=b.Texture.fromImage(a);return new b.Sprite(c)},b.Stage=function(a){b.DisplayObjectContainer.call(this),this.worldTransform=b.mat3.create(),this.interactive=!0,this.interactionManager=new b.InteractionManager(this),this.dirty=!0,this.__childrenAdded=[],this.__childrenRemoved=[],this.stage=this,this.stage.hitArea=new b.Rectangle(0,0,1e5,1e5),this.setBackgroundColor(a),this.worldVisible=!0},b.Stage.prototype=Object.create(b.DisplayObjectContainer.prototype),b.Stage.prototype.constructor=b.Stage,b.Stage.prototype.setInteractionDelegate=function(a){this.interactionManager.setTargetDomElement(a)},b.Stage.prototype.updateTransform=function(){this.worldAlpha=1,this.vcount=b.visibleCount;for(var a=0,c=this.children.length;c>a;a++)this.children[a].updateTransform();this.dirty&&(this.dirty=!1,this.interactionManager.dirty=!0),this.interactive&&this.interactionManager.update()},b.Stage.prototype.setBackgroundColor=function(a){this.backgroundColor=a||0,this.backgroundColorSplit=b.hex2rgb(this.backgroundColor);var c=this.backgroundColor.toString(16);c="000000".substr(0,6-c.length)+c,this.backgroundColorString="#"+c},b.Stage.prototype.getMousePosition=function(){return this.interactionManager.mouse.global},b.CustomRenderable=function(){b.DisplayObject.call(this),this.renderable=!0},b.CustomRenderable.prototype=Object.create(b.DisplayObject.prototype),b.CustomRenderable.prototype.constructor=b.CustomRenderable,b.CustomRenderable.prototype.renderCanvas=function(){},b.CustomRenderable.prototype.initWebGL=function(){},b.CustomRenderable.prototype.renderWebGL=function(){},b.Strip=function(a,c,d){b.DisplayObjectContainer.call(this),this.texture=a,this.blendMode=b.blendModes.NORMAL;try{this.uvs=new Float32Array([0,1,1,1,1,0,0,1]),this.verticies=new Float32Array([0,0,0,0,0,0,0,0,0]),this.colors=new Float32Array([1,1,1,1]),this.indices=new Uint16Array([0,1,2,3])}catch(e){this.uvs=[0,1,1,1,1,0,0,1],this.verticies=[0,0,0,0,0,0,0,0,0],this.colors=[1,1,1,1],this.indices=[0,1,2,3]}this.width=c,this.height=d,a.baseTexture.hasLoaded?(this.width=this.texture.frame.width,this.height=this.texture.frame.height,this.updateFrame=!0):(this.onTextureUpdateBind=this.onTextureUpdate.bind(this),this.texture.addEventListener("update",this.onTextureUpdateBind)),this.renderable=!0},b.Strip.prototype=Object.create(b.DisplayObjectContainer.prototype),b.Strip.prototype.constructor=b.Strip,b.Strip.prototype.setTexture=function(a){this.texture=a,this.width=a.frame.width,this.height=a.frame.height,this.updateFrame=!0},b.Strip.prototype.onTextureUpdate=function(){this.updateFrame=!0},b.Rope=function(a,c){b.Strip.call(this,a),this.points=c;try{this.verticies=new Float32Array(4*c.length),this.uvs=new Float32Array(4*c.length),this.colors=new Float32Array(2*c.length),this.indices=new Uint16Array(2*c.length)}catch(d){this.verticies=new Array(4*c.length),this.uvs=new Array(4*c.length),this.colors=new Array(2*c.length),this.indices=new Array(2*c.length)}this.refresh()},b.Rope.prototype=Object.create(b.Strip.prototype),b.Rope.prototype.constructor=b.Rope,b.Rope.prototype.refresh=function(){var a=this.points;if(!(a.length<1)){var b=this.uvs,c=a[0],d=this.indices,e=this.colors;this.count-=.2,b[0]=0,b[1]=1,b[2]=0,b[3]=1,e[0]=1,e[1]=1,d[0]=0,d[1]=1;for(var f,g,h,i=a.length,j=1;i>j;j++)f=a[j],g=4*j,h=j/(i-1),j%2?(b[g]=h,b[g+1]=0,b[g+2]=h,b[g+3]=1):(b[g]=h,b[g+1]=0,b[g+2]=h,b[g+3]=1),g=2*j,e[g]=1,e[g+1]=1,g=2*j,d[g]=g,d[g+1]=g+1,c=f}},b.Rope.prototype.updateTransform=function(){var a=this.points;if(!(a.length<1)){var c,d=a[0],e={x:0,y:0};this.count-=.2;var f=this.verticies;f[0]=d.x+e.x,f[1]=d.y+e.y,f[2]=d.x-e.x,f[3]=d.y-e.y;for(var g,h,i,j,k,l=a.length,m=1;l>m;m++)g=a[m],h=4*m,c=m1&&(i=1),j=Math.sqrt(e.x*e.x+e.y*e.y),k=this.texture.height/2,e.x/=j,e.y/=j,e.x*=k,e.y*=k,f[h]=g.x+e.x,f[h+1]=g.y+e.y,f[h+2]=g.x-e.x,f[h+3]=g.y-e.y,d=g;b.DisplayObjectContainer.prototype.updateTransform.call(this)}},b.Rope.prototype.setTexture=function(a){this.texture=a,this.updateFrame=!0},b.TilingSprite=function(a,c,d){b.DisplayObjectContainer.call(this),this.texture=a,this.width=c,this.height=d,this.tileScale=new b.Point(1,1),this.tilePosition=new b.Point(0,0),this.renderable=!0,this.blendMode=b.blendModes.NORMAL},b.TilingSprite.prototype=Object.create(b.DisplayObjectContainer.prototype),b.TilingSprite.prototype.constructor=b.TilingSprite,b.TilingSprite.prototype.setTexture=function(a){this.texture=a,this.updateFrame=!0},b.TilingSprite.prototype.onTextureUpdate=function(){this.updateFrame=!0},b.AbstractFilter=function(a,b){this.passes=[this],this.dirty=!0,this.padding=0,this.uniforms=b||{},this.fragmentSrc=a||[]},b.FilterBlock=function(){this.visible=!0,this.renderable=!0},b.Graphics=function(){b.DisplayObjectContainer.call(this),this.renderable=!0,this.fillAlpha=1,this.lineWidth=0,this.lineColor="black",this.graphicsData=[],this.currentPath={points:[]}},b.Graphics.prototype=Object.create(b.DisplayObjectContainer.prototype),b.Graphics.prototype.constructor=b.Graphics,b.Graphics.prototype.lineStyle=function(a,c,d){this.currentPath.points.length||this.graphicsData.pop(),this.lineWidth=a||0,this.lineColor=c||0,this.lineAlpha=arguments.length<3?1:d,this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[],type:b.Graphics.POLY},this.graphicsData.push(this.currentPath)},b.Graphics.prototype.moveTo=function(a,c){this.currentPath.points.length||this.graphicsData.pop(),this.currentPath=this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[],type:b.Graphics.POLY},this.currentPath.points.push(a,c),this.graphicsData.push(this.currentPath)},b.Graphics.prototype.lineTo=function(a,b){this.currentPath.points.push(a,b),this.dirty=!0},b.Graphics.prototype.beginFill=function(a,b){this.filling=!0,this.fillColor=a||0,this.fillAlpha=arguments.length<2?1:b},b.Graphics.prototype.endFill=function(){this.filling=!1,this.fillColor=null,this.fillAlpha=1},b.Graphics.prototype.drawRect=function(a,c,d,e){this.currentPath.points.length||this.graphicsData.pop(),this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[a,c,d,e],type:b.Graphics.RECT},this.graphicsData.push(this.currentPath),this.dirty=!0},b.Graphics.prototype.drawCircle=function(a,c,d){this.currentPath.points.length||this.graphicsData.pop(),this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[a,c,d,d],type:b.Graphics.CIRC},this.graphicsData.push(this.currentPath),this.dirty=!0},b.Graphics.prototype.drawEllipse=function(a,c,d,e){this.currentPath.points.length||this.graphicsData.pop(),this.currentPath={lineWidth:this.lineWidth,lineColor:this.lineColor,lineAlpha:this.lineAlpha,fillColor:this.fillColor,fillAlpha:this.fillAlpha,fill:this.filling,points:[a,c,d,e],type:b.Graphics.ELIP},this.graphicsData.push(this.currentPath),this.dirty=!0},b.Graphics.prototype.clear=function(){this.lineWidth=0,this.filling=!1,this.dirty=!0,this.clearDirty=!0,this.graphicsData=[],this.bounds=null},b.Graphics.prototype.updateFilterBounds=function(){if(!this.bounds){for(var a,c,d,e=1/0,f=-1/0,g=1/0,h=-1/0,i=0;ic?c:e,f=c+m>f?c+m:f,g=g>d?c:g,h=d+n>h?d+n:h}else if(k===b.Graphics.CIRC||k===b.Graphics.ELIP){c=a.x,d=a.y;var o=a.radius+l/2;e=e>c-o?c-o:e,f=c+o>f?c+o:f,g=g>d-o?d-o:g,h=d+o>h?d+o:h}else for(var p=0;pc-l?c-l:e,f=c+l>f?c+l:f,g=g>d-l?d-l:g,h=d+l>h?d+l:h}this.bounds=new b.Rectangle(e,g,f-e,h-g)}},b.Graphics.POLY=0,b.Graphics.RECT=1,b.Graphics.CIRC=2,b.Graphics.ELIP=3,b.CanvasGraphics=function(){},b.CanvasGraphics.renderGraphics=function(a,c){for(var d=a.worldAlpha,e="",f=0;f1&&(d=1,window.console.log("Pixi.js warning: masks in canvas can only mask using the first path in the graphics object"));for(var e=0;1>e;e++){var f=a.graphicsData[e],g=f.points;if(f.type===b.Graphics.POLY){c.beginPath(),c.moveTo(g[0],g[1]);for(var h=1;h0&&(b.Texture.frameUpdates=[])},b.CanvasRenderer.prototype.resize=function(a,b){this.width=a,this.height=b,this.view.width=a,this.view.height=b},b.CanvasRenderer.prototype.renderDisplayObject=function(a){var c,d=this.context;d.globalCompositeOperation="source-over";var e=a.last._iNext;a=a.first;do if(c=a.worldTransform,a.visible)if(a.renderable){if(a instanceof b.Sprite){var f=a.texture.frame;f&&f.width&&f.height&&a.texture.baseTexture.source&&(d.globalAlpha=a.worldAlpha,d.setTransform(c[0],c[3],c[1],c[4],c[2],c[5]),this.smoothProperty&&this.scaleMode!==a.texture.baseTexture.scaleMode&&(this.scaleMode=a.texture.baseTexture.scaleMode,d[this.smoothProperty]=this.scaleMode===b.BaseTexture.SCALE_MODE.LINEAR),d.drawImage(a.texture.baseTexture.source,f.x,f.y,f.width,f.height,a.anchor.x*-f.width,a.anchor.y*-f.height,f.width,f.height))}else if(a instanceof b.Strip)d.setTransform(c[0],c[3],c[1],c[4],c[2],c[5]),this.renderStrip(a);else if(a instanceof b.TilingSprite)d.setTransform(c[0],c[3],c[1],c[4],c[2],c[5]),this.renderTilingSprite(a);else if(a instanceof b.CustomRenderable)d.setTransform(c[0],c[3],c[1],c[4],c[2],c[5]),a.renderCanvas(this);else if(a instanceof b.Graphics)d.setTransform(c[0],c[3],c[1],c[4],c[2],c[5]),b.CanvasGraphics.renderGraphics(a,d);else if(a instanceof b.FilterBlock&&a.data instanceof b.Graphics){var g=a.data;if(a.open){d.save();var h=g.alpha,i=g.worldTransform;d.setTransform(i[0],i[3],i[1],i[4],i[2],i[5]),g.worldAlpha=.5,d.worldAlpha=0,b.CanvasGraphics.renderGraphicsMask(g,d),d.clip(),g.worldAlpha=h}else d.restore()}a=a._iNext}else a=a._iNext;else a=a.last._iNext;while(a!==e)},b.CanvasRenderer.prototype.renderStripFlat=function(a){var b=this.context,c=a.verticies,d=c.length/2;this.count++,b.beginPath();for(var e=1;d-2>e;e++){var f=2*e,g=c[f],h=c[f+2],i=c[f+4],j=c[f+1],k=c[f+3],l=c[f+5];b.moveTo(g,j),b.lineTo(h,k),b.lineTo(i,l)}b.fillStyle="#FF0000",b.fill(),b.closePath()},b.CanvasRenderer.prototype.renderTilingSprite=function(a){var b=this.context;b.globalAlpha=a.worldAlpha,a.__tilePattern||(a.__tilePattern=b.createPattern(a.texture.baseTexture.source,"repeat")),b.beginPath();var c=a.tilePosition,d=a.tileScale;b.scale(d.x,d.y),b.translate(c.x,c.y),b.fillStyle=a.__tilePattern,b.fillRect(-c.x,-c.y,a.width/d.x,a.height/d.y),b.scale(1/d.x,1/d.y),b.translate(-c.x,-c.y),b.closePath()},b.CanvasRenderer.prototype.renderStrip=function(a){var b=this.context,c=a.verticies,d=a.uvs,e=c.length/2;this.count++;for(var f=1;e-2>f;f++){var g=2*f,h=c[g],i=c[g+2],j=c[g+4],k=c[g+1],l=c[g+3],m=c[g+5],n=d[g]*a.texture.width,o=d[g+2]*a.texture.width,p=d[g+4]*a.texture.width,q=d[g+1]*a.texture.height,r=d[g+3]*a.texture.height,s=d[g+5]*a.texture.height;b.save(),b.beginPath(),b.moveTo(h,k),b.lineTo(i,l),b.lineTo(j,m),b.closePath(),b.clip();var t=n*r+q*p+o*s-r*p-q*o-n*s,u=h*r+q*j+i*s-r*j-q*i-h*s,v=n*i+h*p+o*j-i*p-h*o-n*j,w=n*r*j+q*i*p+h*o*s-h*r*p-q*o*j-n*i*s,x=k*r+q*m+l*s-r*m-q*l-k*s,y=n*l+k*p+o*m-l*p-k*o-n*m,z=n*r*m+q*l*p+k*o*s-k*r*p-q*o*m-n*l*s;b.transform(u/t,x/t,v/t,y/t,w/t,z/t),b.drawImage(a.texture.baseTexture.source,0,0),b.restore()}},b.PixiShader=function(){this.program=null,this.fragmentSrc=["precision lowp float;","varying vec2 vTextureCoord;","varying float vColor;","uniform sampler2D uSampler;","void main(void) {"," gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;","}"],this.textureCount=0},b.PixiShader.prototype.init=function(){var a=b.compileProgram(this.vertexSrc||b.PixiShader.defaultVertexSrc,this.fragmentSrc),c=b.gl;c.useProgram(a),this.uSampler=c.getUniformLocation(a,"uSampler"),this.projectionVector=c.getUniformLocation(a,"projectionVector"),this.offsetVector=c.getUniformLocation(a,"offsetVector"),this.dimensions=c.getUniformLocation(a,"dimensions"),this.aVertexPosition=c.getAttribLocation(a,"aVertexPosition"),this.colorAttribute=c.getAttribLocation(a,"aColor"),this.aTextureCoord=c.getAttribLocation(a,"aTextureCoord");for(var d in this.uniforms)this.uniforms[d].uniformLocation=c.getUniformLocation(a,d);this.initUniforms(),this.program=a},b.PixiShader.prototype.initUniforms=function(){this.textureCount=1;var a;for(var c in this.uniforms){a=this.uniforms[c];var d=a.type;"sampler2D"===d?(a._init=!1,null!==a.value&&this.initSampler2D(a)):"mat2"===d||"mat3"===d||"mat4"===d?(a.glMatrix=!0,a.glValueLength=1,"mat2"===d?a.glFunc=b.gl.uniformMatrix2fv:"mat3"===d?a.glFunc=b.gl.uniformMatrix3fv:"mat4"===d&&(a.glFunc=b.gl.uniformMatrix4fv)):(a.glFunc=b.gl["uniform"+d],a.glValueLength="2f"===d||"2i"===d?2:"3f"===d||"3i"===d?3:"4f"===d||"4i"===d?4:1)}},b.PixiShader.prototype.initSampler2D=function(a){if(a.value&&a.value.baseTexture&&a.value.baseTexture.hasLoaded){if(b.gl.activeTexture(b.gl["TEXTURE"+this.textureCount]),b.gl.bindTexture(b.gl.TEXTURE_2D,a.value.baseTexture._glTexture),a.textureData){var c=a.textureData,d=c.magFilter?c.magFilter:b.gl.LINEAR,e=c.minFilter?c.minFilter:b.gl.LINEAR,f=c.wrapS?c.wrapS:b.gl.CLAMP_TO_EDGE,g=c.wrapT?c.wrapT:b.gl.CLAMP_TO_EDGE,h=c.luminance?b.gl.LUMINANCE:b.gl.RGBA;if(c.repeat&&(f=b.gl.REPEAT,g=b.gl.REPEAT),b.gl.pixelStorei(b.gl.UNPACK_FLIP_Y_WEBGL,!1),c.width){var i=c.width?c.width:512,j=c.height?c.height:2,k=c.border?c.border:0;b.gl.texImage2D(b.gl.TEXTURE_2D,0,h,i,j,k,h,b.gl.UNSIGNED_BYTE,null)}else b.gl.texImage2D(b.gl.TEXTURE_2D,0,h,b.gl.RGBA,b.gl.UNSIGNED_BYTE,a.value.baseTexture.source);b.gl.texParameteri(b.gl.TEXTURE_2D,b.gl.TEXTURE_MAG_FILTER,d),b.gl.texParameteri(b.gl.TEXTURE_2D,b.gl.TEXTURE_MIN_FILTER,e),b.gl.texParameteri(b.gl.TEXTURE_2D,b.gl.TEXTURE_WRAP_S,f),b.gl.texParameteri(b.gl.TEXTURE_2D,b.gl.TEXTURE_WRAP_T,g)}b.gl.uniform1i(a.uniformLocation,this.textureCount),a._init=!0,this.textureCount++}},b.PixiShader.prototype.syncUniforms=function(){this.textureCount=1;var a;for(var c in this.uniforms)a=this.uniforms[c],1===a.glValueLength?a.glMatrix===!0?a.glFunc.call(b.gl,a.uniformLocation,a.transpose,a.value):a.glFunc.call(b.gl,a.uniformLocation,a.value):2===a.glValueLength?a.glFunc.call(b.gl,a.uniformLocation,a.value.x,a.value.y):3===a.glValueLength?a.glFunc.call(b.gl,a.uniformLocation,a.value.x,a.value.y,a.value.z):4===a.glValueLength?a.glFunc.call(b.gl,a.uniformLocation,a.value.x,a.value.y,a.value.z,a.value.w):"sampler2D"===a.type&&(a._init?(b.gl.activeTexture(b.gl["TEXTURE"+this.textureCount]),b.gl.bindTexture(b.gl.TEXTURE_2D,a.value.baseTexture._glTexture),b.gl.uniform1i(a.uniformLocation,this.textureCount),this.textureCount++):this.initSampler2D(a))},b.PixiShader.defaultVertexSrc=["attribute vec2 aVertexPosition;","attribute vec2 aTextureCoord;","attribute float aColor;","uniform vec2 projectionVector;","uniform vec2 offsetVector;","varying vec2 vTextureCoord;","varying float vColor;","const vec2 center = vec2(-1.0, 1.0);","void main(void) {"," gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);"," vTextureCoord = aTextureCoord;"," vColor = aColor;","}"],b.PrimitiveShader=function(){this.program=null,this.fragmentSrc=["precision mediump float;","varying vec4 vColor;","void main(void) {"," gl_FragColor = vColor;","}"],this.vertexSrc=["attribute vec2 aVertexPosition;","attribute vec4 aColor;","uniform mat3 translationMatrix;","uniform vec2 projectionVector;","uniform vec2 offsetVector;","uniform float alpha;","varying vec4 vColor;","void main(void) {"," vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);"," v -= offsetVector.xyx;"," gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);"," vColor = aColor * alpha;","}"] +},b.PrimitiveShader.prototype.init=function(){var a=b.compileProgram(this.vertexSrc,this.fragmentSrc),c=b.gl;c.useProgram(a),this.projectionVector=c.getUniformLocation(a,"projectionVector"),this.offsetVector=c.getUniformLocation(a,"offsetVector"),this.aVertexPosition=c.getAttribLocation(a,"aVertexPosition"),this.colorAttribute=c.getAttribLocation(a,"aColor"),this.translationMatrix=c.getUniformLocation(a,"translationMatrix"),this.alpha=c.getUniformLocation(a,"alpha"),this.program=a},b.StripShader=function(){this.program=null,this.fragmentSrc=["precision mediump float;","varying vec2 vTextureCoord;","varying float vColor;","uniform float alpha;","uniform sampler2D uSampler;","void main(void) {"," gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));"," gl_FragColor = gl_FragColor * alpha;","}"],this.vertexSrc=["attribute vec2 aVertexPosition;","attribute vec2 aTextureCoord;","attribute float aColor;","uniform mat3 translationMatrix;","uniform vec2 projectionVector;","uniform vec2 offsetVector;","varying vec2 vTextureCoord;","varying float vColor;","void main(void) {"," vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);"," v -= offsetVector.xyx;"," gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);"," vTextureCoord = aTextureCoord;"," vColor = aColor;","}"]},b.StripShader.prototype.init=function(){var a=b.compileProgram(this.vertexSrc,this.fragmentSrc),c=b.gl;c.useProgram(a),this.uSampler=c.getUniformLocation(a,"uSampler"),this.projectionVector=c.getUniformLocation(a,"projectionVector"),this.offsetVector=c.getUniformLocation(a,"offsetVector"),this.colorAttribute=c.getAttribLocation(a,"aColor"),this.aVertexPosition=c.getAttribLocation(a,"aVertexPosition"),this.aTextureCoord=c.getAttribLocation(a,"aTextureCoord"),this.translationMatrix=c.getUniformLocation(a,"translationMatrix"),this.alpha=c.getUniformLocation(a,"alpha"),this.program=a},b._batchs=[],b._getBatch=function(a){return 0===b._batchs.length?new b.WebGLBatch(a):b._batchs.pop()},b._returnBatch=function(a){a.clean(),b._batchs.push(a)},b._restoreBatchs=function(a){for(var c=0;cc;c++){var d=6*c,e=4*c;this.indices[d+0]=e+0,this.indices[d+1]=e+1,this.indices[d+2]=e+2,this.indices[d+3]=e+0,this.indices[d+4]=e+2,this.indices[d+5]=e+3}a.bindBuffer(a.ELEMENT_ARRAY_BUFFER,this.indexBuffer),a.bufferData(a.ELEMENT_ARRAY_BUFFER,this.indices,a.STATIC_DRAW)},b.WebGLBatch.prototype.refresh=function(){this.dynamicSizethis.width&&(f.width=this.width),f.y<0&&(f.y=0),f.height>this.height&&(f.height=this.height),c.bindFramebuffer(c.FRAMEBUFFER,e.frameBuffer),c.viewport(0,0,f.width,f.height),b.projection.x=f.width/2,b.projection.y=-f.height/2,b.offset.x=-f.x,b.offset.y=-f.y,c.uniform2f(b.defaultShader.projectionVector,f.width/2,-f.height/2),c.uniform2f(b.defaultShader.offsetVector,-f.x,-f.y),c.colorMask(!0,!0,!0,!0),c.clearColor(0,0,0,0),c.clear(c.COLOR_BUFFER_BIT),a._glFilterTexture=e},b.WebGLFilterManager.prototype.popFilter=function(){var a=b.gl,c=this.filterStack.pop(),d=c.target.filterArea,e=c._glFilterTexture;if(c.filterPasses.length>1){a.viewport(0,0,d.width,d.height),a.bindBuffer(a.ARRAY_BUFFER,this.vertexBuffer),this.vertexArray[0]=0,this.vertexArray[1]=d.height,this.vertexArray[2]=d.width,this.vertexArray[3]=d.height,this.vertexArray[4]=0,this.vertexArray[5]=0,this.vertexArray[6]=d.width,this.vertexArray[7]=0,a.bufferSubData(a.ARRAY_BUFFER,0,this.vertexArray),a.bindBuffer(a.ARRAY_BUFFER,this.uvBuffer),this.uvArray[2]=d.width/this.width,this.uvArray[5]=d.height/this.height,this.uvArray[6]=d.width/this.width,this.uvArray[7]=d.height/this.height,a.bufferSubData(a.ARRAY_BUFFER,0,this.uvArray);var f=e,g=this.texturePool.pop();g||(g=new b.FilterTexture(this.width,this.height)),a.bindFramebuffer(a.FRAMEBUFFER,g.frameBuffer),a.clear(a.COLOR_BUFFER_BIT),a.disable(a.BLEND);for(var h=0;hs?s:E,E=E>t?t:E,E=E>u?u:E,E=E>v?v:E,F=F>w?w:F,F=F>x?x:F,F=F>y?y:F,F=F>z?z:F,C=s>C?s:C,C=t>C?t:C,C=u>C?u:C,C=v>C?v:C,D=w>D?w:D,D=x>D?x:D,D=y>D?y:D,D=z>D?z:D),l=!1,A=A._iNext}while(A!==B);a.filterArea.x=E,a.filterArea.y=F,a.filterArea.width=C-E,a.filterArea.height=D-F},b.FilterTexture=function(a,c){var d=b.gl;this.frameBuffer=d.createFramebuffer(),this.texture=d.createTexture(),d.bindTexture(d.TEXTURE_2D,this.texture),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_MAG_FILTER,d.LINEAR),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_MIN_FILTER,d.LINEAR),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_WRAP_S,d.CLAMP_TO_EDGE),d.texParameteri(d.TEXTURE_2D,d.TEXTURE_WRAP_T,d.CLAMP_TO_EDGE),d.bindFramebuffer(d.FRAMEBUFFER,this.framebuffer),d.bindFramebuffer(d.FRAMEBUFFER,this.frameBuffer),d.framebufferTexture2D(d.FRAMEBUFFER,d.COLOR_ATTACHMENT0,d.TEXTURE_2D,this.texture,0),this.resize(a,c)},b.FilterTexture.prototype.resize=function(a,c){if(this.width!==a||this.height!==c){this.width=a,this.height=c;var d=b.gl;d.bindTexture(d.TEXTURE_2D,this.texture),d.texImage2D(d.TEXTURE_2D,0,d.RGBA,a,c,0,d.RGBA,d.UNSIGNED_BYTE,null)}},b.WebGLGraphics=function(){},b.WebGLGraphics.renderGraphics=function(a,c){var d=b.gl;a._webGL||(a._webGL={points:[],indices:[],lastIndex:0,buffer:d.createBuffer(),indexBuffer:d.createBuffer()}),a.dirty&&(a.dirty=!1,a.clearDirty&&(a.clearDirty=!1,a._webGL.lastIndex=0,a._webGL.points=[],a._webGL.indices=[]),b.WebGLGraphics.updateGraphics(a)),b.activatePrimitiveShader();var e=b.mat3.clone(a.worldTransform);b.mat3.transpose(e),d.blendFunc(d.ONE,d.ONE_MINUS_SRC_ALPHA),d.uniformMatrix3fv(b.primitiveShader.translationMatrix,!1,e),d.uniform2f(b.primitiveShader.projectionVector,c.x,-c.y),d.uniform2f(b.primitiveShader.offsetVector,-b.offset.x,-b.offset.y),d.uniform1f(b.primitiveShader.alpha,a.worldAlpha),d.bindBuffer(d.ARRAY_BUFFER,a._webGL.buffer),d.vertexAttribPointer(b.primitiveShader.aVertexPosition,2,d.FLOAT,!1,24,0),d.vertexAttribPointer(b.primitiveShader.colorAttribute,4,d.FLOAT,!1,24,8),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,a._webGL.indexBuffer),d.drawElements(d.TRIANGLE_STRIP,a._webGL.indices.length,d.UNSIGNED_SHORT,0),b.deactivatePrimitiveShader()},b.WebGLGraphics.updateGraphics=function(a){for(var c=a._webGL.lastIndex;c3&&b.WebGLGraphics.buildPoly(d,a._webGL),d.lineWidth>0&&b.WebGLGraphics.buildLine(d,a._webGL)):d.type===b.Graphics.RECT?b.WebGLGraphics.buildRectangle(d,a._webGL):(d.type===b.Graphics.CIRC||d.type===b.Graphics.ELIP)&&b.WebGLGraphics.buildCircle(d,a._webGL)}a._webGL.lastIndex=a.graphicsData.length;var e=b.gl;a._webGL.glPoints=new Float32Array(a._webGL.points),e.bindBuffer(e.ARRAY_BUFFER,a._webGL.buffer),e.bufferData(e.ARRAY_BUFFER,a._webGL.glPoints,e.STATIC_DRAW),a._webGL.glIndicies=new Uint16Array(a._webGL.indices),e.bindBuffer(e.ELEMENT_ARRAY_BUFFER,a._webGL.indexBuffer),e.bufferData(e.ELEMENT_ARRAY_BUFFER,a._webGL.glIndicies,e.STATIC_DRAW)},b.WebGLGraphics.buildRectangle=function(a,c){var d=a.points,e=d[0],f=d[1],g=d[2],h=d[3];if(a.fill){var i=b.hex2rgb(a.fillColor),j=a.fillAlpha,k=i[0]*j,l=i[1]*j,m=i[2]*j,n=c.points,o=c.indices,p=n.length/6;n.push(e,f),n.push(k,l,m,j),n.push(e+g,f),n.push(k,l,m,j),n.push(e,f+h),n.push(k,l,m,j),n.push(e+g,f+h),n.push(k,l,m,j),o.push(p,p,p+1,p+2,p+3,p+3)}a.lineWidth&&(a.points=[e,f,e+g,f,e+g,f+h,e,f+h,e,f],b.WebGLGraphics.buildLine(a,c))},b.WebGLGraphics.buildCircle=function(a,c){var d=a.points,e=d[0],f=d[1],g=d[2],h=d[3],i=40,j=2*Math.PI/i,k=0;if(a.fill){var l=b.hex2rgb(a.fillColor),m=a.fillAlpha,n=l[0]*m,o=l[1]*m,p=l[2]*m,q=c.points,r=c.indices,s=q.length/6;for(r.push(s),k=0;i+1>k;k++)q.push(e,f,n,o,p,m),q.push(e+Math.sin(j*k)*g,f+Math.cos(j*k)*h,n,o,p,m),r.push(s++,s++);r.push(s-1)}if(a.lineWidth){for(a.points=[],k=0;i+1>k;k++)a.points.push(e+Math.sin(j*k)*g,f+Math.cos(j*k)*h);b.WebGLGraphics.buildLine(a,c)}},b.WebGLGraphics.buildLine=function(a,c){var d=0,e=a.points;if(0!==e.length){if(a.lineWidth%2)for(d=0;dd;d++)l=e[2*(d-1)],m=e[2*(d-1)+1],n=e[2*d],o=e[2*d+1],p=e[2*(d+1)],q=e[2*(d+1)+1],r=-(m-o),s=l-n,F=Math.sqrt(r*r+s*s),r/=F,s/=F,r*=L,s*=L,t=-(o-q),u=n-p,F=Math.sqrt(t*t+u*u),t/=F,u/=F,t*=L,u*=L,x=-s+m-(-s+o),y=-r+n-(-r+l),z=(-r+l)*(-s+o)-(-r+n)*(-s+m),A=-u+q-(-u+o),B=-t+n-(-t+p),C=(-t+p)*(-u+o)-(-t+n)*(-u+q),D=x*B-A*y,Math.abs(D)<.1?(D+=10.1,G.push(n-r,o-s,O,P,Q,N),G.push(n+r,o+s,O,P,Q,N)):(j=(y*C-B*z)/D,k=(A*z-x*C)/D,E=(j-n)*(j-n)+(k-o)+(k-o),E>19600?(v=r-t,w=s-u,F=Math.sqrt(v*v+w*w),v/=F,w/=F,v*=L,w*=L,G.push(n-v,o-w),G.push(O,P,Q,N),G.push(n+v,o+w),G.push(O,P,Q,N),G.push(n-v,o-w),G.push(O,P,Q,N),J++):(G.push(j,k),G.push(O,P,Q,N),G.push(n-(j-n),o-(k-o)),G.push(O,P,Q,N)));for(l=e[2*(I-2)],m=e[2*(I-2)+1],n=e[2*(I-1)],o=e[2*(I-1)+1],r=-(m-o),s=l-n,F=Math.sqrt(r*r+s*s),r/=F,s/=F,r*=L,s*=L,G.push(n-r,o-s),G.push(O,P,Q,N),G.push(n+r,o+s),G.push(O,P,Q,N),H.push(K),d=0;J>d;d++)H.push(K++);H.push(K-1)}},b.WebGLGraphics.buildPoly=function(a,c){var d=a.points;if(!(d.length<6)){var e=c.points,f=c.indices,g=d.length/2,h=b.hex2rgb(a.fillColor),i=a.fillAlpha,j=h[0]*i,k=h[1]*i,l=h[2]*i,m=b.PolyK.Triangulate(d),n=e.length/6,o=0;for(o=0;oo;o++)e.push(d[2*o],d[2*o+1],j,k,l,i)}},b._defaultFrame=new b.Rectangle(0,0,1,1),b.gl=null,b.WebGLRenderer=function(a,c,d,e,f){this.transparent=!!e,this.width=a||800,this.height=c||600,this.view=d||document.createElement("canvas"),this.view.width=this.width,this.view.height=this.height;var g=this;this.view.addEventListener("webglcontextlost",function(a){g.handleContextLost(a)},!1),this.view.addEventListener("webglcontextrestored",function(a){g.handleContextRestored(a)},!1),this.batchs=[];var h={alpha:this.transparent,antialias:!!f,premultipliedAlpha:!1,stencil:!0};try{b.gl=this.gl=this.view.getContext("experimental-webgl",h)}catch(i){try{b.gl=this.gl=this.view.getContext("webgl",h)}catch(j){throw new Error(" This browser does not support webGL. Try using the canvas renderer"+this)}}b.initDefaultShaders();var k=this.gl;k.useProgram(b.defaultShader.program),b.WebGLRenderer.gl=k,this.batch=new b.WebGLBatch(k),k.disable(k.DEPTH_TEST),k.disable(k.CULL_FACE),k.enable(k.BLEND),k.colorMask(!0,!0,!0,this.transparent),b.projection=new b.Point(400,300),b.offset=new b.Point(0,0),this.resize(this.width,this.height),this.contextLost=!1,this.stageRenderGroup=new b.WebGLRenderGroup(this.gl,this.transparent)},b.WebGLRenderer.prototype.constructor=b.WebGLRenderer,b.WebGLRenderer.getBatch=function(){return 0===b._batchs.length?new b.WebGLBatch(b.WebGLRenderer.gl):b._batchs.pop()},b.WebGLRenderer.returnBatch=function(a){a.clean(),b._batchs.push(a)},b.WebGLRenderer.prototype.render=function(a){if(!this.contextLost){this.__stage!==a&&(this.__stage=a,this.stageRenderGroup.setRenderable(a)),b.WebGLRenderer.updateTextures(),b.visibleCount++,a.updateTransform();var c=this.gl;if(c.colorMask(!0,!0,!0,this.transparent),c.viewport(0,0,this.width,this.height),c.bindFramebuffer(c.FRAMEBUFFER,null),c.clearColor(a.backgroundColorSplit[0],a.backgroundColorSplit[1],a.backgroundColorSplit[2],!this.transparent),c.clear(c.COLOR_BUFFER_BIT),this.stageRenderGroup.backgroundColor=a.backgroundColorSplit,b.projection.x=this.width/2,b.projection.y=-this.height/2,this.stageRenderGroup.render(b.projection),a.interactive&&(a._interactiveEventsAdded||(a._interactiveEventsAdded=!0,a.interactionManager.setTarget(this))),b.Texture.frameUpdates.length>0){for(var d=0;dn;n++)renderable=this.batchs[n],renderable instanceof b.WebGLBatch?this.batchs[n].render():this.renderSpecial(renderable,c);endBatch instanceof b.WebGLBatch?endBatch.render(0,h+1):this.renderSpecial(endBatch,c)},b.WebGLRenderGroup.prototype.renderSpecial=function(a,c){var d=a.vcount===b.visibleCount;a instanceof b.TilingSprite?d&&this.renderTilingSprite(a,c):a instanceof b.Strip?d&&this.renderStrip(a,c):a instanceof b.CustomRenderable?d&&a.renderWebGL(this,c):a instanceof b.Graphics?d&&a.renderable&&b.WebGLGraphics.renderGraphics(a,c):a instanceof b.FilterBlock&&this.handleFilterBlock(a,c)},flip=!1;var d=[],e=0;return b.WebGLRenderGroup.prototype.handleFilterBlock=function(a,c){var f=b.gl;if(a.open)a.data instanceof Array?this.filterManager.pushFilter(a):(e++,d.push(a),f.enable(f.STENCIL_TEST),f.colorMask(!1,!1,!1,!1),f.stencilFunc(f.ALWAYS,1,1),f.stencilOp(f.KEEP,f.KEEP,f.INCR),b.WebGLGraphics.renderGraphics(a.data,c),f.colorMask(!0,!0,!0,!0),f.stencilFunc(f.NOTEQUAL,0,d.length),f.stencilOp(f.KEEP,f.KEEP,f.KEEP));else if(a.data instanceof Array)this.filterManager.popFilter();else{var g=d.pop(a);g&&(f.colorMask(!1,!1,!1,!1),f.stencilFunc(f.ALWAYS,1,1),f.stencilOp(f.KEEP,f.KEEP,f.DECR),b.WebGLGraphics.renderGraphics(g.data,c),f.colorMask(!0,!0,!0,!0),f.stencilFunc(f.NOTEQUAL,0,d.length),f.stencilOp(f.KEEP,f.KEEP,f.KEEP)),f.disable(f.STENCIL_TEST)}},b.WebGLRenderGroup.prototype.updateTexture=function(a){this.removeObject(a);for(var b=a.first;b!=this.root&&(b=b._iPrev,!b.renderable||!b.__renderGroup););for(var c=a.last;c._iNext&&(c=c._iNext,!c.renderable||!c.__renderGroup););this.insertObject(a,b,c)},b.WebGLRenderGroup.prototype.addFilterBlocks=function(a,b){a.__renderGroup=this,b.__renderGroup=this;for(var c=a;c!=this.root.first&&(c=c._iPrev,!c.renderable||!c.__renderGroup););this.insertAfter(a,c);for(var d=b;d!=this.root.first&&(d=d._iPrev,!d.renderable||!d.__renderGroup););this.insertAfter(b,d)},b.WebGLRenderGroup.prototype.removeFilterBlocks=function(a,b){this.removeObject(a),this.removeObject(b)},b.WebGLRenderGroup.prototype.addDisplayObjectAndChildren=function(a){a.__renderGroup&&a.__renderGroup.removeDisplayObjectAndChildren(a);for(var b=a.first;b!=this.root.first&&(b=b._iPrev,!b.renderable||!b.__renderGroup););for(var c=a.last;c._iNext&&(c=c._iNext,!c.renderable||!c.__renderGroup););var d=a.first,e=a.last._iNext;do d.__renderGroup=this,d.renderable&&(this.insertObject(d,b,c),b=d),d=d._iNext;while(d!=e)},b.WebGLRenderGroup.prototype.removeDisplayObjectAndChildren=function(a){if(a.__renderGroup==this){a.last;do a.__renderGroup=null,a.renderable&&this.removeObject(a),a=a._iNext;while(a)}},b.WebGLRenderGroup.prototype.insertObject=function(a,c,d){var e=c,f=d;if(a instanceof b.Sprite){var g,h;if(e instanceof b.Sprite){if(g=e.batch,g&&g.texture==a.texture.baseTexture&&g.blendMode==a.blendMode)return g.insertAfter(a,e),void 0}else g=e;if(f)if(f instanceof b.Sprite){if(h=f.batch){if(h.texture==a.texture.baseTexture&&h.blendMode==a.blendMode)return h.insertBefore(a,f),void 0;if(h==g){var i=g.split(f),j=b.WebGLRenderer.getBatch(),k=this.batchs.indexOf(g);return j.init(a),this.batchs.splice(k+1,0,j,i),void 0}}}else h=f;var j=b.WebGLRenderer.getBatch();if(j.init(a),g){var k=this.batchs.indexOf(g);this.batchs.splice(k+1,0,j)}else this.batchs.push(j)}else a instanceof b.TilingSprite?this.initTilingSprite(a):a instanceof b.Strip&&this.initStrip(a),this.insertAfter(a,e)},b.WebGLRenderGroup.prototype.insertAfter=function(a,c){if(c instanceof b.Sprite){var d=c.batch;if(d)if(d.tail==c){var e=this.batchs.indexOf(d);this.batchs.splice(e+1,0,a)}else{var f=d.split(c.__next),e=this.batchs.indexOf(d);this.batchs.splice(e+1,0,a,f)}else this.batchs.push(a)}else{var e=this.batchs.indexOf(c);this.batchs.splice(e+1,0,a)}},b.WebGLRenderGroup.prototype.removeObject=function(a){var c;if(a instanceof b.Sprite){var d=a.batch;if(!d)return;d.remove(a),0==d.size&&(c=d)}else c=a;if(c){var e=this.batchs.indexOf(c);if(-1==e)return;if(0==e||e==this.batchs.length-1)return this.batchs.splice(e,1),c instanceof b.WebGLBatch&&b.WebGLRenderer.returnBatch(c),void 0;if(this.batchs[e-1]instanceof b.WebGLBatch&&this.batchs[e+1]instanceof b.WebGLBatch&&this.batchs[e-1].texture==this.batchs[e+1].texture&&this.batchs[e-1].blendMode==this.batchs[e+1].blendMode)return this.batchs[e-1].merge(this.batchs[e+1]),c instanceof b.WebGLBatch&&b.WebGLRenderer.returnBatch(c),b.WebGLRenderer.returnBatch(this.batchs[e+1]),this.batchs.splice(e,2),void 0;this.batchs.splice(e,1),c instanceof b.WebGLBatch&&b.WebGLRenderer.returnBatch(c)}},b.WebGLRenderGroup.prototype.initTilingSprite=function(a){var b=this.gl;a.verticies=new Float32Array([0,0,a.width,0,a.width,a.height,0,a.height]),a.uvs=new Float32Array([0,0,1,0,1,1,0,1]),a.colors=new Float32Array([1,1,1,1]),a.indices=new Uint16Array([0,1,3,2]),a._vertexBuffer=b.createBuffer(),a._indexBuffer=b.createBuffer(),a._uvBuffer=b.createBuffer(),a._colorBuffer=b.createBuffer(),b.bindBuffer(b.ARRAY_BUFFER,a._vertexBuffer),b.bufferData(b.ARRAY_BUFFER,a.verticies,b.STATIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._uvBuffer),b.bufferData(b.ARRAY_BUFFER,a.uvs,b.DYNAMIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._colorBuffer),b.bufferData(b.ARRAY_BUFFER,a.colors,b.STATIC_DRAW),b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,a._indexBuffer),b.bufferData(b.ELEMENT_ARRAY_BUFFER,a.indices,b.STATIC_DRAW),a.texture.baseTexture._glTexture?(b.bindTexture(b.TEXTURE_2D,a.texture.baseTexture._glTexture),b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_S,b.REPEAT),b.texParameteri(b.TEXTURE_2D,b.TEXTURE_WRAP_T,b.REPEAT),a.texture.baseTexture._powerOf2=!0):a.texture.baseTexture._powerOf2=!0},b.WebGLRenderGroup.prototype.renderStrip=function(a,c){var d=this.gl;b.activateStripShader();var e=b.stripShader;e.program;var f=b.mat3.clone(a.worldTransform);b.mat3.transpose(f),d.uniformMatrix3fv(e.translationMatrix,!1,f),d.uniform2f(e.projectionVector,c.x,c.y),d.uniform2f(e.offsetVector,-b.offset.x,-b.offset.y),d.uniform1f(e.alpha,a.worldAlpha),a.dirty?(a.dirty=!1,d.bindBuffer(d.ARRAY_BUFFER,a._vertexBuffer),d.bufferData(d.ARRAY_BUFFER,a.verticies,d.STATIC_DRAW),d.vertexAttribPointer(e.aVertexPosition,2,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,a._uvBuffer),d.bufferData(d.ARRAY_BUFFER,a.uvs,d.STATIC_DRAW),d.vertexAttribPointer(e.aTextureCoord,2,d.FLOAT,!1,0,0),d.activeTexture(d.TEXTURE0),d.bindTexture(d.TEXTURE_2D,a.texture.baseTexture._glTexture),d.bindBuffer(d.ARRAY_BUFFER,a._colorBuffer),d.bufferData(d.ARRAY_BUFFER,a.colors,d.STATIC_DRAW),d.vertexAttribPointer(e.colorAttribute,1,d.FLOAT,!1,0,0),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,a._indexBuffer),d.bufferData(d.ELEMENT_ARRAY_BUFFER,a.indices,d.STATIC_DRAW)):(d.bindBuffer(d.ARRAY_BUFFER,a._vertexBuffer),d.bufferSubData(d.ARRAY_BUFFER,0,a.verticies),d.vertexAttribPointer(e.aVertexPosition,2,d.FLOAT,!1,0,0),d.bindBuffer(d.ARRAY_BUFFER,a._uvBuffer),d.vertexAttribPointer(e.aTextureCoord,2,d.FLOAT,!1,0,0),d.activeTexture(d.TEXTURE0),d.bindTexture(d.TEXTURE_2D,a.texture.baseTexture._glTexture),d.bindBuffer(d.ARRAY_BUFFER,a._colorBuffer),d.vertexAttribPointer(e.colorAttribute,1,d.FLOAT,!1,0,0),d.bindBuffer(d.ELEMENT_ARRAY_BUFFER,a._indexBuffer)),d.drawElements(d.TRIANGLE_STRIP,a.indices.length,d.UNSIGNED_SHORT,0),b.deactivateStripShader() +},b.WebGLRenderGroup.prototype.renderTilingSprite=function(a,c){var d=this.gl;b.shaderProgram;var e=a.tilePosition,f=a.tileScale,g=e.x/a.texture.baseTexture.width,h=e.y/a.texture.baseTexture.height,i=a.width/a.texture.baseTexture.width/f.x,j=a.height/a.texture.baseTexture.height/f.y;a.uvs[0]=0-g,a.uvs[1]=0-h,a.uvs[2]=1*i-g,a.uvs[3]=0-h,a.uvs[4]=1*i-g,a.uvs[5]=1*j-h,a.uvs[6]=0-g,a.uvs[7]=1*j-h,d.bindBuffer(d.ARRAY_BUFFER,a._uvBuffer),d.bufferSubData(d.ARRAY_BUFFER,0,a.uvs),this.renderStrip(a,c)},b.WebGLRenderGroup.prototype.initStrip=function(a){var b=this.gl;this.shaderProgram,a._vertexBuffer=b.createBuffer(),a._indexBuffer=b.createBuffer(),a._uvBuffer=b.createBuffer(),a._colorBuffer=b.createBuffer(),b.bindBuffer(b.ARRAY_BUFFER,a._vertexBuffer),b.bufferData(b.ARRAY_BUFFER,a.verticies,b.DYNAMIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._uvBuffer),b.bufferData(b.ARRAY_BUFFER,a.uvs,b.STATIC_DRAW),b.bindBuffer(b.ARRAY_BUFFER,a._colorBuffer),b.bufferData(b.ARRAY_BUFFER,a.colors,b.STATIC_DRAW),b.bindBuffer(b.ELEMENT_ARRAY_BUFFER,a._indexBuffer),b.bufferData(b.ELEMENT_ARRAY_BUFFER,a.indices,b.STATIC_DRAW)},b.initDefaultShaders=function(){b.primitiveShader=new b.PrimitiveShader,b.primitiveShader.init(),b.stripShader=new b.StripShader,b.stripShader.init(),b.defaultShader=new b.PixiShader,b.defaultShader.init();var a=b.gl,c=b.defaultShader.program;a.useProgram(c),a.enableVertexAttribArray(b.defaultShader.aVertexPosition),a.enableVertexAttribArray(b.defaultShader.colorAttribute),a.enableVertexAttribArray(b.defaultShader.aTextureCoord)},b.activatePrimitiveShader=function(){var a=b.gl;a.useProgram(b.primitiveShader.program),a.disableVertexAttribArray(b.defaultShader.aVertexPosition),a.disableVertexAttribArray(b.defaultShader.colorAttribute),a.disableVertexAttribArray(b.defaultShader.aTextureCoord),a.enableVertexAttribArray(b.primitiveShader.aVertexPosition),a.enableVertexAttribArray(b.primitiveShader.colorAttribute)},b.deactivatePrimitiveShader=function(){var a=b.gl;a.useProgram(b.defaultShader.program),a.disableVertexAttribArray(b.primitiveShader.aVertexPosition),a.disableVertexAttribArray(b.primitiveShader.colorAttribute),a.enableVertexAttribArray(b.defaultShader.aVertexPosition),a.enableVertexAttribArray(b.defaultShader.colorAttribute),a.enableVertexAttribArray(b.defaultShader.aTextureCoord)},b.activateStripShader=function(){var a=b.gl;a.useProgram(b.stripShader.program)},b.deactivateStripShader=function(){var a=b.gl;a.useProgram(b.defaultShader.program)},b.CompileVertexShader=function(a,c){return b._CompileShader(a,c,a.VERTEX_SHADER)},b.CompileFragmentShader=function(a,c){return b._CompileShader(a,c,a.FRAGMENT_SHADER)},b._CompileShader=function(a,b,c){var d=b.join("\n"),e=a.createShader(c);return a.shaderSource(e,d),a.compileShader(e),a.getShaderParameter(e,a.COMPILE_STATUS)?e:(window.console.log(a.getShaderInfoLog(e)),null)},b.compileProgram=function(a,c){var d=b.gl,e=b.CompileFragmentShader(d,c),f=b.CompileVertexShader(d,a),g=d.createProgram();return d.attachShader(g,f),d.attachShader(g,e),d.linkProgram(g),d.getProgramParameter(g,d.LINK_STATUS)||window.console.log("Could not initialise shaders"),g},b.BitmapText=function(a,c){b.DisplayObjectContainer.call(this),this.setText(a),this.setStyle(c),this.updateText(),this.dirty=!1},b.BitmapText.prototype=Object.create(b.DisplayObjectContainer.prototype),b.BitmapText.prototype.constructor=b.BitmapText,b.BitmapText.prototype.setText=function(a){this.text=a||" ",this.dirty=!0},b.BitmapText.prototype.setStyle=function(a){a=a||{},a.align=a.align||"left",this.style=a;var c=a.font.split(" ");this.fontName=c[c.length-1],this.fontSize=c.length>=2?parseInt(c[c.length-2],10):b.BitmapText.fonts[this.fontName].size,this.dirty=!0},b.BitmapText.prototype.updateText=function(){for(var a=b.BitmapText.fonts[this.fontName],c=new b.Point,d=null,e=[],f=0,g=[],h=0,i=this.fontSize/a.size,j=0;j=j;j++){var n=0;"right"===this.style.align?n=f-g[j]:"center"===this.style.align&&(n=(f-g[j])/2),m.push(n)}for(j=0;j0;)this.removeChild(this.getChildAt(0));this.updateText(),this.dirty=!1}b.DisplayObjectContainer.prototype.updateTransform.call(this)},b.BitmapText.fonts={},b.Text=function(a,c){this.canvas=document.createElement("canvas"),this.context=this.canvas.getContext("2d"),b.Sprite.call(this,b.Texture.fromCanvas(this.canvas)),this.setText(a),this.setStyle(c),this.updateText(),this.dirty=!1},b.Text.prototype=Object.create(b.Sprite.prototype),b.Text.prototype.constructor=b.Text,b.Text.prototype.setStyle=function(a){a=a||{},a.font=a.font||"bold 20pt Arial",a.fill=a.fill||"black",a.align=a.align||"left",a.stroke=a.stroke||"black",a.strokeThickness=a.strokeThickness||0,a.wordWrap=a.wordWrap||!1,a.wordWrapWidth=a.wordWrapWidth||100,this.style=a,this.dirty=!0},b.Text.prototype.setText=function(a){this.text=a.toString()||" ",this.dirty=!0},b.Text.prototype.updateText=function(){this.context.font=this.style.font;var a=this.text;this.style.wordWrap&&(a=this.wordWrap(this.text));for(var c=a.split(/(?:\r\n|\r|\n)/),d=[],e=0,f=0;fe?(g>0&&(b+="\n"),b+=f[g]+" ",e=this.style.wordWrapWidth-h):(e-=i,b+=f[g]+" ")}b+="\n"}return b},b.Text.prototype.destroy=function(a){a&&this.texture.destroy()},b.Text.heightCache={},b.BaseTextureCache={},b.texturesToUpdate=[],b.texturesToDestroy=[],b.BaseTexture=function(a,c){if(b.EventTarget.call(this),this.width=100,this.height=100,this.scaleMode=c||b.BaseTexture.SCALE_MODE.DEFAULT,this.hasLoaded=!1,this.source=a,a){if(this.source instanceof Image||this.source instanceof HTMLImageElement)if(this.source.complete)this.hasLoaded=!0,this.width=this.source.width,this.height=this.source.height,b.texturesToUpdate.push(this);else{var d=this;this.source.onload=function(){d.hasLoaded=!0,d.width=d.source.width,d.height=d.source.height,b.texturesToUpdate.push(d),d.dispatchEvent({type:"loaded",content:d})}}else this.hasLoaded=!0,this.width=this.source.width,this.height=this.source.height,b.texturesToUpdate.push(this);this.imageUrl=null,this._powerOf2=!1}},b.BaseTexture.prototype.constructor=b.BaseTexture,b.BaseTexture.prototype.destroy=function(){this.source instanceof Image&&(this.imageUrl in b.BaseTextureCache&&delete b.BaseTextureCache[this.imageUrl],this.imageUrl=null,this.source.src=null),this.source=null,b.texturesToDestroy.push(this)},b.BaseTexture.prototype.updateSourceImage=function(a){this.hasLoaded=!1,this.source.src=null,this.source.src=a},b.BaseTexture.fromImage=function(a,c,d){var e=b.BaseTextureCache[a];if(!e){var f=new Image;c&&(f.crossOrigin=""),f.src=a,e=new b.BaseTexture(f,d),e.imageUrl=a,b.BaseTextureCache[a]=e}return e},b.BaseTexture.SCALE_MODE={DEFAULT:0,LINEAR:0,NEAREST:1},b.TextureCache={},b.FrameCache={},b.Texture=function(a,c){if(b.EventTarget.call(this),c||(this.noFrame=!0,c=new b.Rectangle(0,0,1,1)),a instanceof b.Texture&&(a=a.baseTexture),this.baseTexture=a,this.frame=c,this.trim=new b.Point,this.scope=this,a.hasLoaded)this.noFrame&&(c=new b.Rectangle(0,0,a.width,a.height)),this.setFrame(c);else{var d=this;a.addEventListener("loaded",function(){d.onBaseTextureLoaded()})}},b.Texture.prototype.constructor=b.Texture,b.Texture.prototype.onBaseTextureLoaded=function(){var a=this.baseTexture;a.removeEventListener("loaded",this.onLoaded),this.noFrame&&(this.frame=new b.Rectangle(0,0,a.width,a.height)),this.noFrame=!1,this.width=this.frame.width,this.height=this.frame.height,this.scope.dispatchEvent({type:"update",content:this})},b.Texture.prototype.destroy=function(a){a&&this.baseTexture.destroy()},b.Texture.prototype.setFrame=function(a){if(this.frame=a,this.width=a.width,this.height=a.height,a.x+a.width>this.baseTexture.width||a.y+a.height>this.baseTexture.height)throw new Error("Texture Error: frame does not fit inside the base Texture dimensions "+this);this.updateFrame=!0,b.Texture.frameUpdates.push(this)},b.Texture.fromImage=function(a,c,d){var e=b.TextureCache[a];return e||(e=new b.Texture(b.BaseTexture.fromImage(a,c,d)),b.TextureCache[a]=e),e},b.Texture.fromFrame=function(a){var c=b.TextureCache[a];if(!c)throw new Error('The frameId "'+a+'" does not exist in the texture cache '+this);return c},b.Texture.fromCanvas=function(a,c){var d=new b.BaseTexture(a,c);return new b.Texture(d)},b.Texture.addTextureToCache=function(a,c){b.TextureCache[c]=a},b.Texture.removeTextureFromCache=function(a){var c=b.TextureCache[a];return b.TextureCache[a]=null,c},b.Texture.frameUpdates=[],b.Texture.SCALE_MODE=b.BaseTexture.SCALE_MODE,b.RenderTexture=function(a,c){b.EventTarget.call(this),this.width=a||100,this.height=c||100,this.indetityMatrix=b.mat3.create(),this.frame=new b.Rectangle(0,0,this.width,this.height),b.gl?this.initWebGL():this.initCanvas()},b.RenderTexture.prototype=Object.create(b.Texture.prototype),b.RenderTexture.prototype.constructor=b.RenderTexture,b.RenderTexture.prototype.initWebGL=function(){var a=b.gl;this.glFramebuffer=a.createFramebuffer(),a.bindFramebuffer(a.FRAMEBUFFER,this.glFramebuffer),this.glFramebuffer.width=this.width,this.glFramebuffer.height=this.height,this.baseTexture=new b.BaseTexture,this.baseTexture.width=this.width,this.baseTexture.height=this.height,this.baseTexture._glTexture=a.createTexture(),a.bindTexture(a.TEXTURE_2D,this.baseTexture._glTexture),a.texImage2D(a.TEXTURE_2D,0,a.RGBA,this.width,this.height,0,a.RGBA,a.UNSIGNED_BYTE,null),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MAG_FILTER,a.LINEAR),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_MIN_FILTER,a.LINEAR),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_S,a.CLAMP_TO_EDGE),a.texParameteri(a.TEXTURE_2D,a.TEXTURE_WRAP_T,a.CLAMP_TO_EDGE),this.baseTexture.isRender=!0,a.bindFramebuffer(a.FRAMEBUFFER,this.glFramebuffer),a.framebufferTexture2D(a.FRAMEBUFFER,a.COLOR_ATTACHMENT0,a.TEXTURE_2D,this.baseTexture._glTexture,0),this.projection=new b.Point(this.width/2,-this.height/2),this.render=this.renderWebGL},b.RenderTexture.prototype.resize=function(a,c){if(this.width=a,this.height=c,b.gl){this.projection.x=this.width/2,this.projection.y=-this.height/2;var d=b.gl;d.bindTexture(d.TEXTURE_2D,this.baseTexture._glTexture),d.texImage2D(d.TEXTURE_2D,0,d.RGBA,this.width,this.height,0,d.RGBA,d.UNSIGNED_BYTE,null)}else this.frame.width=this.width,this.frame.height=this.height,this.renderer.resize(this.width,this.height)},b.RenderTexture.prototype.initCanvas=function(){this.renderer=new b.CanvasRenderer(this.width,this.height,null,0),this.baseTexture=new b.BaseTexture(this.renderer.view),this.frame=new b.Rectangle(0,0,this.width,this.height),this.render=this.renderCanvas},b.RenderTexture.prototype.renderWebGL=function(a,c,d){var e=b.gl;e.colorMask(!0,!0,!0,!0),e.viewport(0,0,this.width,this.height),e.bindFramebuffer(e.FRAMEBUFFER,this.glFramebuffer),d&&(e.clearColor(0,0,0,0),e.clear(e.COLOR_BUFFER_BIT));var f=a.children,g=a.worldTransform;a.worldTransform=b.mat3.create(),a.worldTransform[4]=-1,a.worldTransform[5]=-2*this.projection.y,c&&(a.worldTransform[2]=c.x,a.worldTransform[5]-=c.y),b.visibleCount++,a.vcount=b.visibleCount;for(var h=0,i=f.length;i>h;h++)f[h].updateTransform();var j=a.__renderGroup;j?a===j.root?j.render(this.projection,this.glFramebuffer):j.renderSpecific(a,this.projection,this.glFramebuffer):(this.renderGroup||(this.renderGroup=new b.WebGLRenderGroup(e)),this.renderGroup.setRenderable(a),this.renderGroup.render(this.projection,this.glFramebuffer)),a.worldTransform=g},b.RenderTexture.prototype.renderCanvas=function(a,c,d){var e=a.children;a.worldTransform=b.mat3.create(),c&&(a.worldTransform[2]=c.x,a.worldTransform[5]=c.y);for(var f=0,g=e.length;g>f;f++)e[f].updateTransform();d&&this.renderer.context.clearRect(0,0,this.width,this.height),this.renderer.renderDisplayObject(a),this.renderer.context.setTransform(1,0,0,1,0,0)},b.EventTarget=function(){var a={};this.addEventListener=this.on=function(b,c){void 0===a[b]&&(a[b]=[]),-1===a[b].indexOf(c)&&a[b].push(c)},this.dispatchEvent=this.emit=function(b){if(a[b.type]&&a[b.type].length)for(var c=0,d=a[b.type].length;d>c;c++)a[b.type][c](b)},this.removeEventListener=this.off=function(b,c){var d=a[b].indexOf(c);-1!==d&&a[b].splice(d,1)},this.removeAllEventListeners=function(b){var c=a[b];c&&(c.length=0)}},b.PolyK={},b.PolyK.Triangulate=function(a){var c=!0,d=a.length>>1;if(3>d)return[];for(var e=[],f=[],g=0;d>g;g++)f.push(g);g=0;for(var h=d;h>3;){var i=f[(g+0)%h],j=f[(g+1)%h],k=f[(g+2)%h],l=a[2*i],m=a[2*i+1],n=a[2*j],o=a[2*j+1],p=a[2*k],q=a[2*k+1],r=!1;if(b.PolyK._convex(l,m,n,o,p,q,c)){r=!0;for(var s=0;h>s;s++){var t=f[s];if(t!==i&&t!==j&&t!==k&&b.PolyK._PointInTriangle(a[2*t],a[2*t+1],l,m,n,o,p,q)){r=!1;break}}}if(r)e.push(i,j,k),f.splice((g+1)%h,1),h--,g=0;else if(g++>3*h){if(!c)return window.console.log("PIXI Warning: shape too complex to fill"),[];for(e=[],f=[],g=0;d>g;g++)f.push(g);g=0,h=d,c=!1}}return e.push(f[0],f[1],f[2]),e},b.PolyK._PointInTriangle=function(a,b,c,d,e,f,g,h){var i=g-c,j=h-d,k=e-c,l=f-d,m=a-c,n=b-d,o=i*i+j*j,p=i*k+j*l,q=i*m+j*n,r=k*k+l*l,s=k*m+l*n,t=1/(o*r-p*p),u=(r*q-p*s)*t,v=(o*s-p*q)*t;return u>=0&&v>=0&&1>u+v},b.PolyK._convex=function(a,b,c,d,e,f,g){return(b-d)*(e-c)+(c-a)*(f-d)>=0===g},c.Camera=function(a,b,d,e,f,g){this.game=a,this.world=a.world,this.id=0,this.view=new c.Rectangle(d,e,f,g),this.screenView=new c.Rectangle(d,e,f,g),this.bounds=new c.Rectangle(d,e,f,g),this.deadzone=null,this.visible=!0,this.atLimit={x:!1,y:!1},this.target=null,this._edge=0,this.displayObject=null},c.Camera.FOLLOW_LOCKON=0,c.Camera.FOLLOW_PLATFORMER=1,c.Camera.FOLLOW_TOPDOWN=2,c.Camera.FOLLOW_TOPDOWN_TIGHT=3,c.Camera.prototype={follow:function(a,b){"undefined"==typeof b&&(b=c.Camera.FOLLOW_LOCKON),this.target=a;var d;switch(b){case c.Camera.FOLLOW_PLATFORMER:var e=this.width/8,f=this.height/3;this.deadzone=new c.Rectangle((this.width-e)/2,(this.height-f)/2-.25*f,e,f);break;case c.Camera.FOLLOW_TOPDOWN:d=Math.max(this.width,this.height)/4,this.deadzone=new c.Rectangle((this.width-d)/2,(this.height-d)/2,d,d);break;case c.Camera.FOLLOW_TOPDOWN_TIGHT:d=Math.max(this.width,this.height)/8,this.deadzone=new c.Rectangle((this.width-d)/2,(this.height-d)/2,d,d);break;case c.Camera.FOLLOW_LOCKON:this.deadzone=null;break;default:this.deadzone=null}},focusOn:function(a){this.setPosition(Math.round(a.x-this.view.halfWidth),Math.round(a.y-this.view.halfHeight))},focusOnXY:function(a,b){this.setPosition(Math.round(a-this.view.halfWidth),Math.round(b-this.view.halfHeight))},update:function(){this.target&&this.updateTarget(),this.bounds&&this.checkBounds(),this.displayObject.position.x=-this.view.x,this.displayObject.position.y=-this.view.y},updateTarget:function(){this.deadzone?(this._edge=this.target.x-this.deadzone.x,this.view.x>this._edge&&(this.view.x=this._edge),this._edge=this.target.x+this.target.width-this.deadzone.x-this.deadzone.width,this.view.xthis._edge&&(this.view.y=this._edge),this._edge=this.target.y+this.target.height-this.deadzone.y-this.deadzone.height,this.view.ythis.bounds.right&&(this.atLimit.x=!0,this.view.x=this.bounds.right-this.width),this.view.ythis.bounds.bottom&&(this.atLimit.y=!0,this.view.y=this.bounds.bottom-this.height),this.view.floor()},setPosition:function(a,b){this.view.x=a,this.view.y=b,this.bounds&&this.checkBounds()},setSize:function(a,b){this.view.width=a,this.view.height=b}},c.Camera.prototype.constructor=c.Camera,Object.defineProperty(c.Camera.prototype,"x",{get:function(){return this.view.x},set:function(a){this.view.x=a,this.bounds&&this.checkBounds()}}),Object.defineProperty(c.Camera.prototype,"y",{get:function(){return this.view.y},set:function(a){this.view.y=a,this.bounds&&this.checkBounds()}}),Object.defineProperty(c.Camera.prototype,"width",{get:function(){return this.view.width},set:function(a){this.view.width=a}}),Object.defineProperty(c.Camera.prototype,"height",{get:function(){return this.view.height},set:function(a){this.view.height=a}}),c.State=function(){this.game=null,this.add=null,this.camera=null,this.cache=null,this.input=null,this.load=null,this.math=null,this.sound=null,this.stage=null,this.time=null,this.tweens=null,this.world=null,this.particles=null,this.physics=null},c.State.prototype={preload:function(){},loadUpdate:function(){},loadRender:function(){},create:function(){},update:function(){},render:function(){},paused:function(){},destroy:function(){}},c.State.prototype.constructor=c.State,c.StateManager=function(a,b){this.game=a,this.states={},this._pendingState=null,"undefined"!=typeof b&&null!==b&&(this._pendingState=b),this._created=!1,this.current="",this.onInitCallback=null,this.onPreloadCallback=null,this.onCreateCallback=null,this.onUpdateCallback=null,this.onRenderCallback=null,this.onPreRenderCallback=null,this.onLoadUpdateCallback=null,this.onLoadRenderCallback=null,this.onPausedCallback=null,this.onShutDownCallback=null},c.StateManager.prototype={boot:function(){this.game.onPause.add(this.pause,this),this.game.onResume.add(this.resume,this),null!==this._pendingState&&("string"==typeof this._pendingState?this.start(this._pendingState,!1,!1):this.add("default",this._pendingState,!0))},add:function(a,b,d){"undefined"==typeof d&&(d=!1);var e;return b instanceof c.State?e=b:"object"==typeof b?(e=b,e.game=this.game):"function"==typeof b&&(e=new b(this.game)),this.states[a]=e,d&&(this.game.isBooted?this.start(a):this._pendingState=a),e},remove:function(a){this.current==a&&(this.callbackContext=null,this.onInitCallback=null,this.onShutDownCallback=null,this.onPreloadCallback=null,this.onLoadRenderCallback=null,this.onLoadUpdateCallback=null,this.onCreateCallback=null,this.onUpdateCallback=null,this.onRenderCallback=null,this.onPausedCallback=null,this.onDestroyCallback=null),delete this.states[a]},start:function(a,b,c){return"undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=!1),this.game.isBooted===!1?(this._pendingState=a,void 0):(this.checkState(a)!==!1&&(this.current&&this.onShutDownCallback.call(this.callbackContext,this.game),b&&(this.game.tweens.removeAll(),this.game.world.destroy(),c===!0&&this.game.cache.destroy()),this.setCurrentState(a),this.onPreloadCallback?(this.game.load.reset(),this.onPreloadCallback.call(this.callbackContext,this.game),0===this.game.load.totalQueuedFiles()?this.game.loadComplete():this.game.load.start()):this.game.loadComplete()),void 0)},dummy:function(){},checkState:function(a){if(this.states[a]){var b=!1;return this.states[a].preload&&(b=!0),b===!1&&this.states[a].loadRender&&(b=!0),b===!1&&this.states[a].loadUpdate&&(b=!0),b===!1&&this.states[a].create&&(b=!0),b===!1&&this.states[a].update&&(b=!0),b===!1&&this.states[a].preRender&&(b=!0),b===!1&&this.states[a].render&&(b=!0),b===!1&&this.states[a].paused&&(b=!0),b===!1?(console.warn("Invalid Phaser State object given. Must contain at least a one of the required functions."),!1):!0}return console.warn("Phaser.StateManager - No state found with the key: "+a),!1},link:function(a){this.states[a].game=this.game,this.states[a].add=this.game.add,this.states[a].camera=this.game.camera,this.states[a].cache=this.game.cache,this.states[a].input=this.game.input,this.states[a].load=this.game.load,this.states[a].math=this.game.math,this.states[a].sound=this.game.sound,this.states[a].stage=this.game.stage,this.states[a].time=this.game.time,this.states[a].tweens=this.game.tweens,this.states[a].world=this.game.world,this.states[a].particles=this.game.particles,this.states[a].physics=this.game.physics,this.states[a].rnd=this.game.rnd},setCurrentState:function(a){this.callbackContext=this.states[a],this.link(a),this.onInitCallback=this.states[a].init||this.dummy,this.onPreloadCallback=this.states[a].preload||null,this.onLoadRenderCallback=this.states[a].loadRender||null,this.onLoadUpdateCallback=this.states[a].loadUpdate||null,this.onCreateCallback=this.states[a].create||null,this.onUpdateCallback=this.states[a].update||null,this.onPreRenderCallback=this.states[a].preRender||null,this.onRenderCallback=this.states[a].render||null,this.onPausedCallback=this.states[a].paused||null,this.onShutDownCallback=this.states[a].shutdown||this.dummy,this.current=a,this._created=!1,this.onInitCallback.call(this.callbackContext,this.game)},getCurrentState:function(){return this.states[this.current]},loadComplete:function(){this._created===!1&&this.onCreateCallback?(this._created=!0,this.onCreateCallback.call(this.callbackContext,this.game)):this._created=!0},pause:function(){this._created&&this.onPausedCallback&&this.onPausedCallback.call(this.callbackContext,this.game,!0)},resume:function(){this._created&&this.onre&&this.onPausedCallback.call(this.callbackContext,this.game,!1)},update:function(){this._created&&this.onUpdateCallback?this.onUpdateCallback.call(this.callbackContext,this.game):this.onLoadUpdateCallback&&this.onLoadUpdateCallback.call(this.callbackContext,this.game)},preRender:function(){this.onPreRenderCallback&&this.onPreRenderCallback.call(this.callbackContext,this.game)},render:function(){this._created&&this.onRenderCallback?(this.game.renderType===c.CANVAS&&(this.game.context.save(),this.game.context.setTransform(1,0,0,1,0,0)),this.onRenderCallback.call(this.callbackContext,this.game),this.game.renderType===c.CANVAS&&this.game.context.restore()):this.onLoadRenderCallback&&this.onLoadRenderCallback.call(this.callbackContext,this.game)},destroy:function(){this.callbackContext=null,this.onInitCallback=null,this.onShutDownCallback=null,this.onPreloadCallback=null,this.onLoadRenderCallback=null,this.onLoadUpdateCallback=null,this.onCreateCallback=null,this.onUpdateCallback=null,this.onRenderCallback=null,this.onPausedCallback=null,this.onDestroyCallback=null,this.game=null,this.states={},this._pendingState=null}},c.StateManager.prototype.constructor=c.StateManager,c.LinkedList=function(){this.next=null,this.prev=null,this.first=null,this.last=null,this.total=0},c.LinkedList.prototype={add:function(a){return 0===this.total&&null==this.first&&null==this.last?(this.first=a,this.last=a,this.next=a,a.prev=this,this.total++,a):(this.last.next=a,a.prev=this.last,this.last=a,this.total++,a)},remove:function(a){a==this.first?this.first=this.first.next:a==this.last&&(this.last=this.last.prev),a.prev&&(a.prev.next=a.next),a.next&&(a.next.prev=a.prev),a.next=a.prev=null,null==this.first&&(this.last=null),this.total--},callAll:function(a){if(this.first&&this.last){var b=this.first;do b&&b[a]&&b[a].call(b),b=b.next;while(b!=this.last.next)}}},c.LinkedList.prototype.constructor=c.LinkedList,c.Signal=function(){this._bindings=[],this._prevParams=null;var a=this;this.dispatch=function(){c.Signal.prototype.dispatch.apply(a,arguments)}},c.Signal.prototype={memorize:!1,_shouldPropagate:!0,active:!0,validateListener:function(a,b){if("function"!=typeof a)throw new Error("listener is a required param of {fn}() and should be a Function.".replace("{fn}",b))},_registerListener:function(a,b,d,e){var f,g=this._indexOfListener(a,d);if(-1!==g){if(f=this._bindings[g],f.isOnce()!==b)throw new Error("You cannot add"+(b?"":"Once")+"() then add"+(b?"Once":"")+"() the same listener without removing the relationship first.")}else f=new c.SignalBinding(this,a,b,d,e),this._addBinding(f);return this.memorize&&this._prevParams&&f.execute(this._prevParams),f},_addBinding:function(a){var b=this._bindings.length;do--b;while(this._bindings[b]&&a._priority<=this._bindings[b]._priority);this._bindings.splice(b+1,0,a)},_indexOfListener:function(a,b){for(var c,d=this._bindings.length;d--;)if(c=this._bindings[d],c._listener===a&&c.context===b)return d;return-1},has:function(a,b){return-1!==this._indexOfListener(a,b)},add:function(a,b,c){return this.validateListener(a,"add"),this._registerListener(a,!1,b,c)},addOnce:function(a,b,c){return this.validateListener(a,"addOnce"),this._registerListener(a,!0,b,c)},remove:function(a,b){this.validateListener(a,"remove");var c=this._indexOfListener(a,b);return-1!==c&&(this._bindings[c]._destroy(),this._bindings.splice(c,1)),a},removeAll:function(){for(var a=this._bindings.length;a--;)this._bindings[a]._destroy();this._bindings.length=0},getNumListeners:function(){return this._bindings.length},halt:function(){this._shouldPropagate=!1},dispatch:function(){if(this.active){var a,b=Array.prototype.slice.call(arguments),c=this._bindings.length;if(this.memorize&&(this._prevParams=b),c){a=this._bindings.slice(),this._shouldPropagate=!0;do c--;while(a[c]&&this._shouldPropagate&&a[c].execute(b)!==!1)}}},forget:function(){this._prevParams=null},dispose:function(){this.removeAll(),delete this._bindings,delete this._prevParams},toString:function(){return"[Phaser.Signal active:"+this.active+" numListeners:"+this.getNumListeners()+"]"}},c.Signal.prototype.constructor=c.Signal,c.SignalBinding=function(a,b,c,d,e){this._listener=b,this._isOnce=c,this.context=d,this._signal=a,this._priority=e||0},c.SignalBinding.prototype={active:!0,params:null,execute:function(a){var b,c;return this.active&&this._listener&&(c=this.params?this.params.concat(a):a,b=this._listener.apply(this.context,c),this._isOnce&&this.detach()),b},detach:function(){return this.isBound()?this._signal.remove(this._listener,this.context):null},isBound:function(){return!!this._signal&&!!this._listener},isOnce:function(){return this._isOnce},getListener:function(){return this._listener},getSignal:function(){return this._signal},_destroy:function(){delete this._signal,delete this._listener,delete this.context},toString:function(){return"[Phaser.SignalBinding isOnce:"+this._isOnce+", isBound:"+this.isBound()+", active:"+this.active+"]"}},c.SignalBinding.prototype.constructor=c.SignalBinding,c.Filter=function(a,b,d){this.game=a,this.type=c.WEBGL_FILTER,this.passes=[this],this.dirty=!0,this.padding=0,this.uniforms={time:{type:"1f",value:0},resolution:{type:"2f",value:{x:256,y:256}},mouse:{type:"2f",value:{x:0,y:0}}},this.fragmentSrc=d||[]},c.Filter.prototype={init:function(){},setResolution:function(a,b){this.uniforms.resolution.value.x=a,this.uniforms.resolution.value.y=b},update:function(a){"undefined"!=typeof a&&(a.x>0&&(this.uniforms.mouse.x=a.x.toFixed(2)),a.y>0&&(this.uniforms.mouse.y=a.y.toFixed(2))),this.uniforms.time.value=this.game.time.totalElapsedSeconds()},destroy:function(){this.game=null}},c.Filter.prototype.constructor=c.Filter,Object.defineProperty(c.Filter.prototype,"width",{get:function(){return this.uniforms.resolution.value.x},set:function(a){this.uniforms.resolution.value.x=a}}),Object.defineProperty(c.Filter.prototype,"height",{get:function(){return this.uniforms.resolution.value.y},set:function(a){this.uniforms.resolution.value.y=a}}),c.Plugin=function(a,b){"undefined"==typeof b&&(b=null),this.game=a,this.parent=b,this.active=!1,this.visible=!1,this.hasPreUpdate=!1,this.hasUpdate=!1,this.hasPostUpdate=!1,this.hasRender=!1,this.hasPostRender=!1},c.Plugin.prototype={preUpdate:function(){},update:function(){},render:function(){},postRender:function(){},destroy:function(){this.game=null,this.parent=null,this.active=!1,this.visible=!1}},c.Plugin.prototype.constructor=c.Plugin,c.PluginManager=function(a,b){this.game=a,this._parent=b,this.plugins=[],this._pluginsLength=0},c.PluginManager.prototype={add:function(a){var b=!1;return"function"==typeof a?a=new a(this.game,this._parent):(a.game=this.game,a.parent=this._parent),"function"==typeof a.preUpdate&&(a.hasPreUpdate=!0,b=!0),"function"==typeof a.update&&(a.hasUpdate=!0,b=!0),"function"==typeof a.postUpdate&&(a.hasPostUpdate=!0,b=!0),"function"==typeof a.render&&(a.hasRender=!0,b=!0),"function"==typeof a.postRender&&(a.hasPostRender=!0,b=!0),b?((a.hasPreUpdate||a.hasUpdate||a.hasPostUpdate)&&(a.active=!0),(a.hasRender||a.hasPostRender)&&(a.visible=!0),this._pluginsLength=this.plugins.push(a),"function"==typeof a.init&&a.init(),a):null},remove:function(a){if(0!==this._pluginsLength)for(this._p=0;this._pthis._nextOffsetCheck&&(c.Canvas.getOffset(this.canvas,this.offset),this._nextOffsetCheck=this.game.time.now+this.checkOffsetInterval)},visibilityChange:function(a){this.disableVisibilityChange||(this.game.paused=this.game.paused!==!1||"pagehide"!=a.type&&"blur"!=a.type&&document.hidden!==!0&&document.webkitHidden!==!0?!1:!0)}},c.Stage.prototype.constructor=c.Stage,Object.defineProperty(c.Stage.prototype,"backgroundColor",{get:function(){return this._backgroundColor},set:function(a){this._backgroundColor=a,this.game.transparent===!1&&(this.game.renderType==c.CANVAS?this.game.canvas.style.backgroundColor=a:("string"==typeof a&&(a=c.Color.hexToRGB(a)),this._stage.setBackgroundColor(a)))}}),c.Group=function(a,d,e,f){this.game=a,"undefined"==typeof d&&(d=a.world),this.name=e||"group","undefined"==typeof f&&(f=!1),f?this._container=this.game.stage._stage:(this._container=new b.DisplayObjectContainer,this._container.name=this.name,d?d instanceof c.Group?d._container.addChild(this._container):(d.addChild(this._container),d.updateTransform()):(this.game.stage._stage.addChild(this._container),this.game.stage._stage.updateTransform())),this.type=c.GROUP,this.alive=!0,this.exists=!0,this.group=null,this._container.scale=new c.Point(1,1),this.scale=this._container.scale,this.pivot=this._container.pivot,this.cursor=null},c.Group.RETURN_NONE=0,c.Group.RETURN_TOTAL=1,c.Group.RETURN_CHILD=2,c.Group.SORT_ASCENDING=-1,c.Group.SORT_DESCENDING=1,c.Group.prototype={add:function(a){return a.group!==this&&(a.type&&a.type===c.GROUP?(a.group=this,this._container.addChild(a._container),a._container.updateTransform()):(a.group=this,this._container.addChild(a),a.updateTransform(),a.events&&a.events.onAddedToGroup.dispatch(a,this)),null===this.cursor&&(this.cursor=a)),a},addAt:function(a,b){return a.group!==this&&(a.type&&a.type===c.GROUP?(a.group=this,this._container.addChildAt(a._container,b),a._container.updateTransform()):(a.group=this,this._container.addChildAt(a,b),a.updateTransform(),a.events&&a.events.onAddedToGroup.dispatch(a,this)),null===this.cursor&&(this.cursor=a)),a},getAt:function(a){return this._container.getChildAt(a)},create:function(a,b,d,e,f){"undefined"==typeof f&&(f=!0);var g=new c.Sprite(this.game,a,b,d,e);return g.group=this,g.exists=f,g.visible=f,g.alive=f,this._container.addChild(g),g.updateTransform(),g.events&&g.events.onAddedToGroup.dispatch(g,this),null===this.cursor&&(this.cursor=g),g},createMultiple:function(a,b,d,e){"undefined"==typeof e&&(e=!1);for(var f=0;a>f;f++){var g=new c.Sprite(this.game,0,0,b,d);g.group=this,g.exists=e,g.visible=e,g.alive=e,this._container.addChild(g),g.updateTransform(),g.events&&g.events.onAddedToGroup.dispatch(g,this),null===this.cursor&&(this.cursor=g)}},next:function(){this.cursor&&(this.cursor=this.cursor==this._container.last?this._container._iNext:this.cursor._iNext)},previous:function(){this.cursor&&(this.cursor=this.cursor==this._container._iNext?this._container.last:this.cursor._iPrev)},childTest:function(a,b){var c=a+" next: ";c+=b._iNext?b._iNext.name:"-null-",c=c+" "+a+" prev: ",c+=b._iPrev?b._iPrev.name:"-null-",console.log(c)},swapIndex:function(a,b){var c=this.getAt(a),d=this.getAt(b);this.swap(c,d)},swap:function(a,b){if(a===b||!a.parent||!b.parent||a.group!==this||b.group!==this)return!1;var c=a._iPrev,d=a._iNext,e=b._iPrev,f=b._iNext,g=this._container.last._iNext,h=this.game.stage._stage;do h!==a&&h!==b&&(h.first===a?h.first=b:h.first===b&&(h.first=a),h.last===a?h.last=b:h.last===b&&(h.last=a)),h=h._iNext;while(h!=g);return a._iNext==b?(a._iNext=f,a._iPrev=b,b._iNext=a,b._iPrev=c,c&&(c._iNext=b),f&&(f._iPrev=a),a.__renderGroup&&a.__renderGroup.updateTexture(a),b.__renderGroup&&b.__renderGroup.updateTexture(b),!0):b._iNext==a?(a._iNext=b,a._iPrev=e,b._iNext=d,b._iPrev=a,e&&(e._iNext=a),d&&(d._iPrev=b),a.__renderGroup&&a.__renderGroup.updateTexture(a),b.__renderGroup&&b.__renderGroup.updateTexture(b),!0):(a._iNext=f,a._iPrev=e,b._iNext=d,b._iPrev=c,c&&(c._iNext=b),d&&(d._iPrev=b),e&&(e._iNext=a),f&&(f._iPrev=a),a.__renderGroup&&a.__renderGroup.updateTexture(a),b.__renderGroup&&b.__renderGroup.updateTexture(b),!0)},bringToTop:function(a){return a.group===this&&(this.remove(a),this.add(a)),a},getIndex:function(a){return this._container.children.indexOf(a)},replace:function(a,b){if(this._container.first._iNext){var c=this.getIndex(a);-1!=c&&(void 0!==b.parent&&(b.events.onRemovedFromGroup.dispatch(b,this),b.parent.removeChild(b)),this._container.removeChild(a),this._container.addChildAt(b,c),b.events.onAddedToGroup.dispatch(b,this),b.updateTransform(),this.cursor==a&&(this.cursor=this._container._iNext))}},setProperty:function(a,b,c,d){d=d||0;var e=b.length;1==e?0===d?a[b[0]]=c:1==d?a[b[0]]+=c:2==d?a[b[0]]-=c:3==d?a[b[0]]*=c:4==d&&(a[b[0]]/=c):2==e?0===d?a[b[0]][b[1]]=c:1==d?a[b[0]][b[1]]+=c:2==d?a[b[0]][b[1]]-=c:3==d?a[b[0]][b[1]]*=c:4==d&&(a[b[0]][b[1]]/=c):3==e?0===d?a[b[0]][b[1]][b[2]]=c:1==d?a[b[0]][b[1]][b[2]]+=c:2==d?a[b[0]][b[1]][b[2]]-=c:3==d?a[b[0]][b[1]][b[2]]*=c:4==d&&(a[b[0]][b[1]][b[2]]/=c):4==e&&(0===d?a[b[0]][b[1]][b[2]][b[3]]=c:1==d?a[b[0]][b[1]][b[2]][b[3]]+=c:2==d?a[b[0]][b[1]][b[2]][b[3]]-=c:3==d?a[b[0]][b[1]][b[2]][b[3]]*=c:4==d&&(a[b[0]][b[1]][b[2]][b[3]]/=c))},set:function(a,b,c,d,e,f){b=b.split("."),"undefined"==typeof d&&(d=!1),"undefined"==typeof e&&(e=!1),(d===!1||d&&a.alive)&&(e===!1||e&&a.visible)&&this.setProperty(a,b,c,f)},setAll:function(a,b,c,d,e){if(a=a.split("."),"undefined"==typeof c&&(c=!1),"undefined"==typeof d&&(d=!1),e=e||0,this._container.children.length>0&&this._container.first._iNext){var f=this._container.first._iNext;do(c===!1||c&&f.alive)&&(d===!1||d&&f.visible)&&this.setProperty(f,a,b,e),f=f._iNext;while(f!=this._container.last._iNext)}},addAll:function(a,b,c,d){this.setAll(a,b,c,d,1)},subAll:function(a,b,c,d){this.setAll(a,b,c,d,2)},multiplyAll:function(a,b,c,d){this.setAll(a,b,c,d,3)},divideAll:function(a,b,c,d){this.setAll(a,b,c,d,4)},callAllExists:function(a,b){var c=Array.prototype.splice.call(arguments,2);if(this._container.children.length>0&&this._container.first._iNext){var d=this._container.first._iNext;do d.exists==b&&d[a]&&d[a].apply(d,c),d=d._iNext;while(d!=this._container.last._iNext)}},callbackFromArray:function(a,b,c){if(1==c){if(a[b[0]])return a[b[0]]}else if(2==c){if(a[b[0]][b[1]])return a[b[0]][b[1]]}else if(3==c){if(a[b[0]][b[1]][b[2]])return a[b[0]][b[1]][b[2]]}else if(4==c){if(a[b[0]][b[1]][b[2]][b[3]])return a[b[0]][b[1]][b[2]][b[3]]}else if(a[b])return a[b];return!1},callAll:function(a,b){if("undefined"!=typeof a){a=a.split(".");var c=a.length;if("undefined"==typeof b)b=null;else if("string"==typeof b){b=b.split(".");var d=b.length}var e=Array.prototype.splice.call(arguments,2),f=null,g=null;if(this._container.children.length>0&&this._container.first._iNext){var h=this._container.first._iNext;do f=this.callbackFromArray(h,a,c),b&&f?(g=this.callbackFromArray(h,b,d),f&&f.apply(g,e)):f&&f.apply(h,e),h=h._iNext;while(h!=this._container.last._iNext)}}},forEach:function(a,b,c){"undefined"==typeof c&&(c=!1);var d=Array.prototype.splice.call(arguments,3);if(d.unshift(null),this._container.children.length>0&&this._container.first._iNext){var e=this._container.first._iNext;do(c===!1||c&&e.exists)&&(d[0]=e,a.apply(b,d)),e=e._iNext;while(e!=this._container.last._iNext)}},forEachExists:function(a,b){var d=Array.prototype.splice.call(arguments,2);d.unshift(null),this.iterate("exists",!0,c.Group.RETURN_TOTAL,a,b,d)},forEachAlive:function(a,b){var d=Array.prototype.splice.call(arguments,2);d.unshift(null),this.iterate("alive",!0,c.Group.RETURN_TOTAL,a,b,d)},forEachDead:function(a,b){var d=Array.prototype.splice.call(arguments,2);d.unshift(null),this.iterate("alive",!1,c.Group.RETURN_TOTAL,a,b,d)},sort:function(a,b){"undefined"==typeof a&&(a="y"),"undefined"==typeof b&&(b=c.Group.SORT_ASCENDING);var d,e;do{d=!1;for(var f=0,g=this._container.children.length-1;g>f;f++)b==c.Group.SORT_ASCENDING?this._container.children[f][a]>this._container.children[f+1][a]&&(this.swap(this.getAt(f),this.getAt(f+1)),e=this._container.children[f],this._container.children[f]=this._container.children[f+1],this._container.children[f+1]=e,d=!0):this._container.children[f][a]0&&this._container.first._iNext){var i=this._container.first._iNext;do{if(i[a]===b&&(h++,e&&(g[0]=i,e.apply(f,g)),d===c.Group.RETURN_CHILD))return i;i=i._iNext}while(i!=this._container.last._iNext)}return d===c.Group.RETURN_TOTAL?h:d===c.Group.RETURN_CHILD?null:void 0},getFirstExists:function(a){return"boolean"!=typeof a&&(a=!0),this.iterate("exists",a,c.Group.RETURN_CHILD)},getFirstAlive:function(){return this.iterate("alive",!0,c.Group.RETURN_CHILD)},getFirstDead:function(){return this.iterate("alive",!1,c.Group.RETURN_CHILD)},countLiving:function(){return this.iterate("alive",!0,c.Group.RETURN_TOTAL)},countDead:function(){return this.iterate("alive",!1,c.Group.RETURN_TOTAL)},getRandom:function(a,b){return 0===this._container.children.length?null:(a=a||0,b=b||this._container.children.length,this.game.math.getRandom(this._container.children,a,b))},remove:function(a){return a.group!==this?!1:(a.events&&a.events.onRemovedFromGroup.dispatch(a,this),a.parent===this._container&&this._container.removeChild(a),this.cursor==a&&(this.cursor=this._container._iNext?this._container._iNext:null),a.group=null,!0)},removeAll:function(){if(0!==this._container.children.length){do this._container.children[0].events&&this._container.children[0].events.onRemovedFromGroup.dispatch(this._container.children[0],this),this._container.removeChild(this._container.children[0]);while(this._container.children.length>0);this.cursor=null}},removeBetween:function(a,b){if(0!==this._container.children.length){if(a>b||0>a||b>this._container.children.length)return!1;for(var c=a;b>c;c++){var d=this._container.children[c];d.events.onRemovedFromGroup.dispatch(d,this),this._container.removeChild(d),this.cursor==d&&(this.cursor=this._container._iNext?this._container._iNext:null)}}},destroy:function(a){if("undefined"==typeof a&&(a=!1),a){if(this._container.children.length>0)do this._container.children[0].group&&this._container.children[0].destroy();while(this._container.children.length>0)}else this.removeAll();this._container.parent.removeChild(this._container),this._container=null,this.game=null,this.exists=!1,this.cursor=null},validate:function(){var a=this.game.stage._stage.last._iNext,b=this.game.stage._stage,c=null,d=null,e=0;do{if(e>0){if(b!==c)return console.log("check next fail"),!1;if(b._iPrev!==d)return console.log("check previous fail"),!1}c=b._iNext,d=b,b=b._iNext,e++}while(b!=a);return!0}},c.Group.prototype.constructor=c.Group,Object.defineProperty(c.Group.prototype,"total",{get:function(){return this._container?this.iterate("exists",!0,c.Group.RETURN_TOTAL):0}}),Object.defineProperty(c.Group.prototype,"length",{get:function(){return this._container?this._container.children.length:0}}),Object.defineProperty(c.Group.prototype,"x",{get:function(){return this._container.position.x},set:function(a){this._container.position.x=a}}),Object.defineProperty(c.Group.prototype,"y",{get:function(){return this._container.position.y},set:function(a){this._container.position.y=a}}),Object.defineProperty(c.Group.prototype,"angle",{get:function(){return c.Math.radToDeg(this._container.rotation)},set:function(a){this._container.rotation=c.Math.degToRad(a)}}),Object.defineProperty(c.Group.prototype,"rotation",{get:function(){return this._container.rotation},set:function(a){this._container.rotation=a}}),Object.defineProperty(c.Group.prototype,"visible",{get:function(){return this._container.visible},set:function(a){this._container.visible=a}}),Object.defineProperty(c.Group.prototype,"alpha",{get:function(){return this._container.alpha},set:function(a){this._container.alpha=a}}),c.World=function(a){c.Group.call(this,a,null,"__world",!1),this.bounds=new c.Rectangle(0,0,a.width,a.height),this.camera=null,this.currentRenderOrderID=0},c.World.prototype=Object.create(c.Group.prototype),c.World.prototype.constructor=c.World,c.World.prototype.boot=function(){this.camera=new c.Camera(this.game,0,0,0,this.game.width,this.game.height),this.camera.displayObject=this._container,this.game.camera=this.camera},c.World.prototype.preUpdate=function(){if(this.game.stage._stage.first._iNext){var a=this.game.stage._stage.first._iNext;do a=a.preUpdate&&!a.preUpdate()?a.last._iNext:a._iNext;while(a!=this.game.stage._stage.last._iNext)}},c.World.prototype.update=function(){if(this.currentRenderOrderID=0,this.game.stage._stage.first._iNext){var a=this.game.stage._stage.first._iNext;do a=a.update&&!a.update()?a.last._iNext:a._iNext;while(a!=this.game.stage._stage.last._iNext)}},c.World.prototype.postUpdate=function(){if(this.camera.target&&this.camera.target.postUpdate){if(this.camera.target.postUpdate(),this.camera.update(),this.game.stage._stage.first._iNext){var a=this.game.stage._stage.first._iNext;do a.postUpdate&&a!==this.camera.target&&a.postUpdate(),a=a._iNext;while(a!=this.game.stage._stage.last._iNext)}}else if(this.camera.update(),this.game.stage._stage.first._iNext){var a=this.game.stage._stage.first._iNext;do a.postUpdate&&a.postUpdate(),a=a._iNext;while(a!=this.game.stage._stage.last._iNext)}},c.World.prototype.setBounds=function(a,b,c,d){c0;b--)null===this["pointer"+b]&&(a=b);return 0===a?(console.warn("You can only have 10 Pointer objects"),null):(this["pointer"+a]=new c.Pointer(this.game,a),this["pointer"+a])},update:function(){return this.pollRate>0&&this._pollCounter=b;b++)this["pointer"+b]&&this["pointer"+b].reset();this.currentPointers=0,"none"!==this.game.canvas.style.cursor&&(this.game.canvas.style.cursor="default"),a===!0&&(this.onDown.dispose(),this.onUp.dispose(),this.onTap.dispose(),this.onHold.dispose(),this.onDown=new c.Signal,this.onUp=new c.Signal,this.onTap=new c.Signal,this.onHold=new c.Signal,this.interactiveItems.callAll("reset")),this._pollCounter=0}},resetSpeed:function(a,b){this._oldPosition.setTo(a,b),this.speed.setTo(0,0)},startPointer:function(a){if(this.maxPointers<10&&this.totalActivePointers==this.maxPointers)return null;if(this.pointer1.active===!1)return this.pointer1.start(a);if(this.pointer2.active===!1)return this.pointer2.start(a);for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].active===!1)return this["pointer"+b].start(a);return null},updatePointer:function(a){if(this.pointer1.active&&this.pointer1.identifier==a.identifier)return this.pointer1.move(a);if(this.pointer2.active&&this.pointer2.identifier==a.identifier)return this.pointer2.move(a);for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].active&&this["pointer"+b].identifier==a.identifier)return this["pointer"+b].move(a);return null},stopPointer:function(a){if(this.pointer1.active&&this.pointer1.identifier==a.identifier)return this.pointer1.stop(a);if(this.pointer2.active&&this.pointer2.identifier==a.identifier)return this.pointer2.stop(a);for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].active&&this["pointer"+b].identifier==a.identifier)return this["pointer"+b].stop(a);return null},getPointer:function(a){if(a=a||!1,this.pointer1.active==a)return this.pointer1;if(this.pointer2.active==a)return this.pointer2;for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].active==a)return this["pointer"+b];return null},getPointerFromIdentifier:function(a){if(this.pointer1.identifier==a)return this.pointer1;if(this.pointer2.identifier==a)return this.pointer2;for(var b=3;10>=b;b++)if(this["pointer"+b]&&this["pointer"+b].identifier==a)return this["pointer"+b];return null}},c.Input.prototype.constructor=c.Input,Object.defineProperty(c.Input.prototype,"x",{get:function(){return this._x},set:function(a){this._x=Math.floor(a)}}),Object.defineProperty(c.Input.prototype,"y",{get:function(){return this._y},set:function(a){this._y=Math.floor(a)}}),Object.defineProperty(c.Input.prototype,"pollLocked",{get:function(){return this.pollRate>0&&this._pollCounter=a;a++)this["pointer"+a]&&this["pointer"+a].active&&this.currentPointers++;return this.currentPointers}}),Object.defineProperty(c.Input.prototype,"worldX",{get:function(){return this.game.camera.view.x+this.x}}),Object.defineProperty(c.Input.prototype,"worldY",{get:function(){return this.game.camera.view.y+this.y}}),c.Key=function(a,b){this.game=a,this.isDown=!1,this.isUp=!1,this.altKey=!1,this.ctrlKey=!1,this.shiftKey=!1,this.timeDown=0,this.duration=0,this.timeUp=0,this.repeats=0,this.keyCode=b,this.onDown=new c.Signal,this.onUp=new c.Signal},c.Key.prototype={processKeyDown:function(a){this.altKey=a.altKey,this.ctrlKey=a.ctrlKey,this.shiftKey=a.shiftKey,this.isDown?(this.duration=a.timeStamp-this.timeDown,this.repeats++):(this.isDown=!0,this.isUp=!1,this.timeDown=a.timeStamp,this.duration=0,this.repeats=0,this.onDown.dispatch(this))},processKeyUp:function(a){this.isDown=!1,this.isUp=!0,this.timeUp=a.timeStamp,this.onUp.dispatch(this)},justPressed:function(a){return"undefined"==typeof a&&(a=250),this.isDown&&this.duration=this.game.input.holdRate&&((this.game.input.multiInputOverride==c.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==c.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==c.Input.TOUCH_OVERRIDES_MOUSE&&0===this.game.input.currentPointers)&&this.game.input.onHold.dispatch(this),this._holdSent=!0),this.game.input.recordPointerHistory&&this.game.time.now>=this._nextDrop&&(this._nextDrop=this.game.time.now+this.game.input.recordRate,this._history.push({x:this.position.x,y:this.position.y}),this._history.length>this.game.input.recordLimit&&this._history.shift()))},move:function(a){if(!this.game.input.pollLocked){if("undefined"!=typeof a.button&&(this.button=a.button),this.clientX=a.clientX,this.clientY=a.clientY,this.pageX=a.pageX,this.pageY=a.pageY,this.screenX=a.screenX,this.screenY=a.screenY,this.x=(this.pageX-this.game.stage.offset.x)*this.game.input.scale.x,this.y=(this.pageY-this.game.stage.offset.y)*this.game.input.scale.y,this.position.setTo(this.x,this.y),this.circle.x=this.x,this.circle.y=this.y,(this.game.input.multiInputOverride==c.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==c.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==c.Input.TOUCH_OVERRIDES_MOUSE&&0===this.game.input.currentPointers)&&(this.game.input.activePointer=this,this.game.input.x=this.x,this.game.input.y=this.y,this.game.input.position.setTo(this.game.input.x,this.game.input.y),this.game.input.circle.x=this.game.input.x,this.game.input.circle.y=this.game.input.y),this.game.paused)return this;if(this.game.input.moveCallback&&this.game.input.moveCallback.call(this.game.input.moveCallbackContext,this,this.x,this.y),null!==this.targetObject&&this.targetObject.isDragged===!0)return this.targetObject.update(this)===!1&&(this.targetObject=null),this;if(this._highestRenderOrderID=-1,this._highestRenderObject=null,this._highestInputPriorityID=-1,this.game.input.interactiveItems.total>0){var b=this.game.input.interactiveItems.next;do(b.pixelPerfect||b.priorityID>this._highestInputPriorityID||b.priorityID==this._highestInputPriorityID&&b.sprite.renderOrderID>this._highestRenderOrderID)&&b.checkPointerOver(this)&&(this._highestRenderOrderID=b.sprite.renderOrderID,this._highestInputPriorityID=b.priorityID,this._highestRenderObject=b),b=b.next;while(null!=b)}return null==this._highestRenderObject?this.targetObject&&(this.targetObject._pointerOutHandler(this),this.targetObject=null):null==this.targetObject?(this.targetObject=this._highestRenderObject,this._highestRenderObject._pointerOverHandler(this)):this.targetObject==this._highestRenderObject?this._highestRenderObject.update(this)===!1&&(this.targetObject=null):(this.targetObject._pointerOutHandler(this),this.targetObject=this._highestRenderObject,this.targetObject._pointerOverHandler(this)),this}},leave:function(a){this.withinGame=!1,this.move(a)},stop:function(a){if(this._stateReset)return a.preventDefault(),void 0;if(this.timeUp=this.game.time.now,(this.game.input.multiInputOverride==c.Input.MOUSE_OVERRIDES_TOUCH||this.game.input.multiInputOverride==c.Input.MOUSE_TOUCH_COMBINE||this.game.input.multiInputOverride==c.Input.TOUCH_OVERRIDES_MOUSE&&0===this.game.input.currentPointers)&&(this.game.input.onUp.dispatch(this,a),this.duration>=0&&this.duration<=this.game.input.tapRate&&(this.timeUp-this.previousTapTime0&&(this.active=!1),this.withinGame=!1,this.isDown=!1,this.isUp=!0,this.isMouse===!1&&this.game.input.currentPointers--,this.game.input.interactiveItems.total>0){var b=this.game.input.interactiveItems.next;do b&&b._releasedHandler(this),b=b.next;while(null!=b)}return this.targetObject&&this.targetObject._releasedHandler(this),this.targetObject=null,this},justPressed:function(a){return a=a||this.game.input.justPressedRate,this.isDown===!0&&this.timeDown+a>this.game.time.now},justReleased:function(a){return a=a||this.game.input.justReleasedRate,this.isUp===!0&&this.timeUp+a>this.game.time.now},reset:function(){this.isMouse===!1&&(this.active=!1),this.identifier=null,this.isDown=!1,this.isUp=!0,this.totalTouches=0,this._holdSent=!1,this._history.length=0,this._stateReset=!0,this.targetObject&&this.targetObject._releasedHandler(this),this.targetObject=null}},c.Pointer.prototype.constructor=c.Pointer,Object.defineProperty(c.Pointer.prototype,"duration",{get:function(){return this.isUp?-1:this.game.time.now-this.timeDown}}),Object.defineProperty(c.Pointer.prototype,"worldX",{get:function(){return this.game.world.camera.x+this.x}}),Object.defineProperty(c.Pointer.prototype,"worldY",{get:function(){return this.game.world.camera.y+this.y}}),c.Touch=function(a){this.game=a,this.disabled=!1,this.callbackContext=this.game,this.touchStartCallback=null,this.touchMoveCallback=null,this.touchEndCallback=null,this.touchEnterCallback=null,this.touchLeaveCallback=null,this.touchCancelCallback=null,this.preventDefault=!0,this.event=null,this._onTouchStart=null,this._onTouchMove=null,this._onTouchEnd=null,this._onTouchEnter=null,this._onTouchLeave=null,this._onTouchCancel=null,this._onTouchMove=null},c.Touch.prototype={start:function(){var a=this;this.game.device.touch&&(this._onTouchStart=function(b){return a.onTouchStart(b)},this._onTouchMove=function(b){return a.onTouchMove(b)},this._onTouchEnd=function(b){return a.onTouchEnd(b)},this._onTouchEnter=function(b){return a.onTouchEnter(b)},this._onTouchLeave=function(b){return a.onTouchLeave(b)},this._onTouchCancel=function(b){return a.onTouchCancel(b)},this.game.renderer.view.addEventListener("touchstart",this._onTouchStart,!1),this.game.renderer.view.addEventListener("touchmove",this._onTouchMove,!1),this.game.renderer.view.addEventListener("touchend",this._onTouchEnd,!1),this.game.renderer.view.addEventListener("touchenter",this._onTouchEnter,!1),this.game.renderer.view.addEventListener("touchleave",this._onTouchLeave,!1),this.game.renderer.view.addEventListener("touchcancel",this._onTouchCancel,!1))},consumeDocumentTouches:function(){this._documentTouchMove=function(a){a.preventDefault()},document.addEventListener("touchmove",this._documentTouchMove,!1)},onTouchStart:function(a){if(this.event=a,this.touchStartCallback&&this.touchStartCallback.call(this.callbackContext,a),!this.game.input.disabled&&!this.disabled){this.preventDefault&&a.preventDefault();for(var b=0;bd;d++)this._pointerData[d]={id:d,x:0,y:0,isDown:!1,isUp:!1,isOver:!1,isOut:!1,timeOver:0,timeOut:0,timeDown:0,timeUp:0,downDuration:0,isDragged:!1};this.snapOffset=new c.Point,this.enabled=!0,this.sprite.events&&null==this.sprite.events.onInputOver&&(this.sprite.events.onInputOver=new c.Signal,this.sprite.events.onInputOut=new c.Signal,this.sprite.events.onInputDown=new c.Signal,this.sprite.events.onInputUp=new c.Signal,this.sprite.events.onDragStart=new c.Signal,this.sprite.events.onDragStop=new c.Signal)}return this.sprite},reset:function(){this.enabled=!1;for(var a=0;10>a;a++)this._pointerData[a]={id:a,x:0,y:0,isDown:!1,isUp:!1,isOver:!1,isOut:!1,timeOver:0,timeOut:0,timeDown:0,timeUp:0,downDuration:0,isDragged:!1}},stop:function(){this.enabled!==!1&&(this.enabled=!1,this.game.input.interactiveItems.remove(this))},destroy:function(){this.enabled&&(this.enabled=!1,this.game.input.interactiveItems.remove(this),this.stop(),this.sprite=null)},pointerX:function(a){return a=a||0,this._pointerData[a].x},pointerY:function(a){return a=a||0,this._pointerData[a].y},pointerDown:function(a){return a=a||0,this._pointerData[a].isDown},pointerUp:function(a){return a=a||0,this._pointerData[a].isUp},pointerTimeDown:function(a){return a=a||0,this._pointerData[a].timeDown},pointerTimeUp:function(a){return a=a||0,this._pointerData[a].timeUp},pointerOver:function(a){if(this.enabled){if("undefined"!=typeof a)return this._pointerData[a].isOver;for(var b=0;10>b;b++)if(this._pointerData[b].isOver)return!0}return!1},pointerOut:function(a){if(this.enabled){if("undefined"!=typeof a)return this._pointerData[a].isOut;for(var b=0;10>b;b++)if(this._pointerData[b].isOut)return!0}return!1},pointerTimeOver:function(a){return a=a||0,this._pointerData[a].timeOver},pointerTimeOut:function(a){return a=a||0,this._pointerData[a].timeOut},pointerDragged:function(a){return a=a||0,this._pointerData[a].isDragged},checkPointerOver:function(a){return this.enabled===!1||this.sprite.visible===!1||this.sprite.group&&this.sprite.group.visible===!1?!1:(this.sprite.getLocalUnmodifiedPosition(this._tempPoint,a.x,a.y),this._tempPoint.x>=0&&this._tempPoint.x<=this.sprite.currentFrame.width&&this._tempPoint.y>=0&&this._tempPoint.y<=this.sprite.currentFrame.height?this.pixelPerfect?this.checkPixel(this._tempPoint.x,this._tempPoint.y):!0:void 0)},checkPixel:function(a,b){if(this.sprite.texture.baseTexture.source){this.game.input.hitContext.clearRect(0,0,1,1),a+=this.sprite.texture.frame.x,b+=this.sprite.texture.frame.y,this.game.input.hitContext.drawImage(this.sprite.texture.baseTexture.source,a,b,1,1,0,0,1,1);var c=this.game.input.hitContext.getImageData(0,0,1,1);if(c.data[3]>=this.pixelPerfectAlpha)return!0}return!1},update:function(a){return this.enabled===!1||this.sprite.visible===!1||this.sprite.group&&this.sprite.group.visible===!1?(this._pointerOutHandler(a),!1):this.draggable&&this._draggedPointerID==a.id?this.updateDrag(a):this._pointerData[a.id].isOver===!0?this.checkPointerOver(a)?(this._pointerData[a.id].x=a.x-this.sprite.x,this._pointerData[a.id].y=a.y-this.sprite.y,!0):(this._pointerOutHandler(a),!1):void 0},_pointerOverHandler:function(a){this._pointerData[a.id].isOver===!1&&(this._pointerData[a.id].isOver=!0,this._pointerData[a.id].isOut=!1,this._pointerData[a.id].timeOver=this.game.time.now,this._pointerData[a.id].x=a.x-this.sprite.x,this._pointerData[a.id].y=a.y-this.sprite.y,this.useHandCursor&&this._pointerData[a.id].isDragged===!1&&(this.game.canvas.style.cursor="pointer"),this.sprite.events.onInputOver.dispatch(this.sprite,a))},_pointerOutHandler:function(a){this._pointerData[a.id].isOver=!1,this._pointerData[a.id].isOut=!0,this._pointerData[a.id].timeOut=this.game.time.now,this.useHandCursor&&this._pointerData[a.id].isDragged===!1&&(this.game.canvas.style.cursor="default"),this.sprite&&this.sprite.events&&this.sprite.events.onInputOut.dispatch(this.sprite,a)},_touchedHandler:function(a){return this._pointerData[a.id].isDown===!1&&this._pointerData[a.id].isOver===!0&&(this._pointerData[a.id].isDown=!0,this._pointerData[a.id].isUp=!1,this._pointerData[a.id].timeDown=this.game.time.now,this.sprite.events.onInputDown.dispatch(this.sprite,a),this.draggable&&this.isDragged===!1&&this.startDrag(a),this.bringToTop&&this.sprite.bringToTop()),this.consumePointerEvent},_releasedHandler:function(a){this._pointerData[a.id].isDown&&a.isUp&&(this._pointerData[a.id].isDown=!1,this._pointerData[a.id].isUp=!0,this._pointerData[a.id].timeUp=this.game.time.now,this._pointerData[a.id].downDuration=this._pointerData[a.id].timeUp-this._pointerData[a.id].timeDown,this.checkPointerOver(a)?this.sprite.events.onInputUp.dispatch(this.sprite,a,!0):(this.sprite.events.onInputUp.dispatch(this.sprite,a,!1),this.useHandCursor&&(this.game.canvas.style.cursor="default")),this.draggable&&this.isDragged&&this._draggedPointerID==a.id&&this.stopDrag(a))},updateDrag:function(a){return a.isUp?(this.stopDrag(a),!1):(this.sprite.fixedToCamera?(this.allowHorizontalDrag&&(this.sprite.cameraOffset.x=a.x+this._dragPoint.x+this.dragOffset.x),this.allowVerticalDrag&&(this.sprite.cameraOffset.y=a.y+this._dragPoint.y+this.dragOffset.y),this.boundsRect&&this.checkBoundsRect(),this.boundsSprite&&this.checkBoundsSprite(),this.snapOnDrag&&(this.sprite.cameraOffset.x=Math.round((this.sprite.cameraOffset.x-this.snapOffsetX%this.snapX)/this.snapX)*this.snapX+this.snapOffsetX%this.snapX,this.sprite.cameraOffset.y=Math.round((this.sprite.cameraOffset.y-this.snapOffsetY%this.snapY)/this.snapY)*this.snapY+this.snapOffsetY%this.snapY)):(this.allowHorizontalDrag&&(this.sprite.x=a.x+this._dragPoint.x+this.dragOffset.x),this.allowVerticalDrag&&(this.sprite.y=a.y+this._dragPoint.y+this.dragOffset.y),this.boundsRect&&this.checkBoundsRect(),this.boundsSprite&&this.checkBoundsSprite(),this.snapOnDrag&&(this.sprite.x=Math.round((this.sprite.x-this.snapOffsetX%this.snapX)/this.snapX)*this.snapX+this.snapOffsetX%this.snapX,this.sprite.y=Math.round((this.sprite.y-this.snapOffsetY%this.snapY)/this.snapY)*this.snapY+this.snapOffsetY%this.snapY)),!0)},justOver:function(a,b){return a=a||0,b=b||500,this._pointerData[a].isOver&&this.overDuration(a)a;a++)this._pointerData[a].isDragged=!1;this.draggable=!1,this.isDragged=!1,this._draggedPointerID=-1},startDrag:function(a){this.isDragged=!0,this._draggedPointerID=a.id,this._pointerData[a.id].isDragged=!0,this.sprite.fixedToCamera?this.dragFromCenter?(this.sprite.centerOn(a.x,a.y),this._dragPoint.setTo(this.sprite.cameraOffset.x-a.x,this.sprite.cameraOffset.y-a.y)):this._dragPoint.setTo(this.sprite.cameraOffset.x-a.x,this.sprite.cameraOffset.y-a.y):this.dragFromCenter?(this.sprite.centerOn(a.x,a.y),this._dragPoint.setTo(this.sprite.x-a.x,this.sprite.y-a.y)):this._dragPoint.setTo(this.sprite.x-a.x,this.sprite.y-a.y),this.updateDrag(a),this.bringToTop&&this.sprite.bringToTop(),this.sprite.events.onDragStart.dispatch(this.sprite,a)},stopDrag:function(a){this.isDragged=!1,this._draggedPointerID=-1,this._pointerData[a.id].isDragged=!1,this.snapOnRelease&&(this.sprite.fixedToCamera?(this.sprite.cameraOffset.x=Math.round((this.sprite.cameraOffset.x-this.snapOffsetX%this.snapX)/this.snapX)*this.snapX+this.snapOffsetX%this.snapX,this.sprite.cameraOffset.y=Math.round((this.sprite.cameraOffset.y-this.snapOffsetY%this.snapY)/this.snapY)*this.snapY+this.snapOffsetY%this.snapY):(this.sprite.x=Math.round((this.sprite.x-this.snapOffsetX%this.snapX)/this.snapX)*this.snapX+this.snapOffsetX%this.snapX,this.sprite.y=Math.round((this.sprite.y-this.snapOffsetY%this.snapY)/this.snapY)*this.snapY+this.snapOffsetY%this.snapY)),this.sprite.events.onDragStop.dispatch(this.sprite,a),this.sprite.events.onInputUp.dispatch(this.sprite,a),this.checkPointerOver(a)===!1&&this._pointerOutHandler(a)},setDragLock:function(a,b){"undefined"==typeof a&&(a=!0),"undefined"==typeof b&&(b=!0),this.allowHorizontalDrag=a,this.allowVerticalDrag=b},enableSnap:function(a,b,c,d){"undefined"==typeof c&&(c=!0),"undefined"==typeof d&&(d=!1),"undefined"==typeof snapOffsetX&&(snapOffsetX=0),"undefined"==typeof snapOffsetY&&(snapOffsetY=0),this.snapX=a,this.snapY=b,this.snapOffsetX=snapOffsetX,this.snapOffsetY=snapOffsetY,this.snapOnDrag=c,this.snapOnRelease=d},disableSnap:function(){this.snapOnDrag=!1,this.snapOnRelease=!1},checkBoundsRect:function(){this.sprite.fixedToCamera?(this.sprite.cameraOffset.xthis.boundsRect.right&&(this.sprite.cameraOffset.x=this.boundsRect.right-this.sprite.width),this.sprite.cameraOffset.ythis.boundsRect.bottom&&(this.sprite.cameraOffset.y=this.boundsRect.bottom-this.sprite.height)):(this.sprite.xthis.boundsRect.right&&(this.sprite.x=this.boundsRect.right-this.sprite.width),this.sprite.ythis.boundsRect.bottom&&(this.sprite.y=this.boundsRect.bottom-this.sprite.height))},checkBoundsSprite:function(){this.sprite.fixedToCamera&&this.boundsSprite.fixedToCamera?(this.sprite.cameraOffset.xthis.boundsSprite.camerOffset.x+this.boundsSprite.width&&(this.sprite.cameraOffset.x=this.boundsSprite.camerOffset.x+this.boundsSprite.width-this.sprite.width),this.sprite.cameraOffset.ythis.boundsSprite.camerOffset.y+this.boundsSprite.height&&(this.sprite.cameraOffset.y=this.boundsSprite.camerOffset.y+this.boundsSprite.height-this.sprite.height)):(this.sprite.xthis.boundsSprite.x+this.boundsSprite.width&&(this.sprite.x=this.boundsSprite.x+this.boundsSprite.width-this.sprite.width),this.sprite.ythis.boundsSprite.y+this.boundsSprite.height&&(this.sprite.y=this.boundsSprite.y+this.boundsSprite.height-this.sprite.height))}},c.InputHandler.prototype.constructor=c.InputHandler,c.Gamepad=function(a){this.game=a,this._gamepads=[new c.SinglePad(a,this),new c.SinglePad(a,this),new c.SinglePad(a,this),new c.SinglePad(a,this)],this._gamepadIndexMap={},this._rawPads=[],this._active=!1,this.disabled=!1,this._gamepadSupportAvailable=!!navigator.webkitGetGamepads||!!navigator.webkitGamepads||-1!=navigator.userAgent.indexOf("Firefox/"),this._prevRawGamepadTypes=[],this._prevTimestamps=[],this.callbackContext=this,this.onConnectCallback=null,this.onDisconnectCallback=null,this.onDownCallback=null,this.onUpCallback=null,this.onAxisCallback=null,this.onFloatCallback=null,this._ongamepadconnected=null,this._gamepaddisconnected=null},c.Gamepad.prototype={addCallbacks:function(a,b){"undefined"!=typeof b&&(this.onConnectCallback="function"==typeof b.onConnect?b.onConnect:this.onConnectCallback,this.onDisconnectCallback="function"==typeof b.onDisconnect?b.onDisconnect:this.onDisconnectCallback,this.onDownCallback="function"==typeof b.onDown?b.onDown:this.onDownCallback,this.onUpCallback="function"==typeof b.onUp?b.onUp:this.onUpCallback,this.onAxisCallback="function"==typeof b.onAxis?b.onAxis:this.onAxisCallback,this.onFloatCallback="function"==typeof b.onFloat?b.onFloat:this.onFloatCallback)},start:function(){this._active=!0;var a=this;this._ongamepadconnected=function(b){var c=b.gamepad;a._rawPads.push(c),a._gamepads[c.index].connect(c)},window.addEventListener("gamepadconnected",this._ongamepadconnected,!1),this._ongamepaddisconnected=function(b){var c=b.gamepad;for(var d in a._rawPads)a._rawPads[d].index===c.index&&a._rawPads.splice(d,1);a._gamepads[c.index].disconnect()},window.addEventListener("gamepaddisconnected",this._ongamepaddisconnected,!1) +},update:function(){this._pollGamepads();for(var a=0;a0&&e>this.deadZone||0>e&&e<-this.deadZone?this.processAxisChange({axis:d,value:e}):this.processAxisChange({axis:d,value:0})}this._prevTimestamp=this._rawPad.timestamp}},connect:function(a){var b=!this._connected;this._index=a.index,this._connected=!0,this._rawPad=a,this._rawButtons=a.buttons,this._axes=a.axes,b&&this._padParent.onConnectCallback&&this._padParent.onConnectCallback.call(this._padParent.callbackContext,this._index),b&&this.onConnectCallback&&this.onConnectCallback.call(this.callbackContext)},disconnect:function(){var a=this._connected;this._connected=!1,this._rawPad=void 0,this._rawButtons=[],this._buttons=[];var b=this._index;this._index=null,a&&this._padParent.onDisconnectCallback&&this._padParent.onDisconnectCallback.call(this._padParent.callbackContext,b),a&&this.onDisconnectCallback&&this.onDisconnectCallback.call(this.callbackContext)},processAxisChange:function(a){this.game.input.disabled||this.game.input.gamepad.disabled||this._axes[a.axis]!==a.value&&(this._axes[a.axis]=a.value,this._padParent.onAxisCallback&&this._padParent.onAxisCallback.call(this._padParent.callbackContext,a,this._index),this.onAxisCallback&&this.onAxisCallback.call(this.callbackContext,a))},processButtonDown:function(a,b){this.game.input.disabled||this.game.input.gamepad.disabled||(this._padParent.onDownCallback&&this._padParent.onDownCallback.call(this._padParent.callbackContext,a,b,this._index),this.onDownCallback&&this.onDownCallback.call(this.callbackContext,a,b),this._buttons[a]&&this._buttons[a].isDown?this._buttons[a].duration=this.game.time.now-this._buttons[a].timeDown:this._buttons[a]?(this._buttons[a].isDown=!0,this._buttons[a].timeDown=this.game.time.now,this._buttons[a].duration=0,this._buttons[a].value=b):this._buttons[a]={isDown:!0,timeDown:this.game.time.now,timeUp:0,duration:0,value:b},this._hotkeys[a]&&this._hotkeys[a].processButtonDown(b))},processButtonUp:function(a,b){this.game.input.disabled||this.game.input.gamepad.disabled||(this._padParent.onUpCallback&&this._padParent.onUpCallback.call(this._padParent.callbackContext,a,b,this._index),this.onUpCallback&&this.onUpCallback.call(this.callbackContext,a,b),this._hotkeys[a]&&this._hotkeys[a].processButtonUp(b),this._buttons[a]?(this._buttons[a].isDown=!1,this._buttons[a].timeUp=this.game.time.now,this._buttons[a].value=b):this._buttons[a]={isDown:!1,timeDown:this.game.time.now,timeUp:this.game.time.now,duration:0,value:b})},processButtonFloat:function(a,b){this.game.input.disabled||this.game.input.gamepad.disabled||(this._padParent.onFloatCallback&&this._padParent.onFloatCallback.call(this._padParent.callbackContext,a,b,this._index),this.onFloatCallback&&this.onFloatCallback.call(this.callbackContext,a,b),this._buttons[a]?this._buttons[a].value=b:this._buttons[a]={value:b},this._hotkeys[a]&&this._hotkeys[a].processButtonFloat(b))},axis:function(a){return this._axes[a]?this._axes[a]:!1},isDown:function(a){return this._buttons[a]?this._buttons[a].isDown:!1},justReleased:function(a,b){return"undefined"==typeof b&&(b=250),this._buttons[a]&&this._buttons[a].isDown===!1&&this.game.time.now-this._buttons[a].timeUp=0&&a<=this.width&&b>=0&&b<=this.height&&(this.pixels[b*this.width+a]=f<<24|e<<16|d<<8|c,this.context.putImageData(this.imageData,0,0),this._dirty=!0)},setPixel:function(a,b,c,d,e){this.setPixel32(a,b,c,d,e,255)},getPixel:function(a,b){return a>=0&&a<=this.width&&b>=0&&b<=this.height?this.data32[b*this.width+a]:void 0},getPixel32:function(a,b){return a>=0&&a<=this.width&&b>=0&&b<=this.height?this.data32[b*this.width+a]:void 0},getPixels:function(a){return this.context.getImageData(a.x,a.y,a.width,a.height)},arc:function(a,b,c,d,e,f){return"undefined"==typeof f&&(f=!1),this._dirty=!0,this.context.arc(a,b,c,d,e,f),this},arcTo:function(a,b,c,d,e){return this._dirty=!0,this.context.arcTo(a,b,c,d,e),this},beginFill:function(a){return this.fillStyle(a),this},beginLinearGradientFill:function(a,b,c,d,e,f){for(var g=this.createLinearGradient(c,d,e,f),h=0,i=a.length;i>h;h++)g.addColorStop(b[h],a[h]);return this.fillStyle(g),this},beginLinearGradientStroke:function(a,b,c,d,e,f){for(var g=this.createLinearGradient(c,d,e,f),h=0,i=a.length;i>h;h++)g.addColorStop(b[h],a[h]);return this.strokeStyle(g),this},beginRadialGradientStroke:function(a,b,c,d,e,f,g,h){for(var i=this.createRadialGradient(c,d,e,f,g,h),j=0,k=a.length;k>j;j++)i.addColorStop(b[j],a[j]);return this.strokeStyle(i),this},beginPath:function(){return this.context.beginPath(),this},beginStroke:function(a){return this.strokeStyle(a),this},bezierCurveTo:function(a,b,c,d,e,f){return this._dirty=!0,this.context.bezierCurveTo(a,b,c,d,e,f),this},circle:function(a,b,c){return this.arc(a,b,c,0,2*Math.PI),this},clearRect:function(a,b,c,d){return this._dirty=!0,this.context.clearRect(a,b,c,d),this},clip:function(){return this._dirty=!0,this.context.clip(),this},closePath:function(){return this._dirty=!0,this.context.closePath(),this},createLinearGradient:function(a,b,c,d){return this.context.createLinearGradient(a,b,c,d)},createRadialGradient:function(a,b,c,d,e,f){return this.context.createRadialGradient(a,b,c,d,e,f)},ellipse:function(a,b,c,d){var e=.5522848,f=c/2*e,g=d/2*e,h=a+c,i=b+d,j=a+c/2,k=b+d/2;return this.moveTo(a,k),this.bezierCurveTo(a,k-g,j-f,b,j,b),this.bezierCurveTo(j+f,b,h,k-g,h,k),this.bezierCurveTo(h,k+g,j+f,i,j,i),this.bezierCurveTo(j-f,i,a,k+g,a,k),this},fill:function(){return this._dirty=!0,this.context.fill(),this},fillRect:function(a,b,c,d){return this._dirty=!0,this.context.fillRect(a,b,c,d),this},fillStyle:function(a){return this.context.fillStyle=a,this},font:function(a){return this.context.font=a,this},globalAlpha:function(a){return this.context.globalAlpha=a,this},globalCompositeOperation:function(a){return this.context.globalCompositeOperation=a,this},lineCap:function(a){return this.context.lineCap=a,this},lineDashOffset:function(a){return this.context.lineDashOffset=a,this},lineJoin:function(a){return this.context.lineJoin=a,this},lineWidth:function(a){return this.context.lineWidth=a,this},miterLimit:function(a){return this.context.miterLimit=a,this},lineTo:function(a,b){return this._dirty=!0,this.context.lineTo(a,b),this},moveTo:function(a,b){return this.context.moveTo(a,b),this},quadraticCurveTo:function(a,b,c,d){return this._dirty=!0,this.context.quadraticCurveTo(a,b,c,d),this},rect:function(a,b,c,d){return this._dirty=!0,this.context.rect(a,b,c,d),this},restore:function(){return this._dirty=!0,this.context.restore(),this},rotate:function(a){return this._dirty=!0,this.context.rotate(a),this},setStrokeStyle:function(a,b,c,d,e){return"undefined"==typeof a&&(a=1),"undefined"==typeof b&&(b="butt"),"undefined"==typeof c&&(c="miter"),"undefined"==typeof d&&(d=10),e=!1,this.lineWidth(a),this.lineCap(b),this.lineJoin(c),this.miterLimit(d),this},save:function(){return this._dirty=!0,this.context.save(),this},scale:function(a,b){return this._dirty=!0,this.context.scale(a,b),this},scrollPathIntoView:function(){return this._dirty=!0,this.context.scrollPathIntoView(),this},stroke:function(){return this._dirty=!0,this.context.stroke(),this},strokeRect:function(a,b,c,d){return this._dirty=!0,this.context.strokeRect(a,b,c,d),this},strokeStyle:function(a){return this.context.strokeStyle=a,this},render:function(){this._dirty&&(this.game.renderType==c.WEBGL&&b.texturesToUpdate.push(this.baseTexture),this._dirty=!1)}},c.BitmapData.prototype.constructor=c.BitmapData,c.BitmapData.prototype.mt=c.BitmapData.prototype.moveTo,c.BitmapData.prototype.lt=c.BitmapData.prototype.lineTo,c.BitmapData.prototype.at=c.BitmapData.prototype.arcTo,c.BitmapData.prototype.bt=c.BitmapData.prototype.bezierCurveTo,c.BitmapData.prototype.qt=c.BitmapData.prototype.quadraticCurveTo,c.BitmapData.prototype.a=c.BitmapData.prototype.arc,c.BitmapData.prototype.r=c.BitmapData.prototype.rect,c.BitmapData.prototype.cp=c.BitmapData.prototype.closePath,c.BitmapData.prototype.c=c.BitmapData.prototype.clear,c.BitmapData.prototype.f=c.BitmapData.prototype.beginFill,c.BitmapData.prototype.lf=c.BitmapData.prototype.beginLinearGradientFill,c.BitmapData.prototype.rf=c.BitmapData.prototype.beginRadialGradientFill,c.BitmapData.prototype.ef=c.BitmapData.prototype.endFill,c.BitmapData.prototype.ss=c.BitmapData.prototype.setStrokeStyle,c.BitmapData.prototype.s=c.BitmapData.prototype.beginStroke,c.BitmapData.prototype.ls=c.BitmapData.prototype.beginLinearGradientStroke,c.BitmapData.prototype.rs=c.BitmapData.prototype.beginRadialGradientStroke,c.BitmapData.prototype.dr=c.BitmapData.prototype.rect,c.BitmapData.prototype.dc=c.BitmapData.prototype.circle,c.BitmapData.prototype.de=c.BitmapData.prototype.ellipse,c.Sprite=function(a,d,e,f,g){d=d||0,e=e||0,f=f||null,g=g||null,this.game=a,this.exists=!0,this.alive=!0,this.group=null,this.name="",this.type=c.SPRITE,this.renderOrderID=-1,this.lifespan=0,this.events=new c.Events(this),this.animations=new c.AnimationManager(this),this.input=new c.InputHandler(this),this.key=f,this.currentFrame=null,f instanceof c.RenderTexture?(b.Sprite.call(this,f),this.currentFrame=this.game.cache.getTextureFrame(f.name)):f instanceof c.BitmapData?(b.Sprite.call(this,f.texture,f.textureFrame),this.currentFrame=f.textureFrame):f instanceof b.Texture?(b.Sprite.call(this,f),this.currentFrame=g):(null===f||"undefined"==typeof f?(f="__default",this.key=f):"string"==typeof f&&this.game.cache.checkImageKey(f)===!1&&(f="__missing",this.key=f),b.Sprite.call(this,b.TextureCache[f]),this.game.cache.isSpriteSheet(f)?(this.animations.loadFrameData(this.game.cache.getFrameData(f)),null!==g&&("string"==typeof g?this.frameName=g:this.frame=g)):this.currentFrame=this.game.cache.getFrame(f)),this.textureRegion=new c.Rectangle(this.texture.frame.x,this.texture.frame.y,this.texture.frame.width,this.texture.frame.height),this.anchor=new c.Point,this.x=d,this.y=e,this.position.x=d,this.position.y=e,this.world=new c.Point(d,e),this.autoCull=!1,this.scale=new c.Point(1,1),this._cache={fresh:!0,dirty:!1,a00:-1,a01:-1,a02:-1,a10:-1,a11:-1,a12:-1,id:-1,i01:-1,i10:-1,idi:-1,left:null,right:null,top:null,bottom:null,prevX:d,prevY:e,x:-1,y:-1,scaleX:1,scaleY:1,width:this.currentFrame.sourceSizeW,height:this.currentFrame.sourceSizeH,halfWidth:Math.floor(this.currentFrame.sourceSizeW/2),halfHeight:Math.floor(this.currentFrame.sourceSizeH/2),calcWidth:-1,calcHeight:-1,frameID:-1,frameWidth:this.currentFrame.width,frameHeight:this.currentFrame.height,cameraVisible:!0,cropX:0,cropY:0,cropWidth:this.currentFrame.sourceSizeW,cropHeight:this.currentFrame.sourceSizeH},this.offset=new c.Point,this.center=new c.Point(d+Math.floor(this._cache.width/2),e+Math.floor(this._cache.height/2)),this.topLeft=new c.Point(d,e),this.topRight=new c.Point(d+this._cache.width,e),this.bottomRight=new c.Point(d+this._cache.width,e+this._cache.height),this.bottomLeft=new c.Point(d,e+this._cache.height),this.bounds=new c.Rectangle(d,e,this._cache.width,this._cache.height),this.body=new c.Physics.Arcade.Body(this),this.health=1,this.inWorld=c.Rectangle.intersects(this.bounds,this.game.world.bounds),this.inWorldThreshold=0,this.outOfBoundsKill=!1,this._outOfBoundsFired=!1,this.fixedToCamera=!1,this.cameraOffset=new c.Point(d,e),this.crop=new c.Rectangle(0,0,this._cache.width,this._cache.height),this.cropEnabled=!1,this.debug=!1,this.updateCache(),this.updateBounds()},c.Sprite.prototype=Object.create(b.Sprite.prototype),c.Sprite.prototype.constructor=c.Sprite,c.Sprite.prototype.preUpdate=function(){return this._cache.fresh?(this.world.setTo(this.parent.position.x+this.x,this.parent.position.y+this.y),this.worldTransform[2]=this.world.x,this.worldTransform[5]=this.world.y,this._cache.fresh=!1,this.body&&(this.body.x=this.world.x-this.anchor.x*this.width+this.body.offset.x,this.body.y=this.world.y-this.anchor.y*this.height+this.body.offset.y,this.body.preX=this.body.x,this.body.preY=this.body.y),void 0):!this.exists||this.group&&!this.group.exists?(this.renderOrderID=-1,!1):this.lifespan>0&&(this.lifespan-=this.game.time.elapsed,this.lifespan<=0)?(this.kill(),!1):(this._cache.dirty=!1,this.visible&&(this.renderOrderID=this.game.world.currentRenderOrderID++),this.updateCache(),this.updateAnimation(),this.updateCrop(),(this._cache.dirty||this.world.x!==this._cache.prevX||this.world.y!==this._cache.prevY)&&this.updateBounds(),this.body&&this.body.preUpdate(),!0)},c.Sprite.prototype.updateCache=function(){this._cache.prevX=this.world.x,this._cache.prevY=this.world.y,this.fixedToCamera&&(this.x=this.game.camera.view.x+this.cameraOffset.x,this.y=this.game.camera.view.y+this.cameraOffset.y),this.world.setTo(this.game.camera.x+this.worldTransform[2],this.game.camera.y+this.worldTransform[5]),(this.worldTransform[1]!=this._cache.i01||this.worldTransform[3]!=this._cache.i10||this.worldTransform[0]!=this._cache.a00||this.worldTransform[41]!=this._cache.a11)&&(this._cache.a00=this.worldTransform[0],this._cache.a01=this.worldTransform[1],this._cache.a10=this.worldTransform[3],this._cache.a11=this.worldTransform[4],this._cache.i01=this.worldTransform[1],this._cache.i10=this.worldTransform[3],this._cache.scaleX=Math.sqrt(this._cache.a00*this._cache.a00+this._cache.a01*this._cache.a01),this._cache.scaleY=Math.sqrt(this._cache.a10*this._cache.a10+this._cache.a11*this._cache.a11),this._cache.a01*=-1,this._cache.a10*=-1,this._cache.id=1/(this._cache.a00*this._cache.a11+this._cache.a01*-this._cache.a10),this._cache.idi=1/(this._cache.a00*this._cache.a11+this._cache.i01*-this._cache.i10),this._cache.dirty=!0),this._cache.a02=this.worldTransform[2],this._cache.a12=this.worldTransform[5]},c.Sprite.prototype.updateAnimation=function(){(this.animations.update()||this.currentFrame&&this.currentFrame.uuid!=this._cache.frameID)&&(this._cache.frameID=this.currentFrame.uuid,this._cache.frameWidth=this.texture.frame.width,this._cache.frameHeight=this.texture.frame.height,this._cache.width=this.currentFrame.width,this._cache.height=this.currentFrame.height,this._cache.halfWidth=Math.floor(this._cache.width/2),this._cache.halfHeight=Math.floor(this._cache.height/2),this._cache.dirty=!0)},c.Sprite.prototype.updateCrop=function(){!this.cropEnabled||this.crop.width==this._cache.cropWidth&&this.crop.height==this._cache.cropHeight&&this.crop.x==this._cache.cropX&&this.crop.y==this._cache.cropY||(this.crop.floorAll(),this._cache.cropX=this.crop.x,this._cache.cropY=this.crop.y,this._cache.cropWidth=this.crop.width,this._cache.cropHeight=this.crop.height,this.texture.frame=this.crop,this.texture.width=this.crop.width,this.texture.height=this.crop.height,this.texture.updateFrame=!0,b.Texture.frameUpdates.push(this.texture))},c.Sprite.prototype.updateBounds=function(){this.offset.setTo(this._cache.a02-this.anchor.x*this.width,this._cache.a12-this.anchor.y*this.height),this.getLocalPosition(this.center,this.offset.x+this.width/2,this.offset.y+this.height/2),this.getLocalPosition(this.topLeft,this.offset.x,this.offset.y),this.getLocalPosition(this.topRight,this.offset.x+this.width,this.offset.y),this.getLocalPosition(this.bottomLeft,this.offset.x,this.offset.y+this.height),this.getLocalPosition(this.bottomRight,this.offset.x+this.width,this.offset.y+this.height),this._cache.left=c.Math.min(this.topLeft.x,this.topRight.x,this.bottomLeft.x,this.bottomRight.x),this._cache.right=c.Math.max(this.topLeft.x,this.topRight.x,this.bottomLeft.x,this.bottomRight.x),this._cache.top=c.Math.min(this.topLeft.y,this.topRight.y,this.bottomLeft.y,this.bottomRight.y),this._cache.bottom=c.Math.max(this.topLeft.y,this.topRight.y,this.bottomLeft.y,this.bottomRight.y),this.bounds.setTo(this._cache.left,this._cache.top,this._cache.right-this._cache.left,this._cache.bottom-this._cache.top),this.updateFrame=!0,this.inWorld===!1?(this.inWorld=c.Rectangle.intersects(this.bounds,this.game.world.bounds,this.inWorldThreshold),this.inWorld&&(this._outOfBoundsFired=!1)):(this.inWorld=c.Rectangle.intersects(this.bounds,this.game.world.bounds,this.inWorldThreshold),this.inWorld===!1&&(this.events.onOutOfBounds.dispatch(this),this._outOfBoundsFired=!0,this.outOfBoundsKill&&this.kill())),this._cache.cameraVisible=c.Rectangle.intersects(this.game.world.camera.screenView,this.bounds,0),this.autoCull&&(this.renderable=this._cache.cameraVisible)},c.Sprite.prototype.getLocalPosition=function(a,b,c){return a.x=(this._cache.a11*this._cache.id*b+-this._cache.a01*this._cache.id*c+(this._cache.a12*this._cache.a01-this._cache.a02*this._cache.a11)*this._cache.id)*this.scale.x+this._cache.a02,a.y=(this._cache.a00*this._cache.id*c+-this._cache.a10*this._cache.id*b+(-this._cache.a12*this._cache.a00+this._cache.a02*this._cache.a10)*this._cache.id)*this.scale.y+this._cache.a12,a},c.Sprite.prototype.getLocalUnmodifiedPosition=function(a,b,c){return a.x=this._cache.a11*this._cache.idi*b+-this._cache.i01*this._cache.idi*c+(this._cache.a12*this._cache.i01-this._cache.a02*this._cache.a11)*this._cache.idi+this.anchor.x*this._cache.width,a.y=this._cache.a00*this._cache.idi*c+-this._cache.i10*this._cache.idi*b+(-this._cache.a12*this._cache.a00+this._cache.a02*this._cache.i10)*this._cache.idi+this.anchor.y*this._cache.height,a},c.Sprite.prototype.resetCrop=function(){this.crop=new c.Rectangle(0,0,this._cache.width,this._cache.height),this.texture.setFrame(this.crop),this.cropEnabled=!1},c.Sprite.prototype.postUpdate=function(){this.key instanceof c.BitmapData&&this.key._dirty&&this.key.render(),this.exists&&(this.body&&this.body.postUpdate(),this.fixedToCamera?(this._cache.x=this.game.camera.view.x+this.cameraOffset.x,this._cache.y=this.game.camera.view.y+this.cameraOffset.y):(this._cache.x=this.x,this._cache.y=this.y),this.position.x=this._cache.x,this.position.y=this._cache.y)},c.Sprite.prototype.loadTexture=function(a,d){this.key=a,a instanceof c.RenderTexture?this.currentFrame=this.game.cache.getTextureFrame(a.name):a instanceof c.BitmapData?(this.setTexture(a.texture),this.currentFrame=a.textureFrame):a instanceof b.Texture?this.currentFrame=d:(("undefined"==typeof a||this.game.cache.checkImageKey(a)===!1)&&(a="__default",this.key=a),this.game.cache.isSpriteSheet(a)?(this.animations.loadFrameData(this.game.cache.getFrameData(a)),"undefined"!=typeof d&&("string"==typeof d?this.frameName=d:this.frame=d)):(this.currentFrame=this.game.cache.getFrame(a),this.setTexture(b.TextureCache[a])))},c.Sprite.prototype.centerOn=function(a,b){return this.fixedToCamera?(this.cameraOffset.x=a+(this.cameraOffset.x-this.center.x),this.cameraOffset.y=b+(this.cameraOffset.y-this.center.y)):(this.x=a+(this.x-this.center.x),this.y=b+(this.y-this.center.y)),this},c.Sprite.prototype.revive=function(a){return"undefined"==typeof a&&(a=1),this.alive=!0,this.exists=!0,this.visible=!0,this.health=a,this.events&&this.events.onRevived.dispatch(this),this},c.Sprite.prototype.kill=function(){return this.alive=!1,this.exists=!1,this.visible=!1,this.events&&this.events.onKilled.dispatch(this),this},c.Sprite.prototype.destroy=function(){this.filters&&(this.filters=null),this.group&&this.group.remove(this),this.input&&this.input.destroy(),this.events&&this.events.destroy(),this.animations&&this.animations.destroy(),this.body&&this.body.destroy(),this.alive=!1,this.exists=!1,this.visible=!1,this.game=null},c.Sprite.prototype.damage=function(a){return this.alive&&(this.health-=a,this.health<0&&this.kill()),this},c.Sprite.prototype.reset=function(a,b,c){return"undefined"==typeof c&&(c=1),this.x=a,this.y=b,this.world.setTo(a,b),this.position.x=this.x,this.position.y=this.y,this.alive=!0,this.exists=!0,this.visible=!0,this.renderable=!0,this._outOfBoundsFired=!1,this.health=c,this.body&&this.body.reset(!1),this},c.Sprite.prototype.bringToTop=function(){return this.group?this.group.bringToTop(this):this.game.world.bringToTop(this),this},c.Sprite.prototype.play=function(a,b,c,d){return this.animations?this.animations.play(a,b,c,d):void 0},Object.defineProperty(c.Sprite.prototype,"deltaX",{get:function(){return this.world.x-this._cache.prevX}}),Object.defineProperty(c.Sprite.prototype,"deltaY",{get:function(){return this.world.y-this._cache.prevY}}),Object.defineProperty(c.Sprite.prototype,"angle",{get:function(){return c.Math.wrapAngle(c.Math.radToDeg(this.rotation))},set:function(a){this.rotation=c.Math.degToRad(c.Math.wrapAngle(a))}}),Object.defineProperty(c.Sprite.prototype,"frame",{get:function(){return this.animations.frame},set:function(a){this.animations.frame=a}}),Object.defineProperty(c.Sprite.prototype,"frameName",{get:function(){return this.animations.frameName},set:function(a){this.animations.frameName=a}}),Object.defineProperty(c.Sprite.prototype,"inCamera",{get:function(){return this._cache.cameraVisible}}),Object.defineProperty(c.Sprite.prototype,"worldCenterX",{get:function(){return this.game.camera.x+this.center.x}}),Object.defineProperty(c.Sprite.prototype,"worldCenterY",{get:function(){return this.game.camera.y+this.center.y}}),Object.defineProperty(c.Sprite.prototype,"width",{get:function(){return this.scale.x*this.currentFrame.width},set:function(a){this.scale.x=a/this.currentFrame.width,this._cache.scaleX=a/this.currentFrame.width,this._width=a}}),Object.defineProperty(c.Sprite.prototype,"height",{get:function(){return this.scale.y*this.currentFrame.height},set:function(a){this.scale.y=a/this.currentFrame.height,this._cache.scaleY=a/this.currentFrame.height,this._height=a}}),Object.defineProperty(c.Sprite.prototype,"inputEnabled",{get:function(){return this.input.enabled},set:function(a){a?this.input.enabled===!1&&this.input.start():this.input.enabled&&this.input.stop()}}),c.TileSprite=function(a,d,e,f,g,h){d=d||0,e=e||0,f=f||256,g=g||256,h=h||null,c.Sprite.call(this,a,d,e,h),this.texture=b.TextureCache[h],b.TilingSprite.call(this,this.texture,f,g),this.type=c.TILESPRITE,this.tileScale=new c.Point(1,1),this.tilePosition=new c.Point(0,0),this.body.width=f,this.body.height=g +},c.TileSprite.prototype=c.Utils.extend(!0,b.TilingSprite.prototype,c.Sprite.prototype),c.TileSprite.prototype.constructor=c.TileSprite,Object.defineProperty(c.TileSprite.prototype,"angle",{get:function(){return c.Math.wrapAngle(c.Math.radToDeg(this.rotation))},set:function(a){this.rotation=c.Math.degToRad(c.Math.wrapAngle(a))}}),Object.defineProperty(c.TileSprite.prototype,"frame",{get:function(){return this.animations.frame},set:function(a){this.animations.frame=a}}),Object.defineProperty(c.TileSprite.prototype,"frameName",{get:function(){return this.animations.frameName},set:function(a){this.animations.frameName=a}}),Object.defineProperty(c.TileSprite.prototype,"inCamera",{get:function(){return this._cache.cameraVisible}}),Object.defineProperty(c.TileSprite.prototype,"inputEnabled",{get:function(){return this.input.enabled},set:function(a){a?this.input.enabled===!1&&this.input.start():this.input.enabled&&this.input.stop()}}),c.Text=function(a,d,e,f,g){d=d||0,e=e||0,f=f||"",g=g||"",this.game=a,this.exists=!0,this.alive=!0,this.group=null,this.name="",this.type=c.TEXT,this._text=f,this._style=g,b.Text.call(this,f,g),this.position.x=this.x=d,this.position.y=this.y=e,this.anchor=new c.Point,this.scale=new c.Point(1,1),this.fixedToCamera=!1,this.cameraOffset=new c.Point(d,e),this._cache={dirty:!1,a00:1,a01:0,a02:d,a10:0,a11:1,a12:e,id:1,x:-1,y:-1,scaleX:1,scaleY:1},this._cache.x=this.x,this._cache.y=this.y,this.renderable=!0},c.Text.prototype=Object.create(b.Text.prototype),c.Text.prototype.constructor=c.Text,c.Text.prototype.update=function(){this.exists&&(this.fixedToCamera&&(this.x=this.game.camera.view.x+this.cameraOffset.x,this.y=this.game.camera.view.y+this.cameraOffset.y),this._cache.dirty=!1,this._cache.x=this.x,this._cache.y=this.y,(this.position.x!=this._cache.x||this.position.y!=this._cache.y)&&(this.position.x=this._cache.x,this.position.y=this._cache.y,this._cache.dirty=!0))},c.Text.prototype.destroy=function(){this.group&&this.group.remove(this),this.canvas.parentNode?this.canvas.parentNode.removeChild(this.canvas):(this.canvas=null,this.context=null),this.exists=!1,this.group=null},Object.defineProperty(c.Text.prototype,"angle",{get:function(){return c.Math.radToDeg(this.rotation)},set:function(a){this.rotation=c.Math.degToRad(a)}}),Object.defineProperty(c.Text.prototype,"x",{get:function(){return this.position.x},set:function(a){this.position.x=a}}),Object.defineProperty(c.Text.prototype,"y",{get:function(){return this.position.y},set:function(a){this.position.y=a}}),Object.defineProperty(c.Text.prototype,"content",{get:function(){return this._text},set:function(a){a!==this._text&&(this._text=a,this.setText(a))}}),Object.defineProperty(c.Text.prototype,"font",{get:function(){return this._style},set:function(a){a!==this._style&&(this._style=a,this.setStyle(a))}}),c.BitmapText=function(a,d,e,f,g){d=d||0,e=e||0,f=f||"",g=g||"",this.game=a,this.exists=!0,this.alive=!0,this.group=null,this.name="",this.type=c.BITMAPTEXT,b.BitmapText.call(this,f,g),this.position.x=d,this.position.y=e,this.anchor=new c.Point,this.scale=new c.Point(1,1),this._cache={dirty:!1,a00:1,a01:0,a02:d,a10:0,a11:1,a12:e,id:1,x:-1,y:-1,scaleX:1,scaleY:1},this._cache.x=this.x,this._cache.y=this.y},c.BitmapText.prototype=Object.create(b.BitmapText.prototype),c.BitmapText.prototype.constructor=c.BitmapText,c.BitmapText.prototype.update=function(){this.exists&&(this._cache.dirty=!1,this._cache.x=this.x,this._cache.y=this.y,(this.position.x!=this._cache.x||this.position.y!=this._cache.y)&&(this.position.x=this._cache.x,this.position.y=this._cache.y,this._cache.dirty=!0),this.pivot.x=this.anchor.x*this.width,this.pivot.y=this.anchor.y*this.height)},c.BitmapText.prototype.destroy=function(){this.group&&this.group.remove(this),this.canvas&&this.canvas.parentNode?this.canvas.parentNode.removeChild(this.canvas):(this.canvas=null,this.context=null),this.exists=!1,this.group=null},Object.defineProperty(c.BitmapText.prototype,"angle",{get:function(){return c.Math.radToDeg(this.rotation)},set:function(a){this.rotation=c.Math.degToRad(a)}}),Object.defineProperty(c.BitmapText.prototype,"x",{get:function(){return this.position.x},set:function(a){this.position.x=a}}),Object.defineProperty(c.BitmapText.prototype,"y",{get:function(){return this.position.y},set:function(a){this.position.y=a}}),c.Button=function(a,b,d,e,f,g,h,i,j,k){b=b||0,d=d||0,e=e||null,f=f||null,g=g||this,c.Sprite.call(this,a,b,d,e,i),this.type=c.BUTTON,this._onOverFrameName=null,this._onOutFrameName=null,this._onDownFrameName=null,this._onUpFrameName=null,this._onOverFrameID=null,this._onOutFrameID=null,this._onDownFrameID=null,this._onUpFrameID=null,this.onOverSound=null,this.onOutSound=null,this.onDownSound=null,this.onUpSound=null,this.onOverSoundMarker="",this.onOutSoundMarker="",this.onDownSoundMarker="",this.onUpSoundMarker="",this.onInputOver=new c.Signal,this.onInputOut=new c.Signal,this.onInputDown=new c.Signal,this.onInputUp=new c.Signal,this.freezeFrames=!1,this.forceOut=!1,this.setFrames(h,i,j,k),null!==f&&this.onInputUp.add(f,g),this.input.start(0,!0),this.events.onInputOver.add(this.onInputOverHandler,this),this.events.onInputOut.add(this.onInputOutHandler,this),this.events.onInputDown.add(this.onInputDownHandler,this),this.events.onInputUp.add(this.onInputUpHandler,this)},c.Button.prototype=Object.create(c.Sprite.prototype),c.Button.prototype=c.Utils.extend(!0,c.Button.prototype,c.Sprite.prototype,b.Sprite.prototype),c.Button.prototype.constructor=c.Button,c.Button.prototype.clearFrames=function(){this._onOverFrameName=null,this._onOverFrameID=null,this._onOutFrameName=null,this._onOutFrameID=null,this._onDownFrameName=null,this._onDownFrameID=null,this._onUpFrameName=null,this._onUpFrameID=null},c.Button.prototype.setFrames=function(a,b,c,d){this.clearFrames(),null!==a&&("string"==typeof a?(this._onOverFrameName=a,this.input.pointerOver()&&(this.frameName=a)):(this._onOverFrameID=a,this.input.pointerOver()&&(this.frame=a))),null!==b&&("string"==typeof b?(this._onOutFrameName=b,this.input.pointerOver()===!1&&(this.frameName=b)):(this._onOutFrameID=b,this.input.pointerOver()===!1&&(this.frame=b))),null!==c&&("string"==typeof c?(this._onDownFrameName=c,this.input.pointerDown()&&(this.frameName=c)):(this._onDownFrameID=c,this.input.pointerDown()&&(this.frame=c))),null!==d&&("string"==typeof d?(this._onUpFrameName=d,this.input.pointerUp()&&(this.frameName=d)):(this._onUpFrameID=d,this.input.pointerUp()&&(this.frame=d)))},c.Button.prototype.setSounds=function(a,b,c,d,e,f,g,h){this.setOverSound(a,b),this.setOutSound(e,f),this.setDownSound(c,d),this.setUpSound(g,h)},c.Button.prototype.setOverSound=function(a,b){this.onOverSound=null,this.onOverSoundMarker="",a instanceof c.Sound&&(this.onOverSound=a),"string"==typeof b&&(this.onOverSoundMarker=b)},c.Button.prototype.setOutSound=function(a,b){this.onOutSound=null,this.onOutSoundMarker="",a instanceof c.Sound&&(this.onOutSound=a),"string"==typeof b&&(this.onOutSoundMarker=b)},c.Button.prototype.setDownSound=function(a,b){this.onDownSound=null,this.onDownSoundMarker="",a instanceof c.Sound&&(this.onDownSound=a),"string"==typeof b&&(this.onDownSoundMarker=b)},c.Button.prototype.setUpSound=function(a,b){this.onUpSound=null,this.onUpSoundMarker="",a instanceof c.Sound&&(this.onUpSound=a),"string"==typeof b&&(this.onUpSoundMarker=b)},c.Button.prototype.onInputOverHandler=function(a,b){this.freezeFrames===!1&&this.setState(1),this.onOverSound&&this.onOverSound.play(this.onOverSoundMarker),this.onInputOver&&this.onInputOver.dispatch(this,b)},c.Button.prototype.onInputOutHandler=function(a,b){this.freezeFrames===!1&&this.setState(2),this.onOutSound&&this.onOutSound.play(this.onOutSoundMarker),this.onInputOut&&this.onInputOut.dispatch(this,b)},c.Button.prototype.onInputDownHandler=function(a,b){this.freezeFrames===!1&&this.setState(3),this.onDownSound&&this.onDownSound.play(this.onDownSoundMarker),this.onInputDown&&this.onInputDown.dispatch(this,b)},c.Button.prototype.onInputUpHandler=function(a,b,c){this.onUpSound&&this.onUpSound.play(this.onUpSoundMarker),this.onInputUp&&this.onInputUp.dispatch(this,b,c),this.freezeFrames||(this.forceOut?this.setState(2):this._onUpFrameName||this._onUpFrameID?this.setState(4):c?this.setState(1):this.setState(2))},c.Button.prototype.setState=function(a){1===a?null!=this._onOverFrameName?this.frameName=this._onOverFrameName:null!=this._onOverFrameID&&(this.frame=this._onOverFrameID):2===a?null!=this._onOutFrameName?this.frameName=this._onOutFrameName:null!=this._onOutFrameID&&(this.frame=this._onOutFrameID):3===a?null!=this._onDownFrameName?this.frameName=this._onDownFrameName:null!=this._onDownFrameID&&(this.frame=this._onDownFrameID):4===a&&(null!=this._onUpFrameName?this.frameName=this._onUpFrameName:null!=this._onUpFrameID&&(this.frame=this._onUpFrameID))},c.Graphics=function(a,d,e){this.game=a,b.Graphics.call(this),this.type=c.GRAPHICS,this.position.x=d,this.position.y=e},c.Graphics.prototype=Object.create(b.Graphics.prototype),c.Graphics.prototype.constructor=c.Graphics,c.Graphics.prototype.destroy=function(){this.clear(),this.group&&this.group.remove(this),this.game=null},c.Graphics.prototype.drawPolygon=function(a){this.moveTo(a.points[0].x,a.points[0].y);for(var b=1;bh;h++)f[h].updateTransform();var j=a.__renderGroup;j?a==j.root?j.render(this.projection,this.glFramebuffer):j.renderSpecific(a,this.projection,this.glFramebuffer):(this.renderGroup||(this.renderGroup=new b.WebGLRenderGroup(e)),this.renderGroup.setRenderable(a),this.renderGroup.render(this.projection,this.glFramebuffer)),a.worldTransform=g},c.RenderTexture.prototype.renderCanvas=function(a,c,d,e){var f=a.children;a.worldTransform=b.mat3.create(),c&&(a.worldTransform[2]=c.x,a.worldTransform[5]=c.y);for(var g=0,h=f.length;h>g;g++)f[g].updateTransform();d&&this.renderer.context.clearRect(0,0,this.width,this.height),this.renderer.renderDisplayObject(a,e),this.renderer.context.setTransform(1,0,0,1,0,0)},c.Canvas={create:function(a,b,c){a=a||256,b=b||256;var d=document.createElement("canvas");return"string"==typeof c&&(d.id=c),d.width=a,d.height=b,d.style.display="block",d},getOffset:function(a,b){b=b||new c.Point;var d=a.getBoundingClientRect(),e=a.clientTop||document.body.clientTop||0,f=a.clientLeft||document.body.clientLeft||0,g=0,h=0;return"CSS1Compat"===document.compatMode?(g=window.pageYOffset||document.documentElement.scrollTop||a.scrollTop||0,h=window.pageXOffset||document.documentElement.scrollLeft||a.scrollLeft||0):(g=window.pageYOffset||document.body.scrollTop||a.scrollTop||0,h=window.pageXOffset||document.body.scrollLeft||a.scrollLeft||0),b.x=d.left+h-f,b.y=d.top+g-e,b},getAspectRatio:function(a){return a.width/a.height},setBackgroundColor:function(a,b){return b=b||"rgb(0,0,0)",a.style.backgroundColor=b,a},setTouchAction:function(a,b){return b=b||"none",a.style.msTouchAction=b,a.style["ms-touch-action"]=b,a.style["touch-action"]=b,a},setUserSelect:function(a,b){return b=b||"none",a.style["-webkit-touch-callout"]=b,a.style["-webkit-user-select"]=b,a.style["-khtml-user-select"]=b,a.style["-moz-user-select"]=b,a.style["-ms-user-select"]=b,a.style["user-select"]=b,a.style["-webkit-tap-highlight-color"]="rgba(0, 0, 0, 0)",a},addToDOM:function(a,b,c){var d;return"undefined"==typeof c&&(c=!0),b&&("string"==typeof b?d=document.getElementById(b):"object"==typeof b&&1===b.nodeType&&(d=b)),d||(d=document.body),c&&d.style&&(d.style.overflow="hidden"),d.appendChild(a),a},setTransform:function(a,b,c,d,e,f,g){return a.setTransform(d,f,g,e,b,c),a},setSmoothingEnabled:function(a,b){return a.imageSmoothingEnabled=b,a.mozImageSmoothingEnabled=b,a.oImageSmoothingEnabled=b,a.webkitImageSmoothingEnabled=b,a.msImageSmoothingEnabled=b,a},setImageRenderingCrisp:function(a){return a.style["image-rendering"]="optimizeSpeed",a.style["image-rendering"]="crisp-edges",a.style["image-rendering"]="-moz-crisp-edges",a.style["image-rendering"]="-webkit-optimize-contrast",a.style["image-rendering"]="optimize-contrast",a.style.msInterpolationMode="nearest-neighbor",a},setImageRenderingBicubic:function(a){return a.style["image-rendering"]="auto",a.style.msInterpolationMode="bicubic",a}},c.StageScaleMode=function(a,b,d){this.game=a,this.width=b,this.height=d,this.minWidth=null,this.maxWidth=null,this.minHeight=null,this.maxHeight=null,this._startHeight=0,this.forceLandscape=!1,this.forcePortrait=!1,this.incorrectOrientation=!1,this.pageAlignHorizontally=!1,this.pageAlignVertically=!1,this._width=0,this._height=0,this.maxIterations=5,this.orientationSprite=null,this.enterLandscape=new c.Signal,this.enterPortrait=new c.Signal,this.enterIncorrectOrientation=new c.Signal,this.leaveIncorrectOrientation=new c.Signal,this.hasResized=new c.Signal,this.orientation=window.orientation?window.orientation:window.outerWidth>window.outerHeight?90:0,this.scaleFactor=new c.Point(1,1),this.scaleFactorInversed=new c.Point(1,1),this.margin=new c.Point(0,0),this.aspectRatio=0,this.event=null;var e=this;window.addEventListener("orientationchange",function(a){return e.checkOrientation(a)},!1),window.addEventListener("resize",function(a){return e.checkResize(a)},!1),document.addEventListener("webkitfullscreenchange",function(a){return e.fullScreenChange(a)},!1),document.addEventListener("mozfullscreenchange",function(a){return e.fullScreenChange(a)},!1),document.addEventListener("fullscreenchange",function(a){return e.fullScreenChange(a)},!1)},c.StageScaleMode.EXACT_FIT=0,c.StageScaleMode.NO_SCALE=1,c.StageScaleMode.SHOW_ALL=2,c.StageScaleMode.prototype={startFullScreen:function(a){if(!this.isFullScreen){"undefined"!=typeof a&&c.Canvas.setSmoothingEnabled(this.game.context,a);var b=this.game.canvas;this._width=this.width,this._height=this.height,b.requestFullScreen?b.requestFullScreen():b.mozRequestFullScreen?b.parentNode.mozRequestFullScreen():b.webkitRequestFullScreen&&b.webkitRequestFullScreen(Element.ALLOW_KEYBOARD_INPUT)}},stopFullScreen:function(){document.cancelFullScreen?document.cancelFullScreen():document.mozCancelFullScreen?document.mozCancelFullScreen():document.webkitCancelFullScreen&&document.webkitCancelFullScreen()},fullScreenChange:function(a){this.event=a,this.isFullScreen?this.game.stage.fullScreenScaleMode===c.StageScaleMode.EXACT_FIT?(this.game.stage.canvas.style.width="100%",this.game.stage.canvas.style.height="100%",this.setMaximum(),this.game.input.scale.setTo(this.game.width/this.width,this.game.height/this.height),this.aspectRatio=this.width/this.height,this.scaleFactor.x=this.game.width/this.width,this.scaleFactor.y=this.game.height/this.height):this.game.stage.fullScreenScaleMode===c.StageScaleMode.SHOW_ALL&&(this.game.stage.scale.setShowAll(),this.game.stage.scale.refresh()):(this.game.stage.canvas.style.width=this.game.width+"px",this.game.stage.canvas.style.height=this.game.height+"px",this.width=this._width,this.height=this._height,this.game.input.scale.setTo(this.game.width/this.width,this.game.height/this.height),this.aspectRatio=this.width/this.height,this.scaleFactor.x=this.game.width/this.width,this.scaleFactor.y=this.game.height/this.height)},forceOrientation:function(a,c,d){"undefined"==typeof c&&(c=!1),this.forceLandscape=a,this.forcePortrait=c,"undefined"!=typeof d&&((null==d||this.game.cache.checkImageKey(d)===!1)&&(d="__default"),this.orientationSprite=new b.Sprite(b.TextureCache[d]),this.orientationSprite.anchor.x=.5,this.orientationSprite.anchor.y=.5,this.orientationSprite.position.x=this.game.width/2,this.orientationSprite.position.y=this.game.height/2,this.checkOrientationState(),this.incorrectOrientation?(this.orientationSprite.visible=!0,this.game.world.visible=!1):(this.orientationSprite.visible=!1,this.game.world.visible=!0),this.game.stage._stage.addChild(this.orientationSprite))},checkOrientationState:function(){this.incorrectOrientation?(this.forceLandscape&&window.innerWidth>window.innerHeight||this.forcePortrait&&window.innerHeight>window.innerWidth)&&(this.game.paused=!1,this.incorrectOrientation=!1,this.leaveIncorrectOrientation.dispatch(),this.orientationSprite&&(this.orientationSprite.visible=!1,this.game.world.visible=!0),this.refresh()):(this.forceLandscape&&window.innerWidthwindow.outerHeight?90:0,this.isLandscape?this.enterLandscape.dispatch(this.orientation,!0,!1):this.enterPortrait.dispatch(this.orientation,!1,!0),this.game.stage.scaleMode!==c.StageScaleMode.NO_SCALE&&this.refresh(),this.checkOrientationState()},refresh:function(){if(this.game.device.iPad===!1&&this.game.device.webApp===!1&&this.game.device.desktop===!1&&(this.game.device.android&&this.game.device.chrome===!1?window.scrollTo(0,1):window.scrollTo(0,0)),null==this._check&&this.maxIterations>0){this._iterations=this.maxIterations;var a=this;this._check=window.setInterval(function(){return a.setScreenSize()},10),this.setScreenSize()}},setScreenSize:function(a){"undefined"==typeof a&&(a=!1),this.game.device.iPad===!1&&this.game.device.webApp===!1&&this.game.device.desktop===!1&&(this.game.device.android&&this.game.device.chrome===!1?window.scrollTo(0,1):window.scrollTo(0,0)),this._iterations--,(a||window.innerHeight>this._startHeight||this._iterations<0)&&(document.documentElement.style.minHeight=window.innerHeight+"px",this.incorrectOrientation===!0?this.setMaximum():this.isFullScreen?this.game.stage.fullScreenScaleMode==c.StageScaleMode.EXACT_FIT?this.setExactFit():this.game.stage.fullScreenScaleMode==c.StageScaleMode.SHOW_ALL&&this.setShowAll():this.game.stage.scaleMode==c.StageScaleMode.EXACT_FIT?this.setExactFit():this.game.stage.scaleMode==c.StageScaleMode.SHOW_ALL&&this.setShowAll(),this.setSize(),clearInterval(this._check),this._check=null)},setSize:function(){this.incorrectOrientation===!1&&(this.maxWidth&&this.width>this.maxWidth&&(this.width=this.maxWidth),this.maxHeight&&this.height>this.maxHeight&&(this.height=this.maxHeight),this.minWidth&&this.widththis.maxWidth?this.maxWidth:a,this.height=this.maxHeight&&b>this.maxHeight?this.maxHeight:b}},c.StageScaleMode.prototype.constructor=c.StageScaleMode,Object.defineProperty(c.StageScaleMode.prototype,"isFullScreen",{get:function(){return document.fullscreenElement||document.mozFullScreenElement||document.webkitFullscreenElement}}),Object.defineProperty(c.StageScaleMode.prototype,"isPortrait",{get:function(){return 0===this.orientation||180==this.orientation}}),Object.defineProperty(c.StageScaleMode.prototype,"isLandscape",{get:function(){return 90===this.orientation||-90===this.orientation}}),c.Device=function(){this.patchAndroidClearRectBug=!1,this.desktop=!1,this.iOS=!1,this.cocoonJS=!1,this.ejecta=!1,this.android=!1,this.chromeOS=!1,this.linux=!1,this.macOS=!1,this.windows=!1,this.canvas=!1,this.file=!1,this.fileSystem=!1,this.localStorage=!1,this.webGL=!1,this.worker=!1,this.touch=!1,this.mspointer=!1,this.css3D=!1,this.pointerLock=!1,this.typedArray=!1,this.vibration=!1,this.quirksMode=!1,this.arora=!1,this.chrome=!1,this.epiphany=!1,this.firefox=!1,this.ie=!1,this.ieVersion=0,this.trident=!1,this.tridentVersion=0,this.mobileSafari=!1,this.midori=!1,this.opera=!1,this.safari=!1,this.webApp=!1,this.silk=!1,this.audioData=!1,this.webAudio=!1,this.ogg=!1,this.opus=!1,this.mp3=!1,this.wav=!1,this.m4a=!1,this.webm=!1,this.iPhone=!1,this.iPhone4=!1,this.iPad=!1,this.pixelRatio=0,this.littleEndian=!1,this._checkAudio(),this._checkBrowser(),this._checkCSS3D(),this._checkDevice(),this._checkFeatures(),this._checkOS()},c.Device.prototype={_checkOS:function(){var a=navigator.userAgent;/Android/.test(a)?this.android=!0:/CrOS/.test(a)?this.chromeOS=!0:/iP[ao]d|iPhone/i.test(a)?this.iOS=!0:/Linux/.test(a)?this.linux=!0:/Mac OS/.test(a)?this.macOS=!0:/Windows/.test(a)&&(this.windows=!0),(this.windows||this.macOS||this.linux&&this.silk===!1)&&(this.desktop=!0)},_checkFeatures:function(){this.canvas=!!window.CanvasRenderingContext2D;try{this.localStorage=!!localStorage.getItem}catch(a){this.localStorage=!1}this.file=!!(window.File&&window.FileReader&&window.FileList&&window.Blob),this.fileSystem=!!window.requestFileSystem,this.webGL=function(){try{var a=document.createElement("canvas");return!!window.WebGLRenderingContext&&(a.getContext("webgl")||a.getContext("experimental-webgl"))}catch(b){return!1}}(),this.webGL=null===this.webGL||this.webGL===!1?!1:!0,this.worker=!!window.Worker,("ontouchstart"in document.documentElement||window.navigator.maxTouchPoints&&window.navigator.maxTouchPoints>1)&&(this.touch=!0),(window.navigator.msPointerEnabled||window.navigator.pointerEnabled)&&(this.mspointer=!0),this.pointerLock="pointerLockElement"in document||"mozPointerLockElement"in document||"webkitPointerLockElement"in document,this.quirksMode="CSS1Compat"===document.compatMode?!1:!0},_checkBrowser:function(){var a=navigator.userAgent;/Arora/.test(a)?this.arora=!0:/Chrome/.test(a)?this.chrome=!0:/Epiphany/.test(a)?this.epiphany=!0:/Firefox/.test(a)?this.firefox=!0:/Mobile Safari/.test(a)?this.mobileSafari=!0:/MSIE (\d+\.\d+);/.test(a)?(this.ie=!0,this.ieVersion=parseInt(RegExp.$1,10)):/Midori/.test(a)?this.midori=!0:/Opera/.test(a)?this.opera=!0:/Safari/.test(a)?this.safari=!0:/Silk/.test(a)?this.silk=!0:/Trident\/(\d+\.\d+);/.test(a)&&(this.ie=!0,this.trident=!0,this.tridentVersion=parseInt(RegExp.$1,10)),navigator.standalone&&(this.webApp=!0),navigator.isCocoonJS&&(this.cocoonJS=!0),"undefined"!=typeof window.ejecta&&(this.ejecta=!0)},_checkAudio:function(){this.audioData=!!window.Audio,this.webAudio=!(!window.webkitAudioContext&&!window.AudioContext);var a=document.createElement("audio"),b=!1;try{(b=!!a.canPlayType)&&(a.canPlayType('audio/ogg; codecs="vorbis"').replace(/^no$/,"")&&(this.ogg=!0),a.canPlayType('audio/ogg; codecs="opus"').replace(/^no$/,"")&&(this.opus=!0),a.canPlayType("audio/mpeg;").replace(/^no$/,"")&&(this.mp3=!0),a.canPlayType('audio/wav; codecs="1"').replace(/^no$/,"")&&(this.wav=!0),(a.canPlayType("audio/x-m4a;")||a.canPlayType("audio/aac;").replace(/^no$/,""))&&(this.m4a=!0),a.canPlayType('audio/webm; codecs="vorbis"').replace(/^no$/,"")&&(this.webm=!0))}catch(c){}},_checkDevice:function(){this.pixelRatio=window.devicePixelRatio||1,this.iPhone=-1!=navigator.userAgent.toLowerCase().indexOf("iphone"),this.iPhone4=2==this.pixelRatio&&this.iPhone,this.iPad=-1!=navigator.userAgent.toLowerCase().indexOf("ipad"),"undefined"!=typeof Int8Array?(this.littleEndian=new Int8Array(new Int16Array([1]).buffer)[0]>0,this.typedArray=!0):(this.littleEndian=!1,this.typedArray=!1),navigator.vibrate=navigator.vibrate||navigator.webkitVibrate||navigator.mozVibrate||navigator.msVibrate,navigator.vibrate&&(this.vibration=!0)},_checkCSS3D:function(){var a,b=document.createElement("p"),c={webkitTransform:"-webkit-transform",OTransform:"-o-transform",msTransform:"-ms-transform",MozTransform:"-moz-transform",transform:"transform"};document.body.insertBefore(b,null);for(var d in c)void 0!==b.style[d]&&(b.style[d]="translate3d(1px,1px,1px)",a=window.getComputedStyle(b).getPropertyValue(c[d]));document.body.removeChild(b),this.css3D=void 0!==a&&a.length>0&&"none"!==a},canPlayAudio:function(a){return"mp3"==a&&this.mp3?!0:"ogg"==a&&(this.ogg||this.opus)?!0:"m4a"==a&&this.m4a?!0:"wav"==a&&this.wav?!0:"webm"==a&&this.webm?!0:!1},isConsoleOpen:function(){return window.console&&window.console.firebug?!0:window.console?(console.profile(),console.profileEnd(),console.clear&&console.clear(),console.profiles.length>0):!1}},c.Device.prototype.constructor=c.Device,c.RequestAnimationFrame=function(a){this.game=a,this.isRunning=!1;for(var b=["ms","moz","webkit","o"],c=0;c>>0,b-=d,b*=d,d=b>>>0,b-=d,d+=4294967296*b;return 2.3283064365386963e-10*(d>>>0)},integer:function(){return 4294967296*this.rnd.apply(this)},frac:function(){return this.rnd.apply(this)+1.1102230246251565e-16*(0|2097152*this.rnd.apply(this))},real:function(){return this.integer()+this.frac()},integerInRange:function(a,b){return Math.floor(this.realInRange(a,b))},realInRange:function(a,b){return this.frac()*(b-a)+a},normal:function(){return 1-2*this.frac()},uuid:function(){var a="",b="";for(b=a="";a++<36;b+=~a%5|4&3*a?(15^a?8^this.frac()*(20^a?16:4):4).toString(16):"-");return b},pick:function(a){return a[this.integerInRange(0,a.length)]},weightedPick:function(a){return a[~~(Math.pow(this.frac(),2)*a.length)]},timestamp:function(a,b){return this.realInRange(a||9466848e5,b||1577862e6)},angle:function(){return this.integerInRange(-180,180)}},c.RandomDataGenerator.prototype.constructor=c.RandomDataGenerator,c.Math={PI2:2*Math.PI,fuzzyEqual:function(a,b,c){return"undefined"==typeof c&&(c=1e-4),Math.abs(a-b)a},fuzzyGreaterThan:function(a,b,c){return"undefined"==typeof c&&(c=1e-4),a>b-c},fuzzyCeil:function(a,b){return"undefined"==typeof b&&(b=1e-4),Math.ceil(a-b)},fuzzyFloor:function(a,b){return"undefined"==typeof b&&(b=1e-4),Math.floor(a+b)},average:function(){for(var a=[],b=0;b0?Math.floor(a):Math.ceil(a)},shear:function(a){return a%1},snapTo:function(a,b,c){return"undefined"==typeof c&&(c=0),0===b?a:(a-=c,a=b*Math.round(a/b),c+a)},snapToFloor:function(a,b,c){return"undefined"==typeof c&&(c=0),0===b?a:(a-=c,a=b*Math.floor(a/b),c+a)},snapToCeil:function(a,b,c){return"undefined"==typeof c&&(c=0),0===b?a:(a-=c,a=b*Math.ceil(a/b),c+a)},snapToInArray:function(a,b,c){if("undefined"==typeof c&&(c=!0),c&&b.sort(),a=f-a?f:e},roundTo:function(a,b,c){"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=10);var d=Math.pow(c,-b);return Math.round(a*d)/d},floorTo:function(a,b,c){"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=10);var d=Math.pow(c,-b);return Math.floor(a*d)/d},ceilTo:function(a,b,c){"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=10);var d=Math.pow(c,-b);return Math.ceil(a*d)/d},interpolateFloat:function(a,b,c){return(b-a)*c+a},angleBetween:function(a,b,c,d){return Math.atan2(d-b,c-a)},reverseAngle:function(a){return this.normalizeAngle(a+Math.PI,!0)},normalizeAngle:function(a){return a%=2*Math.PI,a>=0?a:a+2*Math.PI},normalizeLatitude:function(a){return Math.max(-90,Math.min(90,a))},normalizeLongitude:function(a){return 180==a%360?180:(a%=360,-180>a?a+360:a>180?a-360:a)},nearestAngleBetween:function(a,b,c){"undefined"==typeof c&&(c=!0);var d=c?Math.PI:180;return a=this.normalizeAngle(a,c),b=this.normalizeAngle(b,c),-d/2>a&&b>d/2&&(a+=2*d),-d/2>b&&a>d/2&&(b+=2*d),b-a},interpolateAngles:function(a,b,c,d,e){return"undefined"==typeof d&&(d=!0),"undefined"==typeof e&&(e=null),a=this.normalizeAngle(a,d),b=this.normalizeAngleToAnother(b,a,d),"function"==typeof e?e(c,a,b-a,1):this.interpolateFloat(a,b,c)},chanceRoll:function(a){return"undefined"==typeof a&&(a=50),0>=a?!1:a>=100?!0:100*Math.random()>=a?!1:!0},numberArray:function(a,b){for(var c=[],d=a;b>=d;d++)c.push(d);return c},maxAdd:function(a,b,c){return a+=b,a>c&&(a=c),a},minSub:function(a,b,c){return a-=b,c>a&&(a=c),a},wrap:function(a,b,c){var d=c-b;if(0>=d)return 0;var e=(a-b)%d;return 0>e&&(e+=d),e+b},wrapValue:function(a,b,c){var d;return a=Math.abs(a),b=Math.abs(b),c=Math.abs(c),d=(a+b)%c},randomSign:function(){return Math.random()>.5?1:-1},isOdd:function(a){return 1&a},isEven:function(a){return 1&a?!1:!0},max:function(){for(var a=1,b=0,c=arguments.length;c>a;a++)arguments[b]b;b++)a[b]b;b++)a[b]>a[c]&&(c=b);return a[c]},minProperty:function(a){if(2===arguments.length&&"object"==typeof arguments[1])var b=arguments[1];else var b=arguments.slice(1);for(var c=1,d=0,e=b.length;e>c;c++)b[c][a]c;c++)b[c][a]>b[d][a]&&(d=c);return b[d][a]},wrapAngle:function(a){return this.wrap(a,-180,180)},angleLimit:function(a,b,c){var d=a;return a>c?d=c:b>a&&(d=b),d},linearInterpolation:function(a,b){var c=a.length-1,d=c*b,e=Math.floor(d);return 0>b?this.linear(a[0],a[1],d):b>1?this.linear(a[c],a[c-1],c-d):this.linear(a[e],a[e+1>c?c:e+1],d-e)},bezierInterpolation:function(a,b){for(var c=0,d=a.length-1,e=0;d>=e;e++)c+=Math.pow(1-b,d-e)*Math.pow(b,e)*a[e]*this.bernstein(d,e);return c},catmullRomInterpolation:function(a,b){var c=a.length-1,d=c*b,e=Math.floor(d);return a[0]===a[c]?(0>b&&(e=Math.floor(d=c*(1+b))),this.catmullRom(a[(e-1+c)%c],a[e],a[(e+1)%c],a[(e+2)%c],d-e)):0>b?a[0]-(this.catmullRom(a[0],a[0],a[1],a[1],-d)-a[0]):b>1?a[c]-(this.catmullRom(a[c],a[c],a[c-1],a[c-1],d-c)-a[c]):this.catmullRom(a[e?e-1:0],a[e],a[e+1>c?c:e+1],a[e+2>c?c:e+2],d-e)},linear:function(a,b,c){return(b-a)*c+a},bernstein:function(a,b){return this.factorial(a)/this.factorial(b)/this.factorial(a-b)},catmullRom:function(a,b,c,d,e){var f=.5*(c-a),g=.5*(d-b),h=e*e,i=e*h;return(2*b-2*c+f+g)*i+(-3*b+3*c-2*f-g)*h+f*e+b},difference:function(a,b){return Math.abs(a-b)},getRandom:function(a,b,c){if("undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=0),null!=a){var d=c;if((0===d||d>a.length-b)&&(d=a.length-b),d>0)return a[b+Math.floor(Math.random()*d)]}return null},floor:function(a){var b=0|a;return a>0?b:b!=a?b-1:b},ceil:function(a){var b=0|a;return a>0?b!=a?b+1:b:b},sinCosGenerator:function(a,b,c,d){"undefined"==typeof b&&(b=1),"undefined"==typeof c&&(c=1),"undefined"==typeof d&&(d=1);for(var e=b,f=c,g=d*Math.PI/a,h=[],i=[],j=0;a>j;j++)f-=e*g,e+=f*g,h[j]=f,i[j]=e;return{sin:i,cos:h,length:a}},shift:function(a){var b=a.shift();return a.push(b),b},shuffleArray:function(a){for(var b=a.length-1;b>0;b--){var c=Math.floor(Math.random()*(b+1)),d=a[b];a[b]=a[c],a[c]=d}return a},distance:function(a,b,c,d){var e=a-c,f=b-d;return Math.sqrt(e*e+f*f)},distancePow:function(a,b,c,d,e){return"undefined"==typeof e&&(e=2),Math.sqrt(Math.pow(c-a,e)+Math.pow(d-b,e))},distanceRounded:function(a,b,d,e){return Math.round(c.Math.distance(a,b,d,e))},clamp:function(a,b,c){return b>a?b:a>c?c:a},clampBottom:function(a,b){return b>a?b:a},within:function(a,b,c){return Math.abs(a-b)<=c},mapLinear:function(a,b,c,d,e){return d+(a-b)*(e-d)/(c-b)},smoothstep:function(a,b,c){return b>=a?0:a>=c?1:(a=(a-b)/(c-b),a*a*(3-2*a))},smootherstep:function(a,b,c){return b>=a?0:a>=c?1:(a=(a-b)/(c-b),a*a*a*(a*(6*a-15)+10))},sign:function(a){return 0>a?-1:a>0?1:0},degToRad:function(){var a=Math.PI/180;return function(b){return b*a}}(),radToDeg:function(){var a=180/Math.PI;return function(b){return b*a}}()},c.QuadTree=function(a,b,c,d,e,f,g){this.maxObjects=e||10,this.maxLevels=f||4,this.level=g||0,this.bounds={x:Math.round(a),y:Math.round(b),width:c,height:d,subWidth:Math.floor(c/2),subHeight:Math.floor(d/2),right:Math.round(a)+Math.floor(c/2),bottom:Math.round(b)+Math.floor(d/2)},this.objects=[],this.nodes=[]},c.QuadTree.prototype={populate:function(a){a.forEach(this.populateHandler,this,!0)},populateHandler:function(a){a.body&&a.body.checkCollision.none===!1&&a.alive&&this.insert(a.body)},split:function(){this.level++,this.nodes[0]=new c.QuadTree(this.bounds.right,this.bounds.y,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level),this.nodes[1]=new c.QuadTree(this.bounds.x,this.bounds.y,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level),this.nodes[2]=new c.QuadTree(this.bounds.x,this.bounds.bottom,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level),this.nodes[3]=new c.QuadTree(this.bounds.right,this.bounds.bottom,this.bounds.subWidth,this.bounds.subHeight,this.maxObjects,this.maxLevels,this.level)},insert:function(a){var b,c=0;if(null!=this.nodes[0]&&(b=this.getIndex(a),-1!==b))return this.nodes[b].insert(a),void 0;if(this.objects.push(a),this.objects.length>this.maxObjects&&this.levelthis.bounds.bottom&&(b=2):a.x>this.bounds.right&&(a.ythis.bounds.bottom&&(b=3)),b},retrieve:function(a){var b=this.objects;return a.body.quadTreeIndex=this.getIndex(a.body),this.nodes[0]&&(-1!==a.body.quadTreeIndex?b=b.concat(this.nodes[a.body.quadTreeIndex].retrieve(a)):(b=b.concat(this.nodes[0].retrieve(a)),b=b.concat(this.nodes[1].retrieve(a)),b=b.concat(this.nodes[2].retrieve(a)),b=b.concat(this.nodes[3].retrieve(a)))),b},clear:function(){this.objects=[];for(var a=0,b=this.nodes.length;b>a;a++)this.nodes[a]&&(this.nodes[a].clear(),delete this.nodes[a])}},c.QuadTree.prototype.constructor=c.QuadTree,c.Circle=function(a,b,c){a=a||0,b=b||0,c=c||0,this.x=a,this.y=b,this._diameter=c,this._radius=c>0?.5*c:0},c.Circle.prototype={circumference:function(){return 2*Math.PI*this._radius},setTo:function(a,b,c){return this.x=a,this.y=b,this._diameter=c,this._radius=.5*c,this},copyFrom:function(a){return this.setTo(a.x,a.y,a.diameter)},copyTo:function(a){return a.x=this.x,a.y=this.y,a.diameter=this._diameter,a},distance:function(a,b){return"undefined"==typeof b&&(b=!1),b?c.Math.distanceRound(this.x,this.y,a.x,a.y):c.Math.distance(this.x,this.y,a.x,a.y)},clone:function(a){return"undefined"==typeof a&&(a=new c.Circle),a.setTo(this.x,this.y,this.diameter)},contains:function(a,b){return c.Circle.contains(this,a,b)},circumferencePoint:function(a,b,d){return c.Circle.circumferencePoint(this,a,b,d)},offset:function(a,b){return this.x+=a,this.y+=b,this},offsetPoint:function(a){return this.offset(a.x,a.y)},toString:function(){return"[{Phaser.Circle (x="+this.x+" y="+this.y+" diameter="+this.diameter+" radius="+this.radius+")}]"}},c.Circle.prototype.constructor=c.Circle,Object.defineProperty(c.Circle.prototype,"diameter",{get:function(){return this._diameter},set:function(a){a>0&&(this._diameter=a,this._radius=.5*a)}}),Object.defineProperty(c.Circle.prototype,"radius",{get:function(){return this._radius},set:function(a){a>0&&(this._radius=a,this._diameter=2*a)}}),Object.defineProperty(c.Circle.prototype,"left",{get:function(){return this.x-this._radius},set:function(a){a>this.x?(this._radius=0,this._diameter=0):this.radius=this.x-a}}),Object.defineProperty(c.Circle.prototype,"right",{get:function(){return this.x+this._radius},set:function(a){athis.y?(this._radius=0,this._diameter=0):this.radius=this.y-a}}),Object.defineProperty(c.Circle.prototype,"bottom",{get:function(){return this.y+this._radius},set:function(a){a0?Math.PI*this._radius*this._radius:0}}),Object.defineProperty(c.Circle.prototype,"empty",{get:function(){return 0===this._diameter},set:function(a){a===!0&&this.setTo(0,0,0)}}),c.Circle.contains=function(a,b,c){if(b>=a.left&&b<=a.right&&c>=a.top&&c<=a.bottom){var d=(a.x-b)*(a.x-b),e=(a.y-c)*(a.y-c);return d+e<=a.radius*a.radius}return!1},c.Circle.equals=function(a,b){return a.x==b.x&&a.y==b.y&&a.diameter==b.diameter},c.Circle.intersects=function(a,b){return c.Math.distance(a.x,a.y,b.x,b.y)<=a.radius+b.radius},c.Circle.circumferencePoint=function(a,b,d,e){return"undefined"==typeof d&&(d=!1),"undefined"==typeof e&&(e=new c.Point),d===!0&&(b=c.Math.radToDeg(b)),e.x=a.x+a.radius*Math.cos(b),e.y=a.y+a.radius*Math.sin(b),e},c.Circle.intersectsRectangle=function(a,b){var c=Math.abs(a.x-b.x-b.halfWidth),d=b.halfWidth+a.radius;if(c>d)return!1;var e=Math.abs(a.y-b.y-b.halfHeight),f=b.halfHeight+a.radius;if(e>f)return!1;if(c<=b.halfWidth||e<=b.halfHeight)return!0;var g=c-b.halfWidth,h=e-b.halfHeight,i=g*g,j=h*h,k=a.radius*a.radius;return k>=i+j},c.Point=function(a,b){a=a||0,b=b||0,this.x=a,this.y=b},c.Point.prototype={copyFrom:function(a){return this.setTo(a.x,a.y)},invert:function(){return this.setTo(this.y,this.x)},setTo:function(a,b){return this.x=a,this.y=b,this},add:function(a,b){return this.x+=a,this.y+=b,this},subtract:function(a,b){return this.x-=a,this.y-=b,this},multiply:function(a,b){return this.x*=a,this.y*=b,this},divide:function(a,b){return this.x/=a,this.y/=b,this},clampX:function(a,b){return this.x=c.Math.clamp(this.x,a,b),this},clampY:function(a,b){return this.y=c.Math.clamp(this.y,a,b),this},clamp:function(a,b){return this.x=c.Math.clamp(this.x,a,b),this.y=c.Math.clamp(this.y,a,b),this},clone:function(a){return"undefined"==typeof a&&(a=new c.Point),a.setTo(this.x,this.y)},copyTo:function(a){return a.x=this.x,a.y=this.y,a},distance:function(a,b){return c.Point.distance(this,a,b)},equals:function(a){return a.x==this.x&&a.y==this.y},rotate:function(a,b,d,e,f){return c.Point.rotate(this,a,b,d,e,f)},getMagnitude:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},setMagnitude:function(a){return this.normalize().multiply(a,a)},normalize:function(){if(!this.isZero()){var a=this.getMagnitude();this.x/=a,this.y/=a}return this},isZero:function(){return 0===this.x&&0===this.y},toString:function(){return"[{Point (x="+this.x+" y="+this.y+")}]"}},c.Point.prototype.constructor=c.Point,c.Point.add=function(a,b,d){return"undefined"==typeof d&&(d=new c.Point),d.x=a.x+b.x,d.y=a.y+b.y,d},c.Point.subtract=function(a,b,d){return"undefined"==typeof d&&(d=new c.Point),d.x=a.x-b.x,d.y=a.y-b.y,d},c.Point.multiply=function(a,b,d){return"undefined"==typeof d&&(d=new c.Point),d.x=a.x*b.x,d.y=a.y*b.y,d},c.Point.divide=function(a,b,d){return"undefined"==typeof d&&(d=new c.Point),d.x=a.x/b.x,d.y=a.y/b.y,d},c.Point.equals=function(a,b){return a.x==b.x&&a.y==b.y},c.Point.distance=function(a,b,d){return"undefined"==typeof d&&(d=!1),d?c.Math.distanceRound(a.x,a.y,b.x,b.y):c.Math.distance(a.x,a.y,b.x,b.y)},c.Point.rotate=function(a,b,d,e,f,g){return f=f||!1,g=g||null,f&&(e=c.Math.degToRad(e)),null===g&&(g=Math.sqrt((b-a.x)*(b-a.x)+(d-a.y)*(d-a.y))),a.setTo(b+g*Math.cos(e),d+g*Math.sin(e))},c.Rectangle=function(a,b,c,d){a=a||0,b=b||0,c=c||0,d=d||0,this.x=a,this.y=b,this.width=c,this.height=d},c.Rectangle.prototype={offset:function(a,b){return this.x+=a,this.y+=b,this},offsetPoint:function(a){return this.offset(a.x,a.y)},setTo:function(a,b,c,d){return this.x=a,this.y=b,this.width=c,this.height=d,this},floor:function(){this.x=Math.floor(this.x),this.y=Math.floor(this.y)},floorAll:function(){this.x=Math.floor(this.x),this.y=Math.floor(this.y),this.width=Math.floor(this.width),this.height=Math.floor(this.height)},copyFrom:function(a){return this.setTo(a.x,a.y,a.width,a.height)},copyTo:function(a){return a.x=this.x,a.y=this.y,a.width=this.width,a.height=this.height,a},inflate:function(a,b){return c.Rectangle.inflate(this,a,b)},size:function(a){return c.Rectangle.size(this,a)},clone:function(a){return c.Rectangle.clone(this,a)},contains:function(a,b){return c.Rectangle.contains(this,a,b)},containsRect:function(a){return c.Rectangle.containsRect(this,a)},equals:function(a){return c.Rectangle.equals(this,a)},intersection:function(a,b){return c.Rectangle.intersection(this,a,b)},intersects:function(a,b){return c.Rectangle.intersects(this,a,b)},intersectsRaw:function(a,b,d,e,f){return c.Rectangle.intersectsRaw(this,a,b,d,e,f)},union:function(a,b){return c.Rectangle.union(this,a,b)},toString:function(){return"[{Rectangle (x="+this.x+" y="+this.y+" width="+this.width+" height="+this.height+" empty="+this.empty+")}]"}},c.Rectangle.prototype.constructor=c.Rectangle,Object.defineProperty(c.Rectangle.prototype,"halfWidth",{get:function(){return Math.round(this.width/2)}}),Object.defineProperty(c.Rectangle.prototype,"halfHeight",{get:function(){return Math.round(this.height/2)}}),Object.defineProperty(c.Rectangle.prototype,"bottom",{get:function(){return this.y+this.height},set:function(a){this.height=a<=this.y?0:this.y-a}}),Object.defineProperty(c.Rectangle.prototype,"bottomRight",{get:function(){return new c.Point(this.right,this.bottom)},set:function(a){this.right=a.x,this.bottom=a.y}}),Object.defineProperty(c.Rectangle.prototype,"left",{get:function(){return this.x},set:function(a){this.width=a>=this.right?0:this.right-a,this.x=a}}),Object.defineProperty(c.Rectangle.prototype,"right",{get:function(){return this.x+this.width},set:function(a){this.width=a<=this.x?0:this.x+a}}),Object.defineProperty(c.Rectangle.prototype,"volume",{get:function(){return this.width*this.height}}),Object.defineProperty(c.Rectangle.prototype,"perimeter",{get:function(){return 2*this.width+2*this.height}}),Object.defineProperty(c.Rectangle.prototype,"centerX",{get:function(){return this.x+this.halfWidth},set:function(a){this.x=a-this.halfWidth}}),Object.defineProperty(c.Rectangle.prototype,"centerY",{get:function(){return this.y+this.halfHeight},set:function(a){this.y=a-this.halfHeight}}),Object.defineProperty(c.Rectangle.prototype,"top",{get:function(){return this.y},set:function(a){a>=this.bottom?(this.height=0,this.y=a):this.height=this.bottom-a}}),Object.defineProperty(c.Rectangle.prototype,"topLeft",{get:function(){return new c.Point(this.x,this.y)},set:function(a){this.x=a.x,this.y=a.y}}),Object.defineProperty(c.Rectangle.prototype,"empty",{get:function(){return!this.width||!this.height},set:function(a){a===!0&&this.setTo(0,0,0,0)}}),c.Rectangle.inflate=function(a,b,c){return a.x-=b,a.width+=2*b,a.y-=c,a.height+=2*c,a},c.Rectangle.inflatePoint=function(a,b){return c.Rectangle.inflate(a,b.x,b.y)},c.Rectangle.size=function(a,b){return"undefined"==typeof b&&(b=new c.Point),b.setTo(a.width,a.height)},c.Rectangle.clone=function(a,b){return"undefined"==typeof b&&(b=new c.Rectangle),b.setTo(a.x,a.y,a.width,a.height)},c.Rectangle.contains=function(a,b,c){return b>=a.x&&b<=a.right&&c>=a.y&&c<=a.bottom},c.Rectangle.containsRaw=function(a,b,c,d,e,f){return e>=a&&a+c>=e&&f>=b&&b+d>=f},c.Rectangle.containsPoint=function(a,b){return c.Rectangle.contains(a,b.x,b.y)},c.Rectangle.containsRect=function(a,b){return a.volume>b.volume?!1:a.x>=b.x&&a.y>=b.y&&a.right<=b.right&&a.bottom<=b.bottom},c.Rectangle.equals=function(a,b){return a.x==b.x&&a.y==b.y&&a.width==b.width&&a.height==b.height},c.Rectangle.intersection=function(a,b,d){return d=d||new c.Rectangle,c.Rectangle.intersects(a,b)&&(d.x=Math.max(a.x,b.x),d.y=Math.max(a.y,b.y),d.width=Math.min(a.right,b.right)-d.x,d.height=Math.min(a.bottom,b.bottom)-d.y),d},c.Rectangle.intersects=function(a,b){return a.width<=0||a.height<=0||b.width<=0||b.height<=0?!1:!(a.rightb.right||a.y>b.bottom)},c.Rectangle.intersectsRaw=function(a,b,c,d,e,f){return"undefined"==typeof f&&(f=0),!(b>a.right+f||ca.bottom+f||e1){if(a&&a==this.decodeURI(e[0]))return this.decodeURI(e[1]);b[this.decodeURI(e[0])]=this.decodeURI(e[1])}}return b},decodeURI:function(a){return decodeURIComponent(a.replace(/\+/g," "))}},c.Net.prototype.constructor=c.Net,c.TweenManager=function(a){this.game=a,this._tweens=[],this._add=[],this.game.onPause.add(this.pauseAll,this),this.game.onResume.add(this.resumeAll,this)},c.TweenManager.prototype={getAll:function(){return this._tweens},removeAll:function(){for(var a=0;aa;)this._tweens[a].update(this.game.time.now)?a++:(this._tweens.splice(a,1),b--);return this._add.length>0&&(this._tweens=this._tweens.concat(this._add),this._add.length=0),!0},isTweening:function(a){return this._tweens.some(function(b){return b._object===a})},pauseAll:function(){for(var a=this._tweens.length-1;a>=0;a--)this._tweens[a].pause()},resumeAll:function(){for(var a=this._tweens.length-1;a>=0;a--)this._tweens[a].resume()}},c.TweenManager.prototype.constructor=c.TweenManager,c.Tween=function(a,b){this._object=a,this.game=b,this._manager=this.game.tweens,this._valuesStart={},this._valuesEnd={},this._valuesStartRepeat={},this._duration=1e3,this._repeat=0,this._yoyo=!1,this._reversed=!1,this._delayTime=0,this._startTime=null,this._easingFunction=c.Easing.Linear.None,this._interpolationFunction=c.Math.linearInterpolation,this._chainedTweens=[],this._onStartCallbackFired=!1,this._onUpdateCallback=null,this._onUpdateCallbackContext=null,this._pausedTime=0,this.pendingDelete=!1;for(var d in a)this._valuesStart[d]=parseFloat(a[d],10);this.onStart=new c.Signal,this.onLoop=new c.Signal,this.onComplete=new c.Signal,this.isRunning=!1},c.Tween.prototype={to:function(a,b,c,d,e,f,g){b=b||1e3,c=c||null,d=d||!1,e=e||0,f=f||0,g=g||!1;var h;return this._parent?(h=this._manager.create(this._object),this._lastChild.chain(h),this._lastChild=h):(h=this,this._parent=this,this._lastChild=this),h._repeat=f,h._duration=b,h._valuesEnd=a,null!==c&&(h._easingFunction=c),e>0&&(h._delayTime=e),h._yoyo=g,d?this.start():this},start:function(){if(null!==this.game&&null!==this._object){this._manager.add(this),this.isRunning=!0,this._onStartCallbackFired=!1,this._startTime=this.game.time.now+this._delayTime;for(var a in this._valuesEnd){if(this._valuesEnd[a]instanceof Array){if(0===this._valuesEnd[a].length)continue;this._valuesEnd[a]=[this._object[a]].concat(this._valuesEnd[a])}this._valuesStart[a]=this._object[a],this._valuesStart[a]instanceof Array==!1&&(this._valuesStart[a]*=1),this._valuesStartRepeat[a]=this._valuesStart[a]||0}return this}},stop:function(){return this.isRunning=!1,this._onUpdateCallback=null,this._manager.remove(this),this},delay:function(a){return this._delayTime=a,this},repeat:function(a){return this._repeat=a,this},yoyo:function(a){return this._yoyo=a,this},easing:function(a){return this._easingFunction=a,this},interpolation:function(a){return this._interpolationFunction=a,this},chain:function(){return this._chainedTweens=arguments,this},loop:function(){return this._lastChild.chain(this),this},onUpdateCallback:function(a,b){return this._onUpdateCallback=a,this._onUpdateCallbackContext=b,this},pause:function(){this._paused=!0,this._pausedTime=this.game.time.now},resume:function(){this._paused=!1,this._startTime+=this.game.time.now-this._pausedTime},update:function(a){if(this.pendingDelete)return!1;if(this._paused||a1?1:c;var d=this._easingFunction(c);for(b in this._valuesEnd){var e=this._valuesStart[b]||0,f=this._valuesEnd[b];f instanceof Array?this._object[b]=this._interpolationFunction(f,d):("string"==typeof f&&(f=e+parseFloat(f,10)),"number"==typeof f&&(this._object[b]=e+(f-e)*d))}if(null!==this._onUpdateCallback&&this._onUpdateCallback.call(this._onUpdateCallbackContext,this,d),1==c){if(this._repeat>0){isFinite(this._repeat)&&this._repeat--;for(b in this._valuesStartRepeat){if("string"==typeof this._valuesEnd[b]&&(this._valuesStartRepeat[b]=this._valuesStartRepeat[b]+parseFloat(this._valuesEnd[b],10)),this._yoyo){var g=this._valuesStartRepeat[b];this._valuesStartRepeat[b]=this._valuesEnd[b],this._valuesEnd[b]=g,this._reversed=!this._reversed}this._valuesStart[b]=this._valuesStartRepeat[b]}return this._startTime=a+this._delayTime,this.onLoop.dispatch(this._object),!0}this.isRunning=!1,this.onComplete.dispatch(this._object);for(var h=0,i=this._chainedTweens.length;i>h;h++)this._chainedTweens[h].start(a);return!1}return!0}},c.Tween.prototype.constructor=c.Tween,c.Easing={Linear:{None:function(a){return a}},Quadratic:{In:function(a){return a*a},Out:function(a){return a*(2-a)},InOut:function(a){return(a*=2)<1?.5*a*a:-.5*(--a*(a-2)-1)}},Cubic:{In:function(a){return a*a*a},Out:function(a){return--a*a*a+1},InOut:function(a){return(a*=2)<1?.5*a*a*a:.5*((a-=2)*a*a+2)}},Quartic:{In:function(a){return a*a*a*a},Out:function(a){return 1- --a*a*a*a},InOut:function(a){return(a*=2)<1?.5*a*a*a*a:-.5*((a-=2)*a*a*a-2)}},Quintic:{In:function(a){return a*a*a*a*a},Out:function(a){return--a*a*a*a*a+1},InOut:function(a){return(a*=2)<1?.5*a*a*a*a*a:.5*((a-=2)*a*a*a*a+2)}},Sinusoidal:{In:function(a){return 1-Math.cos(a*Math.PI/2)},Out:function(a){return Math.sin(a*Math.PI/2)},InOut:function(a){return.5*(1-Math.cos(Math.PI*a))}},Exponential:{In:function(a){return 0===a?0:Math.pow(1024,a-1)},Out:function(a){return 1===a?1:1-Math.pow(2,-10*a)},InOut:function(a){return 0===a?0:1===a?1:(a*=2)<1?.5*Math.pow(1024,a-1):.5*(-Math.pow(2,-10*(a-1))+2)}},Circular:{In:function(a){return 1-Math.sqrt(1-a*a)},Out:function(a){return Math.sqrt(1- --a*a)},InOut:function(a){return(a*=2)<1?-.5*(Math.sqrt(1-a*a)-1):.5*(Math.sqrt(1-(a-=2)*a)+1)}},Elastic:{In:function(a){var b,c=.1,d=.4;return 0===a?0:1===a?1:(!c||1>c?(c=1,b=d/4):b=d*Math.asin(1/c)/(2*Math.PI),-(c*Math.pow(2,10*(a-=1))*Math.sin((a-b)*2*Math.PI/d)))},Out:function(a){var b,c=.1,d=.4;return 0===a?0:1===a?1:(!c||1>c?(c=1,b=d/4):b=d*Math.asin(1/c)/(2*Math.PI),c*Math.pow(2,-10*a)*Math.sin((a-b)*2*Math.PI/d)+1)},InOut:function(a){var b,c=.1,d=.4;return 0===a?0:1===a?1:(!c||1>c?(c=1,b=d/4):b=d*Math.asin(1/c)/(2*Math.PI),(a*=2)<1?-.5*c*Math.pow(2,10*(a-=1))*Math.sin((a-b)*2*Math.PI/d):.5*c*Math.pow(2,-10*(a-=1))*Math.sin((a-b)*2*Math.PI/d)+1)}},Back:{In:function(a){var b=1.70158;return a*a*((b+1)*a-b)},Out:function(a){var b=1.70158;return--a*a*((b+1)*a+b)+1},InOut:function(a){var b=2.5949095;return(a*=2)<1?.5*a*a*((b+1)*a-b):.5*((a-=2)*a*((b+1)*a+b)+2)}},Bounce:{In:function(a){return 1-c.Easing.Bounce.Out(1-a)},Out:function(a){return 1/2.75>a?7.5625*a*a:2/2.75>a?7.5625*(a-=1.5/2.75)*a+.75:2.5/2.75>a?7.5625*(a-=2.25/2.75)*a+.9375:7.5625*(a-=2.625/2.75)*a+.984375},InOut:function(a){return.5>a?.5*c.Easing.Bounce.In(2*a):.5*c.Easing.Bounce.Out(2*a-1)+.5}}},c.Time=function(a){this.game=a,this.time=0,this.now=0,this.elapsed=0,this.pausedTime=0,this.fps=0,this.fpsMin=1e3,this.fpsMax=0,this.msMin=1e3,this.msMax=0,this.physicsElapsed=0,this.frames=0,this.pauseDuration=0,this.timeToCall=0,this.lastTime=0,this.events=new c.Timer(this.game,!1),this._started=0,this._timeLastSecond=0,this._pauseStarted=0,this._justResumed=!1,this._timers=[],this._len=0,this._i=0,this.game.onPause.add(this.gamePaused,this),this.game.onResume.add(this.gameResumed,this)},c.Time.prototype={boot:function(){this.events.start()},create:function(a){"undefined"==typeof a&&(a=!0);var b=new c.Timer(this.game,a);return this._timers.push(b),b},removeAll:function(){for(var a=0;athis._timeLastSecond+1e3&&(this.fps=Math.round(1e3*this.frames/(this.now-this._timeLastSecond)),this.fpsMin=this.game.math.min(this.fpsMin,this.fps),this.fpsMax=this.game.math.max(this.fpsMax,this.fps),this._timeLastSecond=this.now,this.frames=0),this.time=this.now,this.lastTime=a+this.timeToCall,this.physicsElapsed=1*(this.elapsed/1e3),this.physicsElapsed>.05&&(this.physicsElapsed=.05),this.game.paused)this.pausedTime=this.now-this._pauseStarted;else for(this.events.update(this.now),this._i=0,this._len=this._timers.length;this._i0&&(this.events.sort(this.sortHandler),this.nextTick=this.events[0].tick)},sortHandler:function(a,b){return a.tickb.tick?1:0},update:function(a){if(this.paused)return!0;if(this._now=a-this._started,this._len=this.events.length,this.running&&this._now>=this.nextTick&&this._len>0){for(this._i=0;this._i=this.events[this._i].tick;)this.events[this._i].loop===!0?(this.events[this._i].tick+=this.events[this._i].delay-(this._now-this.events[this._i].tick),this.events[this._i].callback.apply(this.events[this._i].callbackContext,this.events[this._i].args)):this.events[this._i].repeatCount>0?(this.events[this._i].repeatCount--,this.events[this._i].tick+=this.events[this._i].delay-(this._now-this.events[this._i].tick),this.events[this._i].callback.apply(this.events[this._i].callbackContext,this.events[this._i].args)):(this.events[this._i].callback.apply(this.events[this._i].callbackContext,this.events[this._i].args),this.events.splice(this._i,1),this._len--),this._i++;this.events.length>0?this.order():(this.expired=!0,this.onComplete.dispatch(this))}return this.expired&&this.autoDestroy?!1:!0},pause:function(){this._pauseStarted=this.game.time.now,this.paused=!0},resume:function(){for(var a=this.game.time.now-this._pauseStarted,b=0;bthis._now?this.nextTick-this._now:0}}),Object.defineProperty(c.Timer.prototype,"length",{get:function(){return this.events.length}}),Object.defineProperty(c.Timer.prototype,"ms",{get:function(){return this._now}}),Object.defineProperty(c.Timer.prototype,"seconds",{get:function(){return.001*this._now}}),c.Timer.prototype.constructor=c.Timer,c.TimerEvent=function(a,b,c,d,e,f,g,h){this.timer=a,this.delay=b,this.tick=c,this.repeatCount=d-1,this.loop=e,this.callback=f,this.callbackContext=g,this.args=h},c.TimerEvent.prototype.constructor=c.TimerEvent,c.AnimationManager=function(a){this.sprite=a,this.game=a.game,this.currentFrame=null,this.updateIfVisible=!0,this.isLoaded=!1,this._frameData=null,this._anims={},this._outputFrames=[]},c.AnimationManager.prototype={loadFrameData:function(a){this._frameData=a,this.frame=0,this.isLoaded=!0},add:function(a,d,e,f,g){return null==this._frameData?(console.warn("No FrameData available for Phaser.Animation "+a),void 0):(e=e||60,"undefined"==typeof f&&(f=!1),"undefined"==typeof g&&(g=d&&"number"==typeof d[0]?!0:!1),null==this.sprite.events.onAnimationStart&&(this.sprite.events.onAnimationStart=new c.Signal,this.sprite.events.onAnimationComplete=new c.Signal,this.sprite.events.onAnimationLoop=new c.Signal),this._outputFrames.length=0,this._frameData.getFrameIndexes(d,g,this._outputFrames),this._anims[a]=new c.Animation(this.game,this.sprite,a,this._frameData,this._outputFrames,e,f),this.currentAnim=this._anims[a],this.currentFrame=this.currentAnim.currentFrame,this.sprite.setTexture(b.TextureCache[this.currentFrame.uuid]),this._anims[a])},validateFrames:function(a,b){"undefined"==typeof b&&(b=!0);for(var c=0;cthis._frameData.total)return!1}else if(this._frameData.checkFrameName(a[c])===!1)return!1;return!0},play:function(a,b,c,d){if(this._anims[a]){if(this.currentAnim!=this._anims[a])return this.currentAnim=this._anims[a],this.currentAnim.paused=!1,this.currentAnim.play(b,c,d);if(this.currentAnim.isPlaying===!1)return this.currentAnim.paused=!1,this.currentAnim.play(b,c,d)}},stop:function(a,b){"undefined"==typeof b&&(b=!1),"string"==typeof a?this._anims[a]&&(this.currentAnim=this._anims[a],this.currentAnim.stop(b)):this.currentAnim&&this.currentAnim.stop(b)},update:function(){return this.updateIfVisible&&this.sprite.visible===!1?!1:this.currentAnim&&this.currentAnim.update()===!0?(this.currentFrame=this.currentAnim.currentFrame,this.sprite.currentFrame=this.currentFrame,!0):!1},getAnimation:function(a){return"string"==typeof a&&this._anims[a]?this._anims[a]:null},refreshFrame:function(){this.sprite.currentFrame=this.currentFrame,this.sprite.setTexture(b.TextureCache[this.currentFrame.uuid])},destroy:function(){this._anims={},this._frameData=null,this._frameIndex=0,this.currentAnim=null,this.currentFrame=null}},c.AnimationManager.prototype.constructor=c.AnimationManager,Object.defineProperty(c.AnimationManager.prototype,"frameData",{get:function(){return this._frameData}}),Object.defineProperty(c.AnimationManager.prototype,"frameTotal",{get:function(){return this._frameData?this._frameData.total:-1}}),Object.defineProperty(c.AnimationManager.prototype,"paused",{get:function(){return this.currentAnim.isPaused},set:function(a){this.currentAnim.paused=a}}),Object.defineProperty(c.AnimationManager.prototype,"frame",{get:function(){return this.currentFrame?this._frameIndex:void 0},set:function(a){"number"==typeof a&&this._frameData&&null!==this._frameData.getFrame(a)&&(this.currentFrame=this._frameData.getFrame(a),this._frameIndex=a,this.sprite.currentFrame=this.currentFrame,this.sprite.setTexture(b.TextureCache[this.currentFrame.uuid]))}}),Object.defineProperty(c.AnimationManager.prototype,"frameName",{get:function(){return this.currentFrame?this.currentFrame.name:void 0},set:function(a){"string"==typeof a&&this._frameData&&null!==this._frameData.getFrameByName(a)?(this.currentFrame=this._frameData.getFrameByName(a),this._frameIndex=this.currentFrame.index,this.sprite.currentFrame=this.currentFrame,this.sprite.setTexture(b.TextureCache[this.currentFrame.uuid])):console.warn("Cannot set frameName: "+a)}}),c.Animation=function(a,b,c,d,e,f,g){this.game=a,this._parent=b,this._frameData=d,this.name=c,this._frames=[],this._frames=this._frames.concat(e),this.delay=1e3/f,this.looped=g,this.killOnComplete=!1,this.isFinished=!1,this.isPlaying=!1,this.isPaused=!1,this._pauseStartTime=0,this._frameIndex=0,this._frameDiff=0,this._frameSkip=1,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex])},c.Animation.prototype={play:function(a,c,d){return"number"==typeof a&&(this.delay=1e3/a),"boolean"==typeof c&&(this.looped=c),"undefined"!=typeof d&&(this.killOnComplete=d),this.isPlaying=!0,this.isFinished=!1,this.paused=!1,this._timeLastFrame=this.game.time.now,this._timeNextFrame=this.game.time.now+this.delay,this._frameIndex=0,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this._parent.setTexture(b.TextureCache[this.currentFrame.uuid]),this._parent.events&&this._parent.events.onAnimationStart.dispatch(this._parent,this),this},restart:function(){this.isPlaying=!0,this.isFinished=!1,this.paused=!1,this._timeLastFrame=this.game.time.now,this._timeNextFrame=this.game.time.now+this.delay,this._frameIndex=0,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex])},stop:function(a){"undefined"==typeof a&&(a=!1),this.isPlaying=!1,this.isFinished=!0,this.paused=!1,a&&(this.currentFrame=this._frameData.getFrame(this._frames[0]))},update:function(){return this.isPaused?!1:this.isPlaying===!0&&this.game.time.now>=this._timeNextFrame?(this._frameSkip=1,this._frameDiff=this.game.time.now-this._timeNextFrame,this._timeLastFrame=this.game.time.now,this._frameDiff>this.delay&&(this._frameSkip=Math.floor(this._frameDiff/this.delay),this._frameDiff-=this._frameSkip*this.delay),this._timeNextFrame=this.game.time.now+(this.delay-this._frameDiff),this._frameIndex+=this._frameSkip,this._frameIndex>=this._frames.length?this.looped?(this._frameIndex%=this._frames.length,this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.currentFrame&&this._parent.setTexture(b.TextureCache[this.currentFrame.uuid]),this._parent.events.onAnimationLoop.dispatch(this._parent,this)):this.onComplete():(this.currentFrame=this._frameData.getFrame(this._frames[this._frameIndex]),this.currentFrame&&this._parent.setTexture(b.TextureCache[this.currentFrame.uuid])),!0):!1},destroy:function(){this.game=null,this._parent=null,this._frames=null,this._frameData=null,this.currentFrame=null,this.isPlaying=!1},onComplete:function(){this.isPlaying=!1,this.isFinished=!0,this.paused=!1,this._parent.events&&this._parent.events.onAnimationComplete.dispatch(this._parent,this),this.killOnComplete&&this._parent.kill()}},c.Animation.prototype.constructor=c.Animation,Object.defineProperty(c.Animation.prototype,"paused",{get:function(){return this.isPaused},set:function(a){this.isPaused=a,a?this._pauseStartTime=this.game.time.now:this.isPlaying&&(this._timeNextFrame=this.game.time.now+this.delay)}}),Object.defineProperty(c.Animation.prototype,"frameTotal",{get:function(){return this._frames.length}}),Object.defineProperty(c.Animation.prototype,"frame",{get:function(){return null!==this.currentFrame?this.currentFrame.index:this._frameIndex},set:function(a){this.currentFrame=this._frameData.getFrame(a),null!==this.currentFrame&&(this._frameIndex=a,this._parent.setTexture(b.TextureCache[this.currentFrame.uuid]))}}),c.Animation.generateFrameNames=function(a,b,d,e,f){"undefined"==typeof e&&(e="");var g=[],h="";if(d>b)for(var i=b;d>=i;i++)h="number"==typeof f?c.Utils.pad(i.toString(),f,"0",1):i.toString(),h=a+h+e,g.push(h);else for(var i=b;i>=d;i--)h="number"==typeof f?c.Utils.pad(i.toString(),f,"0",1):i.toString(),h=a+h+e,g.push(h);return g},c.Frame=function(a,b,d,e,f,g,h){this.index=a,this.x=b,this.y=d,this.width=e,this.height=f,this.name=g,this.uuid=h,this.centerX=Math.floor(e/2),this.centerY=Math.floor(f/2),this.distance=c.Math.distance(0,0,e,f),this.rotated=!1,this.rotationDirection="cw",this.trimmed=!1,this.sourceSizeW=e,this.sourceSizeH=f,this.spriteSourceSizeX=0,this.spriteSourceSizeY=0,this.spriteSourceSizeW=0,this.spriteSourceSizeH=0},c.Frame.prototype={setTrim:function(a,b,c,d,e,f,g){this.trimmed=a,a&&(this.width=b,this.height=c,this.sourceSizeW=b,this.sourceSizeH=c,this.centerX=Math.floor(b/2),this.centerY=Math.floor(c/2),this.spriteSourceSizeX=d,this.spriteSourceSizeY=e,this.spriteSourceSizeW=f,this.spriteSourceSizeH=g)}},c.Frame.prototype.constructor=c.Frame,c.FrameData=function(){this._frames=[],this._frameNames=[]},c.FrameData.prototype={addFrame:function(a){return a.index=this._frames.length,this._frames.push(a),""!==a.name&&(this._frameNames[a.name]=a.index),a},getFrame:function(a){return this._frames.length>a?this._frames[a]:null},getFrameByName:function(a){return"number"==typeof this._frameNames[a]?this._frames[this._frameNames[a]]:null},checkFrameName:function(a){return null==this._frameNames[a]?!1:!0},getFrameRange:function(a,b,c){"undefined"==typeof c&&(c=[]);for(var d=a;b>=d;d++)c.push(this._frames[d]);return c},getFrames:function(a,b,c){if("undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=[]),"undefined"==typeof a||0===a.length)for(var d=0;dd;d++)b?c.push(this.getFrame(a[d])):c.push(this.getFrameByName(a[d]));return c},getFrameIndexes:function(a,b,c){if("undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=[]),"undefined"==typeof a||0===a.length)for(var d=0,e=this._frames.length;e>d;d++)c.push(this._frames[d].index);else for(var d=0,e=a.length;e>d;d++)b?c.push(a[d]):this.getFrameByName(a[d])&&c.push(this.getFrameByName(a[d]).index);return c}},c.FrameData.prototype.constructor=c.FrameData,Object.defineProperty(c.FrameData.prototype,"total",{get:function(){return this._frames.length}}),c.AnimationParser={spriteSheet:function(a,d,e,f,g,h,i){var j=a.cache.getImage(d);if(null==j)return null;var k=j.width,l=j.height;0>=e&&(e=Math.floor(-k/Math.min(-1,e))),0>=f&&(f=Math.floor(-l/Math.min(-1,f)));var m=Math.round(k/e),n=Math.round(l/f),o=m*n;if(-1!==g&&(o=g),0===k||0===l||e>k||f>l||0===o)return console.warn("Phaser.AnimationParser.spriteSheet: width/height zero or width/height < given frameWidth/frameHeight"),null;for(var p=new c.FrameData,q=h,r=h,s=0;o>s;s++){var t=a.rnd.uuid();p.addFrame(new c.Frame(s,q,r,e,f,"",t)),b.TextureCache[t]=new b.Texture(b.BaseTextureCache[d],{x:q,y:r,width:e,height:f}),q+=e+i,q===k&&(q=h,r+=f+i)}return p},JSONData:function(a,d,e){if(!d.frames)return console.warn("Phaser.AnimationParser.JSONData: Invalid Texture Atlas JSON given, missing 'frames' array"),console.log(d),void 0;for(var f,g=new c.FrameData,h=d.frames,i=0;i tag"),void 0;for(var f,g,h,i,j,k,l,m,n,o,p,q,r=new c.FrameData,s=d.getElementsByTagName("SubTexture"),t=0;t0)for(var c=0;c0)for(var c=0;c0?(this._fileIndex=0,this._progressChunk=100/this._fileList.length,this.loadFile()):(this.progress=100,this.progressFloat=100,this.hasLoaded=!0,this.onLoadComplete.dispatch()))},loadFile:function(){if(!this._fileList[this._fileIndex])return console.warn("Phaser.Loader loadFile invalid index "+this._fileIndex),void 0;var a=this._fileList[this._fileIndex],b=this;switch(a.type){case"image":case"spritesheet":case"textureatlas":case"bitmapfont":a.data=new Image,a.data.name=a.key,a.data.onload=function(){return b.fileComplete(b._fileIndex)},a.data.onerror=function(){return b.fileError(b._fileIndex)},a.data.crossOrigin=this.crossOrigin,a.data.src=this.baseURL+a.url;break;case"audio":a.url=this.getAudioURL(a.url),null!==a.url?this.game.sound.usingWebAudio?(this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="arraybuffer",this._xhr.onload=function(){return b.fileComplete(b._fileIndex)},this._xhr.onerror=function(){return b.fileError(b._fileIndex)},this._xhr.send()):this.game.sound.usingAudioTag&&(this.game.sound.touchLocked?(a.data=new Audio,a.data.name=a.key,a.data.preload="auto",a.data.src=this.baseURL+a.url,this.fileComplete(this._fileIndex)):(a.data=new Audio,a.data.name=a.key,a.data.onerror=function(){return b.fileError(b._fileIndex)},a.data.preload="auto",a.data.src=this.baseURL+a.url,a.data.addEventListener("canplaythrough",c.GAMES[this.game.id].load.fileComplete(this._fileIndex),!1),a.data.load())):this.fileError(this._fileIndex);break;case"tilemap":if(this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="text",a.format===c.Tilemap.TILED_JSON)this._xhr.onload=function(){return b.jsonLoadComplete(b._fileIndex)};else{if(a.format!==c.Tilemap.CSV)throw new Error("Phaser.Loader. Invalid Tilemap format: "+a.format);this._xhr.onload=function(){return b.csvLoadComplete(b._fileIndex)}}this._xhr.onerror=function(){return b.dataLoadError(b._fileIndex)},this._xhr.send();break;case"text":case"script":this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="text",this._xhr.onload=function(){return b.fileComplete(b._fileIndex)},this._xhr.onerror=function(){return b.fileError(b._fileIndex)},this._xhr.send();break;case"binary":this._xhr.open("GET",this.baseURL+a.url,!0),this._xhr.responseType="arraybuffer",this._xhr.onload=function(){return b.fileComplete(b._fileIndex)},this._xhr.onerror=function(){return b.fileError(b._fileIndex)},this._xhr.send()}},getAudioURL:function(a){var b;"string"==typeof a&&(a=[a]);for(var c=0;c100&&(this.progress=100),null!==this.preloadSprite&&(0===this.preloadSprite.direction?this.preloadSprite.crop.width=Math.floor(this.preloadSprite.width/100*this.progress):this.preloadSprite.crop.height=Math.floor(this.preloadSprite.height/100*this.progress),this.preloadSprite.sprite.crop=this.preloadSprite.crop),this.onFileComplete.dispatch(this.progress,this._fileList[a].key,b,this.totalLoadedFiles(),this._fileList.length),this.totalQueuedFiles()>0?(this._fileIndex++,this.loadFile()):(this.hasLoaded=!0,this.isLoading=!1,this.removeAll(),this.onLoadComplete.dispatch())},totalLoadedFiles:function(){for(var a=0,b=0;b tag"),void 0;var e=b.TextureCache[d],f={},g=c.getElementsByTagName("info")[0],h=c.getElementsByTagName("common")[0];f.font=g.attributes.getNamedItem("face").nodeValue,f.size=parseInt(g.attributes.getNamedItem("size").nodeValue,10),f.lineHeight=parseInt(h.attributes.getNamedItem("lineHeight").nodeValue,10),f.chars={};for(var i=c.getElementsByTagName("char"),j=0;j=this.durationMS&&(this.usingWebAudio?this.loop?(this.onLoop.dispatch(this),""===this.currentMarker?(this.currentTime=0,this.startTime=this.game.time.now):this.play(this.currentMarker,0,this.volume,!0,!0)):this.stop():this.loop?(this.onLoop.dispatch(this),this.play(this.currentMarker,0,this.volume,!0,!0)):this.stop()))},play:function(a,b,c,d,e){if(a=a||"",b=b||0,"undefined"==typeof c&&(c=this._volume),"undefined"==typeof d&&(d=!1),"undefined"==typeof e&&(e=!0),this.isPlaying!==!0||e!==!1||this.override!==!1){if(this.isPlaying&&this.override&&(this.usingWebAudio?"undefined"==typeof this._sound.stop?this._sound.noteOff(0):this._sound.stop(0):this.usingAudioTag&&(this._sound.pause(),this._sound.currentTime=0)),this.currentMarker=a,""!==a){if(!this.markers[a])return console.warn("Phaser.Sound.play: audio marker "+a+" doesn't exist"),void 0;this.position=this.markers[a].start,this.volume=this.markers[a].volume,this.loop=this.markers[a].loop,this.duration=this.markers[a].duration,this.durationMS=this.markers[a].durationMS,this._tempMarker=a,this._tempPosition=this.position,this._tempVolume=this.volume,this._tempLoop=this.loop}else this.position=b,this.volume=c,this.loop=d,this.duration=0,this.durationMS=0,this._tempMarker=a,this._tempPosition=b,this._tempVolume=c,this._tempLoop=d;this.usingWebAudio?this.game.cache.isSoundDecoded(this.key)?(null==this._buffer&&(this._buffer=this.game.cache.getSoundData(this.key)),this._sound=this.context.createBufferSource(),this._sound.buffer=this._buffer,this.externalNode?this._sound.connect(this.externalNode.input):this._sound.connect(this.gainNode),this.totalDuration=this._sound.buffer.duration,0===this.duration&&(this.duration=this.totalDuration,this.durationMS=1e3*this.totalDuration),this.loop&&""===a&&(this._sound.loop=!0),"undefined"==typeof this._sound.start?this._sound.noteGrainOn(0,this.position,this.duration):this._sound.start(0,this.position,this.duration),this.isPlaying=!0,this.startTime=this.game.time.now,this.currentTime=0,this.stopTime=this.startTime+this.durationMS,this.onPlay.dispatch(this)):(this.pendingPlayback=!0,this.game.cache.getSound(this.key)&&this.game.cache.getSound(this.key).isDecoding===!1&&this.game.sound.decode(this.key,this)):this.game.cache.getSound(this.key)&&this.game.cache.getSound(this.key).locked?(this.game.cache.reloadSound(this.key),this.pendingPlayback=!0):this._sound&&(this.game.device.cocoonJS||4===this._sound.readyState)?(this._sound.play(),this.totalDuration=this._sound.duration,0===this.duration&&(this.duration=this.totalDuration,this.durationMS=1e3*this.totalDuration),this._sound.currentTime=this.position,this._sound.muted=this._muted,this._sound.volume=this._muted?0:this._volume,this.isPlaying=!0,this.startTime=this.game.time.now,this.currentTime=0,this.stopTime=this.startTime+this.durationMS,this.onPlay.dispatch(this)):this.pendingPlayback=!0}},restart:function(a,b,c,d){a=a||"",b=b||0,c=c||1,"undefined"==typeof d&&(d=!1),this.play(a,b,c,d,!0)},pause:function(){this.isPlaying&&this._sound&&(this.stop(),this.isPlaying=!1,this.paused=!0,this.pausedPosition=this.currentTime,this.pausedTime=this.game.time.now,this.onPause.dispatch(this))},resume:function(){if(this.paused&&this._sound){if(this.usingWebAudio){var a=this.position+this.pausedPosition/1e3;this._sound=this.context.createBufferSource(),this._sound.buffer=this._buffer,this.externalNode?this._sound.connect(this.externalNode.input):this._sound.connect(this.gainNode),this.loop&&(this._sound.loop=!0),"undefined"==typeof this._sound.start?this._sound.noteGrainOn(0,a,this.duration):this._sound.start(0,a,this.duration)}else this._sound.play();this.isPlaying=!0,this.paused=!1,this.startTime+=this.game.time.now-this.pausedTime,this.onResume.dispatch(this)}},stop:function(){this.isPlaying&&this._sound&&(this.usingWebAudio?"undefined"==typeof this._sound.stop?this._sound.noteOff(0):this._sound.stop(0):this.usingAudioTag&&(this._sound.pause(),this._sound.currentTime=0)),this.isPlaying=!1;var a=this.currentMarker;this.currentMarker="",this.onStop.dispatch(this,a)}},c.Sound.prototype.constructor=c.Sound,Object.defineProperty(c.Sound.prototype,"isDecoding",{get:function(){return this.game.cache.getSound(this.key).isDecoding}}),Object.defineProperty(c.Sound.prototype,"isDecoded",{get:function(){return this.game.cache.isSoundDecoded(this.key)}}),Object.defineProperty(c.Sound.prototype,"mute",{get:function(){return this._muted},set:function(a){a=a||null,a?(this._muted=!0,this.usingWebAudio?(this._muteVolume=this.gainNode.gain.value,this.gainNode.gain.value=0):this.usingAudioTag&&this._sound&&(this._muteVolume=this._sound.volume,this._sound.volume=0)):(this._muted=!1,this.usingWebAudio?this.gainNode.gain.value=this._muteVolume:this.usingAudioTag&&this._sound&&(this._sound.volume=this._muteVolume)),this.onMute.dispatch(this)}}),Object.defineProperty(c.Sound.prototype,"volume",{get:function(){return this._volume},set:function(a){this.usingWebAudio?(this._volume=a,this.gainNode.gain.value=a):this.usingAudioTag&&this._sound&&a>=0&&1>=a&&(this._volume=a,this._sound.volume=a)}}),c.SoundManager=function(a){this.game=a,this.onSoundDecode=new c.Signal,this._muted=!1,this._unlockSource=null,this._volume=1,this._sounds=[],this.context=null,this.usingWebAudio=!0,this.usingAudioTag=!1,this.noAudio=!1,this.connectToMaster=!0,this.touchLocked=!1,this.channels=32},c.SoundManager.prototype={boot:function(){if(this.game.device.iOS&&this.game.device.webAudio===!1&&(this.channels=1),this.game.device.iOS||window.PhaserGlobal&&window.PhaserGlobal.fakeiOSTouchLock?(this.game.input.touch.callbackContext=this,this.game.input.touch.touchStartCallback=this.unlock,this.game.input.mouse.callbackContext=this,this.game.input.mouse.mouseDownCallback=this.unlock,this.touchLocked=!0):this.touchLocked=!1,window.PhaserGlobal){if(window.PhaserGlobal.disableAudio===!0)return this.usingWebAudio=!1,this.noAudio=!0,void 0;if(window.PhaserGlobal.disableWebAudio===!0)return this.usingWebAudio=!1,this.usingAudioTag=!0,this.noAudio=!1,void 0}window.AudioContext?this.context=new window.AudioContext:window.webkitAudioContext?this.context=new window.webkitAudioContext:window.Audio?(this.usingWebAudio=!1,this.usingAudioTag=!0):(this.usingWebAudio=!1,this.noAudio=!0),null!==this.context&&(this.masterGain="undefined"==typeof this.context.createGain?this.context.createGainNode():this.context.createGain(),this.masterGain.gain.value=1,this.masterGain.connect(this.context.destination))},unlock:function(){if(this.touchLocked!==!1)if(this.game.device.webAudio===!1||window.PhaserGlobal&&window.PhaserGlobal.disableWebAudio===!0)this.touchLocked=!1,this._unlockSource=null,this.game.input.touch.callbackContext=null,this.game.input.touch.touchStartCallback=null,this.game.input.mouse.callbackContext=null,this.game.input.mouse.mouseDownCallback=null;else{var a=this.context.createBuffer(1,1,22050);this._unlockSource=this.context.createBufferSource(),this._unlockSource.buffer=a,this._unlockSource.connect(this.context.destination),this._unlockSource.noteOn(0)}},stopAll:function(){for(var a=0;a255)return c.Color.getColor(255,255,255);if(a>b)return c.Color.getColor(255,255,255);var e=a+Math.round(Math.random()*(b-a)),f=a+Math.round(Math.random()*(b-a)),g=a+Math.round(Math.random()*(b-a));return c.Color.getColor32(d,e,f,g)},getRGB:function(a){return{alpha:a>>>24,red:255&a>>16,green:255&a>>8,blue:255&a}},getWebRGB:function(a){var b=(a>>>24)/255,c=255&a>>16,d=255&a>>8,e=255&a;return"rgba("+c.toString()+","+d.toString()+","+e.toString()+","+b.toString()+")"},getAlpha:function(a){return a>>>24},getAlphaFloat:function(a){return(a>>>24)/255},getRed:function(a){return 255&a>>16},getGreen:function(a){return 255&a>>8},getBlue:function(a){return 255&a}},function(a,b){"use strict";"function"==typeof define&&define.amd?define(b):"object"==typeof exports?module.exports=b():a.SAT=b()}(this,function(){"use strict";function a(a,b){this.x=a||0,this.y=b||0}function b(b,c){this.pos=b||new a,this.r=c||0}function c(b,c){this.pos=b||new a,this.points=c||[],this.recalc()}function d(b,c,d){this.pos=b||new a,this.w=c||0,this.h=d||0}function e(){this.a=null,this.b=null,this.overlapN=new a,this.overlapV=new a,this.clear()}function f(a,b,c){for(var d=Number.MAX_VALUE,e=-Number.MAX_VALUE,f=a.length,g=0;f>g;g++){var h=a[g].dot(b);d>h&&(d=h),h>e&&(e=h)}c[0]=d,c[1]=e}function g(a,b,c,d,e,g){var h=p.pop(),i=p.pop(),j=n.pop().copy(b).sub(a),k=j.dot(e);if(f(c,e,h),f(d,e,i),i[0]+=k,i[1]+=k,h[0]>i[1]||i[0]>h[1])return n.push(j),p.push(h),p.push(i),!0;if(g){var l=0;if(h[0]m?m:-o}else if(g.bInA=!1,h[1]>i[1])l=h[0]-i[1],g.aInB=!1;else{var m=h[1]-i[0],o=i[1]-h[0];l=o>m?m:-o}var q=Math.abs(l);ql&&g.overlapN.reverse())}return n.push(j),p.push(h),p.push(i),!1}function h(a,b){var c=a.len2(),d=b.dot(a);return 0>d?q:d>c?s:r}function i(a,b,c){var d=n.pop().copy(b.pos).sub(a.pos),e=a.r+b.r,f=e*e,g=d.len2();if(g>f)return n.push(d),!1;if(c){var h=Math.sqrt(g);c.a=a,c.b=b,c.overlap=e-h,c.overlapN.copy(d.normalize()),c.overlapV.copy(d).scale(c.overlap),c.aInB=a.r<=b.r&&h<=b.r-a.r,c.bInA=b.r<=a.r&&h<=a.r-b.r}return n.push(d),!0}function j(a,b,c){for(var d=n.pop().copy(b.pos).sub(a.pos),e=b.r,f=e*e,g=a.points,i=g.length,j=n.pop(),k=n.pop(),l=0;i>l;l++){var m=l===i-1?0:l+1,o=0===l?i-1:l-1,p=0,r=null;j.copy(a.edges[l]),k.copy(d).sub(g[l]),c&&k.len2()>f&&(c.aInB=!1);var t=h(j,k);if(t===q){j.copy(a.edges[o]);var u=n.pop().copy(d).sub(g[o]);if(t=h(j,u),t===s){var v=k.len();if(v>e)return n.push(d),n.push(j),n.push(k),n.push(u),!1;c&&(c.bInA=!1,r=k.normalize(),p=e-v)}n.push(u)}else if(t===s){if(j.copy(a.edges[m]),k.copy(d).sub(g[m]),t=h(j,k),t===q){var v=k.len();if(v>e)return n.push(d),n.push(j),n.push(k),!1;c&&(c.bInA=!1,r=k.normalize(),p=e-v)}}else{var w=j.perp().normalize(),v=k.dot(w),x=Math.abs(v);if(v>0&&x>e)return n.push(d),n.push(w),n.push(k),!1;c&&(r=w,p=e-v,(v>=0||2*e>p)&&(c.bInA=!1))}r&&c&&Math.abs(p)i;i++)if(g(a.pos,b.pos,d,f,a.normals[i],c))return!1;for(var i=0;h>i;i++)if(g(a.pos,b.pos,d,f,b.normals[i],c))return!1;return c&&(c.a=a,c.b=b,c.overlapV.copy(c.overlapN).scale(c.overlap)),!0}var m={};m.Vector=a,m.V=a,a.prototype.copy=a.prototype.copy=function(a){return this.x=a.x,this.y=a.y,this},a.prototype.perp=a.prototype.perp=function(){var a=this.x;return this.x=this.y,this.y=-a,this},a.prototype.rotate=a.prototype.rotate=function(a){var b=this.x,c=this.y;return this.x=b*Math.cos(a)-c*Math.sin(a),this.y=b*Math.sin(a)+c*Math.cos(a),this},a.prototype.rotatePrecalc=a.prototype.rotatePrecalc=function(a,b){var c=this.x,d=this.y;return this.x=c*b-d*a,this.y=c*a+d*b,this},a.prototype.reverse=a.prototype.reverse=function(){return this.x=-this.x,this.y=-this.y,this},a.prototype.normalize=a.prototype.normalize=function(){var a=this.len();return a>0&&(this.x=this.x/a,this.y=this.y/a),this},a.prototype.add=a.prototype.add=function(a){return this.x+=a.x,this.y+=a.y,this},a.prototype.sub=a.prototype.sub=function(a){return this.x-=a.x,this.y-=a.y,this},a.prototype.scale=a.prototype.scale=function(a,b){return this.x*=a,this.y*=b||a,this},a.prototype.project=a.prototype.project=function(a){var b=this.dot(a)/a.len2();return this.x=b*a.x,this.y=b*a.y,this},a.prototype.projectN=a.prototype.projectN=function(a){var b=this.dot(a);return this.x=b*a.x,this.y=b*a.y,this},a.prototype.reflect=a.prototype.reflect=function(a){var b=this.x,c=this.y;return this.project(a).scale(2),this.x-=b,this.y-=c,this},a.prototype.reflectN=a.prototype.reflectN=function(a){var b=this.x,c=this.y;return this.projectN(a).scale(2),this.x-=b,this.y-=c,this},a.prototype.dot=a.prototype.dot=function(a){return this.x*a.x+this.y*a.y},a.prototype.len2=a.prototype.len2=function(){return this.dot(this) +},a.prototype.len=a.prototype.len=function(){return Math.sqrt(this.len2())},m.Circle=b,m.Polygon=c,c.prototype.recalc=c.prototype.recalc=function(){this.edges=[],this.normals=[];for(var b=this.points,c=b.length,d=0;c>d;d++){var e=b[d],f=c-1>d?b[d+1]:b[0],g=(new a).copy(f).sub(e),h=(new a).copy(g).perp().normalize();this.edges.push(g),this.normals.push(h)}return this},c.prototype.rotate=c.prototype.rotate=function(a){var b,c=this.points,d=this.edges,e=this.normals,f=c.length,g=Math.cos(a),h=Math.sin(a);for(b=0;f>b;b++)c[b].rotatePrecalc(h,g),d[b].rotatePrecalc(h,g),e[b].rotatePrecalc(h,g);return this},c.prototype.scale=c.prototype.scale=function(a,b){var c,d=this.points,e=this.edges,f=this.normals,g=d.length;for(c=0;g>c;c++)d[c].scale(a,b),e[c].scale(a,b),f[c].scale(a,b);return this},c.prototype.translate=c.prototype.translate=function(a,b){var c,d=this.points,e=d.length;for(c=0;e>c;c++)d[c].x+=a,d[c].y+=b;return this},m.Box=d,d.prototype.toPolygon=d.prototype.toPolygon=function(){var b=this.pos,d=this.w,e=this.h;return new c(new a(b.x,b.y),[new a,new a(d,0),new a(d,e),new a(0,e)])},m.Response=e,e.prototype.clear=e.prototype.clear=function(){return this.aInB=!0,this.bInA=!0,this.overlap=Number.MAX_VALUE,this};for(var n=[],o=0;10>o;o++)n.push(new a);for(var p=[],o=0;5>o;o++)p.push([]);var q=-1,r=0,s=1;return m.testCircleCircle=i,m.testPolygonCircle=j,m.testCirclePolygon=k,m.testPolygonPolygon=l,m}),c.Physics={},c.Physics.Arcade=function(a){this.game=a,this.gravity=new c.Point,this.worldLeft=null,this.worldRight=null,this.worldTop=null,this.worldBottom=null,this.worldPolys=[null,null,null,null],this.quadTree=new c.QuadTree(this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height,this.maxObjects,this.maxLevels),this.maxObjects=10,this.maxLevels=4,this._mapData=[],this._mapTiles=0,this._result=!1,this._total=0,this._angle=0,this._drag=0,this._dx=0,this._dy=0,this._p=new c.Point(0,0),this._intersection=[0,0,0,0],this._gravityX=0,this._gravityY=0,this._response=new SAT.Response,this.setBoundsToWorld(!0,!0,!0,!0)},c.Physics.Arcade.RECT=0,c.Physics.Arcade.CIRCLE=1,c.Physics.Arcade.POLYGON=2,c.Physics.Arcade.prototype={checkBounds:function(a){if(!a.collideWorldBounds||!this.worldLeft&&!this.worldRight&&!this.worldTop&&!this.worldBottom)return!1;this._response.clear();var b=SAT.testPolygonPolygon,d=a.polygon,e=!1;return a.type===c.Physics.Arcade.CIRCLE&&(b=SAT.testPolygonCircle,d=a.shape),this.worldLeft&&b(this.worldPolys[0],d,this._response)?(a.blocked.left=!0,d.pos.add(this._response.overlapV),a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),e=!0):this.worldRight&&b(this.worldPolys[1],d,this._response)&&(a.blocked.right=!0,d.pos.add(this._response.overlapV),a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),e=!0),this._response.clear(),this.worldTop&&b(this.worldPolys[2],d,this._response)?(a.blocked.up=!0,d.pos.add(this._response.overlapV),a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),e=!0):this.worldBottom&&b(this.worldPolys[3],d,this._response)&&(a.blocked.down=!0,d.pos.add(this._response.overlapV),a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),e=!0),e},setBoundsToWorld:function(a,b,c,d){this.setBounds(this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height,a,b,c,d)},setBounds:function(a,b,c,d,e,f,g,h){"undefined"==typeof e&&(e=!0),"undefined"==typeof f&&(f=!0),"undefined"==typeof g&&(g=!0),"undefined"==typeof h&&(h=!0);var i=100;e?(this.worldLeft=new SAT.Box(new SAT.Vector(a-i,b),i,d),this.worldPolys[0]=this.worldLeft.toPolygon()):(this.worldLeft=null,this.worldPolys[0]=null),f?(this.worldRight=new SAT.Box(new SAT.Vector(a+c,b),i,d),this.worldPolys[1]=this.worldRight.toPolygon()):(this.worldRight=null,this.worldPolys[1]=null),g?(this.worldTop=new SAT.Box(new SAT.Vector(a,b-i),c,i),this.worldPolys[2]=this.worldTop.toPolygon()):(this.worldTop=null,this.worldPolys[2]=null),h?(this.worldBottom=new SAT.Box(new SAT.Vector(a,b+d),c,i),this.worldPolys[3]=this.worldBottom.toPolygon()):(this.worldBottom=null,this.worldPolys[3]=null)},updateMotion:function(a){return a.allowGravity?(this._gravityX=this.gravity.x+a.gravity.x,this._gravityY=this.gravity.y+a.gravity.y):(this._gravityX=a.gravity.x,this._gravityY=a.gravity.y),(this._gravityX<0&&a.blocked.left||this._gravityX>0&&a.blocked.right)&&(this._gravityX=0),(this._gravityY<0&&a.blocked.up||this._gravityY>0&&a.blocked.down)&&(this._gravityY=0),a.allowRotation&&(this._velocityDelta=a.angularAcceleration*this.game.time.physicsElapsed,0!==a.angularDrag&&0===a.angularAcceleration&&(this._drag=a.angularDrag*this.game.time.physicsElapsed,a.angularVelocity>0?a.angularVelocity-=this._drag:a.angularVelocity<0&&(a.angularVelocity+=this._drag)),a.rotation+=this.game.time.physicsElapsed*(a.angularVelocity+this._velocityDelta/2),a.angularVelocity+=this._velocityDelta,a.angularVelocity>a.maxAngular?a.angularVelocity=a.maxAngular:a.angularVelocity<-a.maxAngular&&(a.angularVelocity=-a.maxAngular)),this._p.setTo((a.acceleration.x+this._gravityX)*this.game.time.physicsElapsed,(a.acceleration.y+this._gravityY)*this.game.time.physicsElapsed),this._p},overlap:function(a,b,c,d,e){if(c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,Array.isArray(b))for(var f=0,g=b.length;g>f;f++)this.collideHandler(a,b[f],c,d,e,!0);else this.collideHandler(a,b,c,d,e,!0);return this._total>0},collide:function(a,b,c,d,e){if(c=c||null,d=d||null,e=e||c,this._result=!1,this._total=0,Array.isArray(b))for(var f=0,g=b.length;g>f;f++)this.collideHandler(a,b[f],c,d,e,!1);else this.collideHandler(a,b,c,d,e,!1);return this._total>0},collideHandler:function(a,b,d,e,f,g){return"undefined"!=typeof b||a.type!==c.GROUP&&a.type!==c.EMITTER?(a&&b&&a.exists&&b.exists&&(a.type==c.SPRITE||a.type==c.TILESPRITE?b.type==c.SPRITE||b.type==c.TILESPRITE?this.collideSpriteVsSprite(a,b,d,e,f,g):b.type==c.GROUP||b.type==c.EMITTER?this.collideSpriteVsGroup(a,b,d,e,f,g):b.type==c.TILEMAPLAYER&&this.collideSpriteVsTilemapLayer(a,b,d,e,f):a.type==c.GROUP?b.type==c.SPRITE||b.type==c.TILESPRITE?this.collideSpriteVsGroup(b,a,d,e,f,g):b.type==c.GROUP||b.type==c.EMITTER?this.collideGroupVsGroup(a,b,d,e,f,g):b.type==c.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,b,d,e,f):a.type==c.TILEMAPLAYER?b.type==c.SPRITE||b.type==c.TILESPRITE?this.collideSpriteVsTilemapLayer(b,a,d,e,f):(b.type==c.GROUP||b.type==c.EMITTER)&&this.collideGroupVsTilemapLayer(b,a,d,e,f):a.type==c.EMITTER&&(b.type==c.SPRITE||b.type==c.TILESPRITE?this.collideSpriteVsGroup(b,a,d,e,f,g):b.type==c.GROUP||b.type==c.EMITTER?this.collideGroupVsGroup(a,b,d,e,f,g):b.type==c.TILEMAPLAYER&&this.collideGroupVsTilemapLayer(a,b,d,e,f))),void 0):(this.collideGroupVsSelf(a,d,e,f,g),void 0)},collideSpriteVsSprite:function(a,b,c,d,e,f){this.separate(a.body,b.body,d,e,f)&&(c&&c.call(e,a,b),this._total++)},collideSpriteVsGroup:function(a,b,d,e,f,g){if(0!==b.length){this.quadTree.clear(),this.quadTree=new c.QuadTree(this.game.world.bounds.x,this.game.world.bounds.y,this.game.world.bounds.width,this.game.world.bounds.height,this.maxObjects,this.maxLevels),this.quadTree.populate(b),this._potentials=this.quadTree.retrieve(a);for(var h=0,i=this._potentials.length;i>h;h++)this.separate(a.body,this._potentials[h],e,f,g)&&(d&&d.call(f,a,this._potentials[h].sprite),this._total++)}},collideGroupVsSelf:function(a,b,c,d,e){if(0!==a.length)for(var f=a._container.children.length,g=0;f>g;g++)for(var h=g+1;f>=h;h++)a._container.children[g]&&a._container.children[h]&&a._container.children[g].exists&&a._container.children[h].exists&&this.collideSpriteVsSprite(a._container.children[g],a._container.children[h],b,c,d,e)},collideGroupVsGroup:function(a,b,c,d,e,f){if(0!==a.length&&0!==b.length&&a._container.first._iNext){var g=a._container.first._iNext;do g.exists&&this.collideSpriteVsGroup(g,b,c,d,e,f),g=g._iNext;while(g!=a._container.last._iNext)}},collideSpriteVsTilemapLayer:function(a,b,c,d,e){if(this._mapData=b.getTiles(a.body.left,a.body.top,a.body.width,a.body.height,!0),0!==this._mapData.length)if(this._mapData.length>1)this.separateTiles(a.body,this._mapData);else{var f=0;this.separateTile(a.body,this._mapData[f])&&(d?d.call(e,a,this._mapData[f])&&(this._total++,c&&c.call(e,a,this._mapData[f])):(this._total++,c&&c.call(e,a,this._mapData[f])))}},collideGroupVsTilemapLayer:function(a,b,c,d,e){if(0!==a.length&&a._container.first._iNext){var f=a._container.first._iNext;do f.exists&&this.collideSpriteVsTilemapLayer(f,b,c,d,e),f=f._iNext;while(f!=a._container.last._iNext)}},separate:function(a,b,c,d,e){return a===b||this.intersects(a,b)===!1?!1:c&&c.call(d,a.sprite,b.sprite)===!1?!1:(this._response.clear(),e?a.overlap(b,this._response):a.overlap(b,this._response)?a.separate(b,this._response):!1)},intersects:function(a,b){var c=!1;(a.width<=0||a.height<=0||b.width<=0||b.height<=0)&&(c=!1),c=!(a.rightb.right||a.top>b.bottom),!c&&a.inContact(b)&&a.removeContact(b)},tileIntersects:function(a,b){return a.width<=0||a.height<=0||b.width<=0||b.height<=0?(this._intersection[4]=0,this._intersection):a.rightb.right||a.top>b.bottom?(this._intersection[4]=0,this._intersection):(this._intersection[0]=Math.max(a.left,b.x),this._intersection[1]=Math.max(a.top,b.y),this._intersection[2]=Math.min(a.right,b.right)-this._intersection[0],this._intersection[3]=Math.min(a.bottom,b.bottom)-this._intersection[1],this._intersection[4]=1,this._intersection)},separateTiles:function(a,b){for(var c,d=!1,e=0;e0&&a.checkCollision.right&&b.tile.faceLeft&&!a.blocked.right&&(a.overlapX=a.right-b.x,a.overlapX>0?c=!0:a.overlapX=0),a.deltaY()<0&&a.checkCollision.up&&b.tile.faceBottom&&!a.blocked.up?(a.overlapY=a.top-b.bottom,a.overlapY<0?c=!0:a.overlapY=0):a.deltaY()>0&&a.checkCollision.down&&b.tile.faceTop&&!a.blocked.down&&(a.overlapY=a.bottom-b.y,a.overlapY>0?c=!0:a.overlapY=0),0!==a.overlapX&&0!==a.overlapY&&(Math.abs(a.overlapX)>Math.abs(a.overlapY)?a.overlapX=0:a.overlapY=0),c?this.processTileSeparation(a):!1},processTileSeparation:function(a){return a.overlapX<0?(a.x-=a.overlapX,a.left-=a.overlapX,a.right-=a.overlapX,a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),a.blocked.left=!0):a.overlapX>0&&(a.x-=a.overlapX,a.left-=a.overlapX,a.right-=a.overlapX,a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),a.blocked.right=!0),a.overlapY<0?(a.y-=a.overlapY,a.top-=a.overlapY,a.bottom-=a.overlapY,a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),a.blocked.up=!0):a.overlapY>0&&(a.y-=a.overlapY,a.top-=a.overlapY,a.bottom-=a.overlapY,a.blocked.x=Math.floor(a.x),a.blocked.y=Math.floor(a.y),a.blocked.down=!0),a.reboundCheck(a.overlapX,a.overlapY,!0),!0},moveToObject:function(a,b,c,d){return"undefined"==typeof c&&(c=60),"undefined"==typeof d&&(d=0),this._angle=Math.atan2(b.y-a.y,b.x-a.x),d>0&&(c=this.distanceBetween(a,b)/(d/1e3)),a.body.velocity.x=Math.cos(this._angle)*c,a.body.velocity.y=Math.sin(this._angle)*c,this._angle},moveToPointer:function(a,b,c,d){return"undefined"==typeof b&&(b=60),c=c||this.game.input.activePointer,"undefined"==typeof d&&(d=0),this._angle=this.angleToPointer(a,c),d>0&&(b=this.distanceToPointer(a,c)/(d/1e3)),a.body.velocity.x=Math.cos(this._angle)*b,a.body.velocity.y=Math.sin(this._angle)*b,this._angle},moveToXY:function(a,b,c,d,e){return"undefined"==typeof d&&(d=60),"undefined"==typeof e&&(e=0),this._angle=Math.atan2(c-a.y,b-a.x),e>0&&(d=this.distanceToXY(a,b,c)/(e/1e3)),a.body.velocity.x=Math.cos(this._angle)*d,a.body.velocity.y=Math.sin(this._angle)*d,this._angle},velocityFromAngle:function(a,b,d){return"undefined"==typeof b&&(b=60),d=d||new c.Point,d.setTo(Math.cos(this.game.math.degToRad(a))*b,Math.sin(this.game.math.degToRad(a))*b)},velocityFromRotation:function(a,b,d){return"undefined"==typeof b&&(b=60),d=d||new c.Point,d.setTo(Math.cos(a)*b,Math.sin(a)*b)},accelerationFromRotation:function(a,b,d){return"undefined"==typeof b&&(b=60),d=d||new c.Point,d.setTo(Math.cos(a)*b,Math.sin(a)*b)},accelerateToObject:function(a,b,c,d,e){return"undefined"==typeof c&&(c=60),"undefined"==typeof d&&(d=1e3),"undefined"==typeof e&&(e=1e3),this._angle=this.angleBetween(a,b),a.body.acceleration.setTo(Math.cos(this._angle)*c,Math.sin(this._angle)*c),a.body.maxVelocity.setTo(d,e),this._angle},accelerateToPointer:function(a,b,c,d,e){return"undefined"==typeof c&&(c=60),"undefined"==typeof b&&(b=this.game.input.activePointer),"undefined"==typeof d&&(d=1e3),"undefined"==typeof e&&(e=1e3),this._angle=this.angleToPointer(a,b),a.body.acceleration.setTo(Math.cos(this._angle)*c,Math.sin(this._angle)*c),a.body.maxVelocity.setTo(d,e),this._angle},accelerateToXY:function(a,b,c,d,e,f){return"undefined"==typeof d&&(d=60),"undefined"==typeof e&&(e=1e3),"undefined"==typeof f&&(f=1e3),this._angle=this.angleToXY(a,b,c),a.body.acceleration.setTo(Math.cos(this._angle)*d,Math.sin(this._angle)*d),a.body.maxVelocity.setTo(e,f),this._angle},distanceBetween:function(a,b){return this._dx=a.x-b.x,this._dy=a.y-b.y,Math.sqrt(this._dx*this._dx+this._dy*this._dy)},distanceToXY:function(a,b,c){return this._dx=a.x-b,this._dy=a.y-c,Math.sqrt(this._dx*this._dx+this._dy*this._dy)},distanceToPointer:function(a,b){return b=b||this.game.input.activePointer,this._dx=a.x-b.x,this._dy=a.y-b.y,Math.sqrt(this._dx*this._dx+this._dy*this._dy)},angleBetween:function(a,b){return this._dx=b.x-a.x,this._dy=b.y-a.y,Math.atan2(this._dy,this._dx)},angleToXY:function(a,b,c){return this._dx=b-a.x,this._dy=c-a.y,Math.atan2(this._dy,this._dx)},angleToPointer:function(a,b){return b=b||this.game.input.activePointer,this._dx=b.worldX-a.x,this._dy=b.worldY-a.y,Math.atan2(this._dy,this._dx)}},c.Physics.Arcade.prototype.constructor=c.Physics.Arcade,c.Physics.Arcade.Body=function(a){this.sprite=a,this.game=a.game,this.offset=new c.Point,this.preX=a.world.x,this.preY=a.world.y,this.preRotation=a.angle,this.velocity=new c.Point,this.acceleration=new c.Point,this.speed=0,this.angle=0,this.gravity=new c.Point,this.bounce=new c.Point,this.minVelocity=new c.Point,this.maxVelocity=new c.Point(1e3,1e3),this.angularVelocity=0,this.angularAcceleration=0,this.angularDrag=0,this.maxAngular=1e3,this.mass=1,this.linearDamping=0,this.checkCollision={none:!1,any:!0,up:!0,down:!0,left:!0,right:!0},this.touching={none:!0,up:!1,down:!1,left:!1,right:!1},this.blocked={x:0,y:0,up:!1,down:!1,left:!1,right:!1},this.facing=c.NONE,this.rebound=!0,this.immovable=!1,this.moves=!0,this.rotation=0,this.allowRotation=!0,this.allowGravity=!0,this.customSeparateCallback=null,this.customSeparateContext=null,this.collideCallback=null,this.collideCallbackContext=null,this.collideWorldBounds=!1,this.type=c.Physics.Arcade.RECT,this.shape=null,this.polygon=null,this.left=0,this.right=0,this.top=0,this.bottom=0,this.width=0,this.height=0,this.contacts=[],this.overlapX=0,this.overlapY=0,this._temp=null,this._dx=0,this._dy=0,this._sx=a.scale.x,this._sy=a.scale.y,this._distances=[0,0,0,0],this._vx=0,this._vy=0,this.setRectangle(a.width,a.height,0,0),this.sprite.events.onBeginContact=new c.Signal,this.sprite.events.onEndContact=new c.Signal},c.Physics.Arcade.Body.prototype={updateScale:function(){this.polygon?this.polygon.scale(this.sprite.scale.x/this._sx,this.sprite.scale.y/this._sy):this.shape.r*=Math.max(this.sprite.scale.x,this.sprite.scale.y),this._sx=this.sprite.scale.x,this._sy=this.sprite.scale.y},preUpdate:function(){this.x=this.sprite.world.x-this.sprite.anchor.x*this.sprite.width+this.offset.x,this.y=this.sprite.world.y-this.sprite.anchor.y*this.sprite.height+this.offset.y,this.preX=this.x,this.preY=this.y,this.preRotation=this.sprite.angle,this.rotation=this.preRotation,(this.sprite.scale.x!==this._sx||this.sprite.scale.y!==this._sy)&&this.updateScale(),this.checkBlocked(),this.touching.none=!0,this.touching.up=!1,this.touching.down=!1,this.touching.left=!1,this.touching.right=!1,this.moves?((this._vx!==this.velocity.x||this._vy!==this.velocity.y)&&(this._vx=this.velocity.x,this._vy=this.velocity.y,this.speed=Math.sqrt(this.velocity.x*this.velocity.x+this.velocity.y*this.velocity.y),this.angle=Math.atan2(this.velocity.y,this.velocity.x)),this.game.physics.checkBounds(this)&&this.reboundCheck(!0,!0,!0),this.applyDamping(),this.integrateVelocity(),this.updateBounds(),this.checkBlocked()):this.updateBounds()},checkBlocked:function(){!this.blocked.left&&!this.blocked.right||Math.floor(this.x)===this.blocked.x&&Math.floor(this.y)===this.blocked.y||(this.blocked.left=!1,this.blocked.right=!1),!this.blocked.up&&!this.blocked.down||Math.floor(this.x)===this.blocked.x&&Math.floor(this.y)===this.blocked.y||(this.blocked.up=!1,this.blocked.down=!1)},updateBounds:function(){this.type===c.Physics.Arcade.CIRCLE?(this.left=this.shape.pos.x-this.shape.r,this.right=this.shape.pos.x+this.shape.r,this.top=this.shape.pos.y-this.shape.r,this.bottom=this.shape.pos.y+this.shape.r):(this.left=c.Math.minProperty("x",this.polygon.points)+this.polygon.pos.x,this.right=c.Math.maxProperty("x",this.polygon.points)+this.polygon.pos.x,this.top=c.Math.minProperty("y",this.polygon.points)+this.polygon.pos.y,this.bottom=c.Math.maxProperty("y",this.polygon.points)+this.polygon.pos.y),this.width=this.right-this.left,this.height=this.bottom-this.top},applyDamping:function(){this.linearDamping>0&&this.acceleration.isZero()&&(this.speed>this.linearDamping?this.speed-=this.linearDamping:this.speed=0,this.speed>0&&(this.velocity.x=Math.cos(this.angle)*this.speed,this.velocity.y=Math.sin(this.angle)*this.speed,this.speed=Math.sqrt(this.velocity.x*this.velocity.x+this.velocity.y*this.velocity.y),this.angle=Math.atan2(this.velocity.y,this.velocity.x)))},reboundCheck:function(a,b,c){if(a&&(c&&0!==this.bounce.x&&(this.blocked.left||this.blocked.right||this.touching.left||this.touching.right)&&(this._vx<=0&&this.velocity.x>0||this._vx>=0&&this.velocity.x<0||(this.velocity.x*=-this.bounce.x,this.angle=Math.atan2(this.velocity.y,this.velocity.x))),0===this.bounce.x||Math.abs(this.velocity.x)d||this.velocity.x<0)||(this.blocked.right||this.touching.right)&&(d>0||this.velocity.x>0))&&(this.velocity.x=0)}if(b&&(c&&0!==this.bounce.y&&(this.blocked.up||this.blocked.down||this.touching.up||this.touching.down)&&(this._vy<=0&&this.velocity.y>0||this._vy>=0&&this.velocity.y<0||(this.velocity.y*=-this.bounce.y,this.angle=Math.atan2(this.velocity.y,this.velocity.x))),0===this.bounce.y||Math.abs(this.velocity.y)e||this.velocity.y<0)||(this.blocked.down||this.touching.down)&&(e>0||this.velocity.y>0))&&(this.velocity.y=0)}},getUpwardForce:function(){return this.allowGravity?this.gravity.x+this.game.physics.gravity.x+this.velocity.x:this.gravity.x+this.velocity.x},getDownwardForce:function(){return this.allowGravity?this.gravity.y+this.game.physics.gravity.y+this.velocity.y:this.gravity.y+this.velocity.y},sub:function(a){this.x-=a.x,this.y-=a.y},add:function(a){this.x+=a.x,this.y+=a.y},give:function(a,b){this.add(b.overlapV),this.rebound&&(this.processRebound(a),this.reboundCheck(!0,!0,!1),a.reboundCheck(!0,!0,!1))},take:function(a,b){this.sub(b.overlapV),this.rebound&&(this.processRebound(a),this.reboundCheck(!0,!0,!1),a.reboundCheck(!0,!0,!1))},split:function(a,b){b.overlapV.scale(.5),this.sub(b.overlapV),a.add(b.overlapV),this.rebound&&(this.exchange(a),this.reboundCheck(!0,!0,!1),a.reboundCheck(!0,!0,!1))},exchange:function(a){if(this.mass===a.mass&&this.speed>0&&a.speed>0)this._dx=a.velocity.x,this._dy=a.velocity.y,a.velocity.x=this.velocity.x*a.bounce.x,a.velocity.y=this.velocity.y*a.bounce.x,this.velocity.x=this._dx*this.bounce.x,this.velocity.y=this._dy*this.bounce.y;else{var b=Math.sqrt(a.velocity.x*a.velocity.x*a.mass/this.mass)*(a.velocity.x>0?1:-1),c=Math.sqrt(this.velocity.x*this.velocity.x*this.mass/a.mass)*(this.velocity.x>0?1:-1),d=.5*(b+c);b-=d,c-=d,this.velocity.x=b,a.velocity.x=c,b=Math.sqrt(a.velocity.y*a.velocity.y*a.mass/this.mass)*(a.velocity.y>0?1:-1),c=Math.sqrt(this.velocity.y*this.velocity.y*this.mass/a.mass)*(this.velocity.y>0?1:-1),d=.5*(b+c),b-=d,c-=d,this.velocity.y=b,a.velocity.y=c}},processRebound:function(a){this._vx<=0&&this.velocity.x>0||this._vx>=0&&this.velocity.x<0||(this.velocity.x=a.velocity.x-this.velocity.x*this.bounce.x),this._vy<=0&&this.velocity.y>0||this._vy>=0&&this.velocity.y<0||(this.velocity.y=a.velocity.y-this.velocity.y*this.bounce.y),this.angle=Math.atan2(this.velocity.y,this.velocity.x),this.reboundCheck(!0,!0,!1)},overlap:function(a,b){var d=!1;return this.type!==c.Physics.Arcade.RECT&&this.type!==c.Physics.Arcade.POLYGON||a.type!==c.Physics.Arcade.RECT&&a.type!==c.Physics.Arcade.POLYGON?this.type===c.Physics.Arcade.CIRCLE&&a.type===c.Physics.Arcade.CIRCLE?d=SAT.testCircleCircle(this.shape,a.shape,b):this.type!==c.Physics.Arcade.RECT&&this.type!==c.Physics.Arcade.POLYGON||a.type!==c.Physics.Arcade.CIRCLE?this.type!==c.Physics.Arcade.CIRCLE||a.type!==c.Physics.Arcade.RECT&&a.type!==c.Physics.Arcade.POLYGON||(d=SAT.testCirclePolygon(this.shape,a.polygon,b)):d=SAT.testPolygonCircle(this.polygon,a.shape,b):d=SAT.testPolygonPolygon(this.polygon,a.polygon,b),d||this.removeContact(a),d},inContact:function(a){return-1!=this.contacts.indexOf(a)},addContact:function(a){return this.inContact(a)?!1:(this.contacts.push(a),this.sprite.events.onBeginContact.dispatch(this.sprite,a.sprite,this,a),a.addContact(this),!0)},removeContact:function(a){return this.inContact(a)?(this.contacts.splice(this.contacts.indexOf(a),1),this.sprite.events.onEndContact.dispatch(this.sprite,a.sprite,this,a),a.removeContact(this),!0):!1},separate:function(a,b){if(this.inContact(a))return!1;if(this._distances[0]=a.right-this.x,this._distances[1]=this.right-a.x,this._distances[2]=a.bottom-this.y,this._distances[3]=this.bottom-a.y,!b.overlapN.x||0!==this._distances[0]&&0!==this._distances[1]?!b.overlapN.y||0!==this._distances[2]&&0!==this._distances[3]||(b.overlapN.x=!0,b.overlapN.y=!1):(b.overlapN.x=!1,b.overlapN.y=!0),this.customSeparateCallback)return this.customSeparateCallback.call(this.customSeparateContext,this,b,this._distances);var c=!1;return b.overlapN.x?this._distances[0]0&&!this.blocked.right&&!this.touching.right)&&(this.x+=this._dx,this.velocity.x+=this._temp.x),(this._dy<0&&!this.blocked.up&&!this.touching.up||this._dy>0&&!this.blocked.down&&!this.touching.down)&&(this.y+=this._dy,this.velocity.y+=this._temp.y),this.velocity.x>this.maxVelocity.x?this.velocity.x=this.maxVelocity.x:this.velocity.x<-this.maxVelocity.x&&(this.velocity.x=-this.maxVelocity.x),this.velocity.y>this.maxVelocity.y?this.velocity.y=this.maxVelocity.y:this.velocity.y<-this.maxVelocity.y&&(this.velocity.y=-this.maxVelocity.y)},postUpdate:function(){this.moves&&(this.game.physics.checkBounds(this),this.reboundCheck(!0,!0,!0),this._dx=this.deltaX(),this._dy=this.deltaY(),this._dx<0?this.facing=c.LEFT:this._dx>0&&(this.facing=c.RIGHT),this._dy<0?this.facing=c.UP:this._dy>0&&(this.facing=c.DOWN),(0!==this._dx||0!==this._dy)&&(this.sprite.x+=this._dx,this.sprite.y+=this._dy),this.allowRotation&&0!==this.deltaZ()&&(this.sprite.angle+=this.deltaZ()),(this.sprite.scale.x!==this._sx||this.sprite.scale.y!==this._sy)&&this.updateScale())},reset:function(a){"undefined"==typeof a&&(a=!1),a&&(this.gravity.setTo(0,0),this.bounce.setTo(0,0),this.minVelocity.setTo(5,5),this.maxVelocity.setTo(1e3,1e3),this.angularDrag=0,this.maxAngular=1e3,this.mass=1,this.friction=0,this.checkCollision={none:!1,any:!0,up:!0,down:!0,left:!0,right:!0}),this.velocity.setTo(0,0),this.acceleration.setTo(0,0),this.angularVelocity=0,this.angularAcceleration=0,this.blocked={x:0,y:0,up:!1,down:!1,left:!1,right:!1},this.x=this.sprite.world.x-this.sprite.anchor.x*this.sprite.width+this.offset.x,this.y=this.sprite.world.y-this.sprite.anchor.y*this.sprite.height+this.offset.y,this.preX=this.x,this.preY=this.y,this.updateBounds(),this.contacts.length=0},destroy:function(){this.sprite=null,this.collideCallback=null,this.collideCallbackContext=null,this.customSeparateCallback=null,this.customSeparateContext=null,this.contacts.length=0},setCircle:function(a,b,d){"undefined"==typeof b&&(b=this.sprite._cache.halfWidth),"undefined"==typeof d&&(d=this.sprite._cache.halfHeight),this.type=c.Physics.Arcade.CIRCLE,this.shape=new SAT.Circle(new SAT.Vector(this.sprite.x,this.sprite.y),a),this.polygon=null,this.offset.setTo(b,d)},setRectangle:function(a,b,d,e){"undefined"==typeof a&&(a=this.sprite.width),"undefined"==typeof b&&(b=this.sprite.height),"undefined"==typeof d&&(d=-this.sprite._cache.halfWidth),"undefined"==typeof e&&(e=-this.sprite._cache.halfHeight),this.type=c.Physics.Arcade.RECT,this.shape=new SAT.Box(new SAT.Vector(this.sprite.world.x,this.sprite.world.y),a,b),this.polygon=this.shape.toPolygon(),this.polygon.translate(d,e),this.offset.setTo(0,0)},setPolygon:function(a){if(this.type=c.Physics.Arcade.POLYGON,this.shape=null,Array.isArray(a)||(a=Array.prototype.slice.call(arguments)),"number"==typeof a[0]){for(var b=[],d=0,e=a.length;e>d;d+=2)b.push(new SAT.Vector(a[d],a[d+1]));a=b}this.polygon=new SAT.Polygon(new SAT.Vector(this.sprite.center.x,this.sprite.center.y),a),this.offset.setTo(0,0)},translate:function(a,b){this.polygon&&this.polygon.translate(a,b)},onFloor:function(){return this.blocked.down},onWall:function(){return!this.blocked.down&&(this.blocked.left||this.blocked.right)},deltaX:function(){return this.x-this.preX},deltaY:function(){return this.y-this.preY},deltaZ:function(){return this.rotation-this.preRotation}},c.Physics.Arcade.Body.prototype.constructor=c.Physics.Arcade.Body,Object.defineProperty(c.Physics.Arcade.Body.prototype,"x",{get:function(){return this.type===c.Physics.Arcade.CIRCLE?this.shape.pos.x:this.polygon.pos.x},set:function(a){this.type===c.Physics.Arcade.CIRCLE?this.shape.pos.x=a:this.polygon.pos.x=a}}),Object.defineProperty(c.Physics.Arcade.Body.prototype,"y",{get:function(){return this.type===c.Physics.Arcade.CIRCLE?this.shape.pos.y:this.polygon.pos.y},set:function(a){this.type===c.Physics.Arcade.CIRCLE?this.shape.pos.y=a:this.polygon.pos.y=a}}),c.Particles=function(a){this.game=a,this.emitters={},this.ID=0},c.Particles.prototype={add:function(a){return this.emitters[a.name]=a,a},remove:function(a){delete this.emitters[a.name]},update:function(){for(var a in this.emitters)this.emitters[a].exists&&this.emitters[a].update()}},c.Particles.prototype.constructor=c.Particles,c.Particles.Arcade={},c.Particles.Arcade.Emitter=function(a,b,d,e){this.maxParticles=e||50,c.Group.call(this,a),this.name="emitter"+this.game.particles.ID++,this.type=c.EMITTER,this.x=0,this.y=0,this.width=1,this.height=1,this.minParticleSpeed=new c.Point(-100,-100),this.maxParticleSpeed=new c.Point(100,100),this.minParticleScale=1,this.maxParticleScale=1,this.minRotation=-360,this.maxRotation=360,this.gravity=100,this.particleClass=null,this.particleFriction=0,this.angularDrag=0,this.frequency=100,this.lifespan=2e3,this.bounce=new c.Point,this._quantity=0,this._timer=0,this._counter=0,this._explode=!0,this.on=!1,this.exists=!0,this.emitX=b,this.emitY=d},c.Particles.Arcade.Emitter.prototype=Object.create(c.Group.prototype),c.Particles.Arcade.Emitter.prototype.constructor=c.Particles.Arcade.Emitter,c.Particles.Arcade.Emitter.prototype.update=function(){if(this.on)if(this._explode){this._counter=0;do this.emitParticle(),this._counter++;while(this._counter=this._timer&&(this.emitParticle(),this._counter++,this._quantity>0&&this._counter>=this._quantity&&(this.on=!1),this._timer=this.game.time.now+this.frequency)},c.Particles.Arcade.Emitter.prototype.makeParticles=function(a,b,d,e,f){"undefined"==typeof b&&(b=0),"undefined"==typeof d&&(d=this.maxParticles),"undefined"==typeof e&&(e=!1),"undefined"==typeof f&&(f=!1);for(var g,h=0,i=a,j=b;d>h;)null===this.particleClass&&("object"==typeof a&&(i=this.game.rnd.pick(a)),"object"==typeof b&&(j=this.game.rnd.pick(b)),g=new c.Sprite(this.game,0,0,i,j)),e?(g.body.checkCollision.any=!0,g.body.checkCollision.none=!1):g.body.checkCollision.none=!0,g.body.collideWorldBounds=f,g.exists=!1,g.visible=!1,g.anchor.setTo(.5,.5),this.add(g),h++;return this},c.Particles.Arcade.Emitter.prototype.kill=function(){this.on=!1,this.alive=!1,this.exists=!1},c.Particles.Arcade.Emitter.prototype.revive=function(){this.alive=!0,this.exists=!0},c.Particles.Arcade.Emitter.prototype.start=function(a,b,c,d){"undefined"==typeof a&&(a=!0),"undefined"==typeof b&&(b=0),"undefined"==typeof c&&(c=250),"undefined"==typeof d&&(d=0),this.revive(),this.visible=!0,this.on=!0,this._explode=a,this.lifespan=b,this.frequency=c,a?this._quantity=d:this._quantity+=d,this._counter=0,this._timer=this.game.time.now+c},c.Particles.Arcade.Emitter.prototype.emitParticle=function(){var a=this.getFirstExists(!1);if(null!=a){if(this.width>1||this.height>1?a.reset(this.game.rnd.integerInRange(this.left,this.right),this.game.rnd.integerInRange(this.top,this.bottom)):a.reset(this.emitX,this.emitY),a.lifespan=this.lifespan,a.body.bounce.setTo(this.bounce.x,this.bounce.y),a.body.velocity.x=this.minParticleSpeed.x!=this.maxParticleSpeed.x?this.game.rnd.integerInRange(this.minParticleSpeed.x,this.maxParticleSpeed.x):this.minParticleSpeed.x,a.body.velocity.y=this.minParticleSpeed.y!=this.maxParticleSpeed.y?this.game.rnd.integerInRange(this.minParticleSpeed.y,this.maxParticleSpeed.y):this.minParticleSpeed.y,a.body.gravity.y=this.gravity,a.body.angularVelocity=this.minRotation!=this.maxRotation?this.game.rnd.integerInRange(this.minRotation,this.maxRotation):this.minRotation,1!==this.minParticleScale||1!==this.maxParticleScale){var b=this.game.rnd.realInRange(this.minParticleScale,this.maxParticleScale); +a.scale.setTo(b,b)}a.body.friction=this.particleFriction,a.body.angularDrag=this.angularDrag}},c.Particles.Arcade.Emitter.prototype.setSize=function(a,b){this.width=a,this.height=b},c.Particles.Arcade.Emitter.prototype.setXSpeed=function(a,b){a=a||0,b=b||0,this.minParticleSpeed.x=a,this.maxParticleSpeed.x=b},c.Particles.Arcade.Emitter.prototype.setYSpeed=function(a,b){a=a||0,b=b||0,this.minParticleSpeed.y=a,this.maxParticleSpeed.y=b},c.Particles.Arcade.Emitter.prototype.setRotation=function(a,b){a=a||0,b=b||0,this.minRotation=a,this.maxRotation=b},c.Particles.Arcade.Emitter.prototype.at=function(a){a.center&&(this.emitX=a.center.x,this.emitY=a.center.y)},Object.defineProperty(c.Particles.Arcade.Emitter.prototype,"alpha",{get:function(){return this._container.alpha},set:function(a){this._container.alpha=a}}),Object.defineProperty(c.Particles.Arcade.Emitter.prototype,"visible",{get:function(){return this._container.visible},set:function(a){this._container.visible=a}}),Object.defineProperty(c.Particles.Arcade.Emitter.prototype,"x",{get:function(){return this.emitX},set:function(a){this.emitX=a}}),Object.defineProperty(c.Particles.Arcade.Emitter.prototype,"y",{get:function(){return this.emitY},set:function(a){this.emitY=a}}),Object.defineProperty(c.Particles.Arcade.Emitter.prototype,"left",{get:function(){return Math.floor(this.x-this.width/2)}}),Object.defineProperty(c.Particles.Arcade.Emitter.prototype,"right",{get:function(){return Math.floor(this.x+this.width/2)}}),Object.defineProperty(c.Particles.Arcade.Emitter.prototype,"top",{get:function(){return Math.floor(this.y-this.height/2)}}),Object.defineProperty(c.Particles.Arcade.Emitter.prototype,"bottom",{get:function(){return Math.floor(this.y+this.height/2)}}),c.Tile=function(a,b,c,d,e,f){this.layer=a,this.index=b,this.x=c,this.y=d,this.width=e,this.height=f,this.alpha=1,this.properties={},this.scanned=!1,this.faceTop=!1,this.faceBottom=!1,this.faceLeft=!1,this.faceRight=!1,this.collides=!1,this.collideNone=!0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1,this.callback=null,this.callbackContext=this},c.Tile.prototype={setCollisionCallback:function(a,b){this.collisionCallbackContext=b,this.collisionCallback=a},destroy:function(){this.collisionCallback=null,this.collisionCallbackContext=null,this.properties=null},setCollision:function(a,b,c,d){this.collideLeft=a,this.collideRight=b,this.collideUp=c,this.collideDown=d,this.collideNone=a||b||c||d?!1:!0},resetCollision:function(){this.collideNone=!0,this.collideLeft=!1,this.collideRight=!1,this.collideUp=!1,this.collideDown=!1},copy:function(a){this.index=a.index,this.alpha=a.alpha,this.properties=a.properties,this.collides=a.collides,this.collideNone=a.collideNone,this.collideUp=a.collideUp,this.collideDown=a.collideDown,this.collideLeft=a.collideLeft,this.collideRight=a.collideRight,this.collisionCallback=a.collisionCallback,this.collisionCallbackContext=a.collisionCallbackContext}},c.Tile.prototype.constructor=c.Tile,Object.defineProperty(c.Tile.prototype,"canCollide",{get:function(){return this.collides||this.collisionCallback||this.layer.callbacks[this.index]}}),Object.defineProperty(c.Tile.prototype,"left",{get:function(){return this.x}}),Object.defineProperty(c.Tile.prototype,"right",{get:function(){return this.x+this.width}}),Object.defineProperty(c.Tile.prototype,"top",{get:function(){return this.y}}),Object.defineProperty(c.Tile.prototype,"bottom",{get:function(){return this.y+this.height}}),c.Tilemap=function(a,b){this.game=a,this.key=b;var d=c.TilemapParser.parse(this.game,b);null!==d&&(this.width=d.width,this.height=d.height,this.tileWidth=d.tileWidth,this.tileHeight=d.tileHeight,this.orientation=d.orientation,this.version=d.version,this.properties=d.properties,this.widthInPixels=d.widthInPixels,this.heightInPixels=d.heightInPixels,this.layers=d.layers,this.tilesets=d.tilesets,this.tiles=d.tiles,this.objects=d.objects,this.images=d.images,this.currentLayer=0,this.debugMap=[],this._results=[],this._tempA=0,this._tempB=0)},c.Tilemap.CSV=0,c.Tilemap.TILED_JSON=1,c.Tilemap.prototype={create:function(a,b,d){for(var e=[],f=0;d>f;f++){e[f]=[];for(var g=0;b>g;g++)e[f][g]=0}this.layers.push({name:a,width:b,height:d,alpha:1,visible:!0,tileMargin:0,tileSpacing:0,format:c.Tilemap.CSV,data:e,indexes:[],dirty:!0}),this.currentLayer=this.layers.length-1},addTilesetImage:function(a,b){if("undefined"==typeof b){if("string"!=typeof a)return!1;b=a}return"string"==typeof a&&(a=this.getTilesetIndex(a)),this.tilesets[a]?(this.tilesets[a].image=this.game.cache.getImage(b),!0):!1},createFromTiles:function(a,b,c,d,e){"undefined"==typeof e&&(e=this.game.world)},createFromObjects:function(a,b,c,d,e,f,g){if("undefined"==typeof e&&(e=!0),"undefined"==typeof f&&(f=!0),"undefined"==typeof g&&(g=this.game.world),!this.objects[a])return console.warn("Tilemap.createFromObjects: Invalid objectgroup name given: "+a),void 0;for(var h,i=0,j=this.objects[a].length;j>i;i++)if(this.objects[a][i].gid===b){h=g.create(this.objects[a][i].x,this.objects[a][i].y,c,d,e),h.anchor.setTo(0,1),h.name=this.objects[a][i].name,h.visible=this.objects[a][i].visible,h.autoCull=f;for(property in this.objects[a][i].properties)g.set(h,property,this.objects[a][i].properties[property],!1,!1,0)}},createLayer:function(a,b,d,e){"undefined"==typeof b&&(b=this.game.width),"undefined"==typeof d&&(d=this.game.height),"undefined"==typeof e&&(e=this.game.world);var f=a;return"string"==typeof a&&(f=this.getLayerIndex(a)),null===f||f>this.layers.length?(console.warn("Tilemap.createLayer: Invalid layer ID given: "+f),void 0):e.add(new c.TilemapLayer(this.game,this,f,b,d))},getIndex:function(a,b){for(var c=0;ce;e++)this.layers[d].callbacks[a[e]]={callback:b,callbackContext:c}},setTileLocationCallback:function(a,b,c,d,e,f,g){if(g=this.getLayer(g),this.copy(a,b,c,d,g),!(this._results.length<2))for(var h=1;hd;d++)this.setCollisionByIndex(a[d],b,c,!1);this.calculateFaces(c)},setCollisionBetween:function(a,b,c,d){if("undefined"==typeof c&&(c=!0),d=this.getLayer(d),!(a>b)){for(var e=a;b>=e;e++)this.setCollisionByIndex(e,c,d,!1);this.calculateFaces(d)}},setCollisionByExclusion:function(a,b,c){"undefined"==typeof b&&(b=!0),c=this.getLayer(c);for(var d=0,e=this.tiles.length;e>d;d++)-1===a.indexOf(d)&&this.setCollisionByIndex(d,b,c,!1);this.calculateFaces(c)},setCollisionByIndex:function(a,b,c,d){"undefined"==typeof b&&(b=!0),"undefined"==typeof c&&(c=this.currentLayer),"undefined"==typeof d&&(d=!0);for(var e=0;ef;f++)for(var h=0,i=this.layers[a].width;i>h;h++){var j=this.layers[a].data[f][h];j&&(b=this.getTileAbove(a,h,f),c=this.getTileBelow(a,h,f),d=this.getTileLeft(a,h,f),e=this.getTileRight(a,h,f),b&&b.collides&&(j.faceTop=!1),c&&c.collides&&(j.faceBottom=!1),d&&d.collides&&(j.faceLeft=!1),e&&e.collides&&(j.faceRight=!1))}},getTileAbove:function(a,b,c){return c>0?this.layers[a].data[c-1][b]:null},getTileBelow:function(a,b,c){return c0?this.layers[a].data[c][b-1]:null},getTileRight:function(a,b,c){return b=0&&b=0&&d=0&&a=0&&ba&&(a=0),0>b&&(b=0),c>this.layers[e].width&&(c=this.layers[e].width),d>this.layers[e].height&&(d=this.layers[e].height),this._results.length=0,this._results.push({x:a,y:b,width:c,height:d,layer:e});for(var f=b;b+d>f;f++)for(var g=a;a+c>g;g++)this._results.push(this.layers[e].data[f][g]);return this._results},paste:function(a,b,c,d){if("undefined"==typeof a&&(a=0),"undefined"==typeof b&&(b=0),d=this.getLayer(d),c&&!(c.length<2)){for(var e=c[1].x-a,f=c[1].y-b,g=1;g1?this.debugMap[this.layers[this.currentLayer].data[c][d]]?b.push("background: "+this.debugMap[this.layers[this.currentLayer].data[c][d]]):b.push("background: #ffffff"):b.push("background: rgb(0, 0, 0)");a+="\n"}b[0]=a,console.log.apply(console,b)},destroy:function(){this.removeAllLayers(),this.data=[],this.game=null}},c.Tilemap.prototype.constructor=c.Tilemap,c.TilemapLayer=function(a,d,e,f,g){this.game=a,this.map=d,this.index=e,this.layer=d.layers[e],this.canvas=c.Canvas.create(f,g),this.context=this.canvas.getContext("2d"),this.baseTexture=new b.BaseTexture(this.canvas),this.texture=new b.Texture(this.baseTexture),this.textureFrame=new c.Frame(0,0,0,f,g,"tilemapLayer",a.rnd.uuid()),c.Sprite.call(this,this.game,0,0,this.texture,this.textureFrame),this.name="",this.type=c.TILEMAPLAYER,this.fixedToCamera=!0,this.cameraOffset=new c.Point(0,0),this.tileColor="rgb(255, 255, 255)",this.debug=!1,this.debugAlpha=.5,this.debugColor="rgba(0, 255, 0, 1)",this.debugFill=!1,this.debugFillColor="rgba(0, 255, 0, 0.2)",this.debugCallbackColor="rgba(255, 0, 0, 1)",this.scrollFactorX=1,this.scrollFactorY=1,this.dirty=!0,this._cw=d.tileWidth,this._ch=d.tileHeight,this._ga=1,this._dx=0,this._dy=0,this._dw=0,this._dh=0,this._tx=0,this._ty=0,this._tw=0,this._th=0,this._tl=0,this._maxX=0,this._maxY=0,this._startX=0,this._startY=0,this._results=[],this._x=0,this._y=0,this._prevX=0,this._prevY=0,this.updateMax()},c.TilemapLayer.prototype=Object.create(c.Sprite.prototype),c.TilemapLayer.prototype=c.Utils.extend(!0,c.TilemapLayer.prototype,c.Sprite.prototype,b.Sprite.prototype),c.TilemapLayer.prototype.constructor=c.TilemapLayer,c.TilemapLayer.prototype.postUpdate=function(){c.Sprite.prototype.postUpdate.call(this),this.scrollX=this.game.camera.x*this.scrollFactorX,this.scrollY=this.game.camera.y*this.scrollFactorY,this.render()},c.TilemapLayer.prototype.resizeWorld=function(){this.game.world.setBounds(0,0,this.layer.widthInPixels,this.layer.heightInPixels)},c.TilemapLayer.prototype._fixX=function(a){return 0>a&&(a=0),1===this.scrollFactorX?a:this._x+(a-this._x/this.scrollFactorX)},c.TilemapLayer.prototype._unfixX=function(a){return 1===this.scrollFactorX?a:this._x/this.scrollFactorX+(a-this._x)},c.TilemapLayer.prototype._fixY=function(a){return 0>a&&(a=0),1===this.scrollFactorY?a:this._y+(a-this._y/this.scrollFactorY)},c.TilemapLayer.prototype._unfixY=function(a){return 1===this.scrollFactorY?a:this._y/this.scrollFactorY+(a-this._y)},c.TilemapLayer.prototype.getTileX=function(a){return this.game.math.snapToFloor(this._fixX(a),this.map.tileWidth)/this.map.tileWidth},c.TilemapLayer.prototype.getTileY=function(a){return this.game.math.snapToFloor(this._fixY(a),this.map.tileHeight)/this.map.tileHeight},c.TilemapLayer.prototype.getTileXY=function(a,b,c){return c.x=this.getTileX(a),c.y=this.getTileY(b),c},c.TilemapLayer.prototype.getTiles=function(a,b,c,d,e){"undefined"==typeof e&&(e=!1),a=this._fixX(a),b=this._fixY(b),c>this.layer.widthInPixels&&(c=this.layer.widthInPixels),d>this.layer.heightInPixels&&(d=this.layer.heightInPixels),this._tx=this.game.math.snapToFloor(a,this._cw)/this._cw,this._ty=this.game.math.snapToFloor(b,this._ch)/this._ch,this._tw=(this.game.math.snapToCeil(c,this._cw)+this._cw)/this._cw,this._th=(this.game.math.snapToCeil(d,this._ch)+this._ch)/this._ch,this._results.length=0;for(var f=this._ty;fthis.layer.width&&(this._maxX=this.layer.width),this._maxY>this.layer.height&&(this._maxY=this.layer.height)),this.dirty=!0},c.TilemapLayer.prototype.render=function(){if(this.layer.dirty&&(this.dirty=!0),this.dirty&&this.visible){this._prevX=this._dx,this._prevY=this._dy,this._dx=-(this._x-this._startX*this.map.tileWidth),this._dy=-(this._y-this._startY*this.map.tileHeight),this._tx=this._dx,this._ty=this._dy,this.context.clearRect(0,0,this.canvas.width,this.canvas.height),this.context.fillStyle=this.tileColor;var a,d;this.debug&&(this.context.globalAlpha=this.debugAlpha);for(var e=this._startY,f=this._startY+this._maxY;f>e;e++){this._column=this.layer.data[e];for(var g=this._startX,h=this._startX+this._maxX;h>g;g++)this._column[g]&&(a=this._column[g],this.map.tiles[a.index]&&(d=this.map.tilesets[this.map.tiles[a.index][2]],d.image?(this.debug===!1&&a.alpha!==this.context.globalAlpha&&(this.context.globalAlpha=a.alpha),d.tileWidth!==this.map.tileWidth||d.tileHeight!==this.map.tileHeight?this.context.drawImage(this.map.tilesets[this.map.tiles[a.index][2]].image,this.map.tiles[a.index][0],this.map.tiles[a.index][1],d.tileWidth,d.tileHeight,Math.floor(this._tx),Math.floor(this._ty)-(d.tileHeight-this.map.tileHeight),d.tileWidth,d.tileHeight):this.context.drawImage(this.map.tilesets[this.map.tiles[a.index][2]].image,this.map.tiles[a.index][0],this.map.tiles[a.index][1],this.map.tileWidth,this.map.tileHeight,Math.floor(this._tx),Math.floor(this._ty),this.map.tileWidth,this.map.tileHeight),a.debug&&(this.context.fillStyle="rgba(0, 255, 0, 0.4)",this.context.fillRect(Math.floor(this._tx),Math.floor(this._ty),this.map.tileWidth,this.map.tileHeight))):this.context.fillRect(Math.floor(this._tx),Math.floor(this._ty),this.map.tileWidth,this.map.tileHeight))),this._tx+=this.map.tileWidth;this._tx=this._dx,this._ty+=this.map.tileHeight}return this.debug&&(this.context.globalAlpha=1,this.renderDebug()),this.game.renderType===c.WEBGL&&b.texturesToUpdate.push(this.baseTexture),this.dirty=!1,this.layer.dirty=!1,!0}},c.TilemapLayer.prototype.renderDebug=function(){this._tx=this._dx,this._ty=this._dy,this.context.strokeStyle=this.debugColor,this.context.fillStyle=this.debugFillColor;for(var a=this._startY,b=this._startY+this._maxY;b>a;a++){this._column=this.layer.data[a];for(var c=this._startX,d=this._startX+this._maxX;d>c;c++){var e=this._column[c];e&&(e.faceTop||e.faceBottom||e.faceLeft||e.faceRight)&&(this._tx=Math.floor(this._tx),this.debugFill&&this.context.fillRect(this._tx,this._ty,this._cw,this._ch),this.context.beginPath(),e.faceTop&&(this.context.moveTo(this._tx,this._ty),this.context.lineTo(this._tx+this._cw,this._ty)),e.faceBottom&&(this.context.moveTo(this._tx,this._ty+this._ch),this.context.lineTo(this._tx+this._cw,this._ty+this._ch)),e.faceLeft&&(this.context.moveTo(this._tx,this._ty),this.context.lineTo(this._tx,this._ty+this._ch)),e.faceRight&&(this.context.moveTo(this._tx+this._cw,this._ty),this.context.lineTo(this._tx+this._cw,this._ty+this._ch)),this.context.stroke()),e&&(e.collisionCallback||e.layer.callbacks[e.index])&&(this.context.fillStyle=this.debugCallbackColor,this.context.fillRect(this._tx,this._ty,this._cw,this._ch),this.context.fillStyle=this.debugFillColor),this._tx+=this.map.tileWidth}this._tx=this._dx,this._ty+=this.map.tileHeight}},Object.defineProperty(c.TilemapLayer.prototype,"scrollX",{get:function(){return this._x},set:function(a){a!==this._x&&a>=0&&this.layer.widthInPixels>this.width&&(this._x=a,this._x>this.layer.widthInPixels-this.width&&(this._x=this.layer.widthInPixels-this.width),this._startX=this.game.math.floor(this._x/this.map.tileWidth),this._startX<0&&(this._startX=0),this._startX+this._maxX>this.layer.width&&(this._startX=this.layer.width-this._maxX),this.dirty=!0)}}),Object.defineProperty(c.TilemapLayer.prototype,"scrollY",{get:function(){return this._y},set:function(a){a!==this._y&&a>=0&&this.layer.heightInPixels>this.height&&(this._y=a,this._y>this.layer.heightInPixels-this.height&&(this._y=this.layer.heightInPixels-this.height),this._startY=this.game.math.floor(this._y/this.map.tileHeight),this._startY<0&&(this._startY=0),this._startY+this._maxY>this.layer.height&&(this._startY=this.layer.height-this._maxY),this.dirty=!0)}}),Object.defineProperty(c.TilemapLayer.prototype,"collisionWidth",{get:function(){return this._cw},set:function(a){this._cw=a,this.dirty=!0}}),Object.defineProperty(c.TilemapLayer.prototype,"collisionHeight",{get:function(){return this._ch},set:function(a){this._ch=a,this.dirty=!0}}),c.TilemapParser={tileset:function(a,b,d,e,f,g,h,i,j){var k=a.cache.getTilesetImage(b);if(null===k)return console.warn("Phaser.TilemapParser.tileSet: Invalid image key given"),null;var l=k.width,m=k.height;return-1===h&&(h=Math.round(l/d)),-1===i&&(i=Math.round(m/e)),-1===j&&(j=h*i),0===l||0===m||d>l||e>m||0===j?(console.warn("Phaser.TilemapParser.tileSet: width/height zero or width/height < given tileWidth/tileHeight"),null):new c.Tileset(k,b,d,e,f,g,h,i,j)},parse:function(a,b){var d=a.cache.getTilemapData(b);return d?d.format===c.Tilemap.CSV?this.parseCSV(d.data):d.format===c.Tilemap.TILED_JSON?this.parseTiledJSON(d.data):void 0:{layers:[],objects:[],images:[],tilesets:[]}},parseCSV:function(a){a=a.trim();for(var b=[],c=a.split("\n"),d=c.length,e=0,f=0;fj;j++)a.layers[e].data[j]>0?h.push(new c.Tile(f,a.layers[e].data[j],g,i.length,a.tilewidth,a.tileheight)):h.push(null),g++,g===a.layers[e].width&&(i.push(h),g=0,h=[]);f.data=i,d.push(f)}b.layers=d;for(var l=[],e=0;eo;o++)if(a.layers[e].objects[o].gid){var p={gid:a.layers[e].objects[o].gid,name:a.layers[e].objects[o].name,x:a.layers[e].objects[o].x,y:a.layers[e].objects[o].y,visible:a.layers[e].objects[o].visible,properties:a.layers[e].objects[o].properties};n[a.layers[e].name].push(p)}}b.objects=n;for(var q=[],e=0;e0&&(b.Texture.frameUpdates.length=0)},b.CanvasRenderer.prototype.renderDisplayObject=function(a,d){var e=a.last._iNext;a=a.first;do if(a.visible||d)if(a.renderable&&0!==a.alpha){if(a instanceof b.Sprite)a.texture.frame&&(this.context.globalAlpha=a.worldAlpha,c.CANVAS_PX_ROUND?this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],Math.floor(a.worldTransform[2]),Math.floor(a.worldTransform[5])):this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2],a.worldTransform[5]),a.texture.trimmed&&this.context.transform(1,0,0,1,a.texture.trim.x,a.texture.trim.y),this.smoothProperty&&this.scaleMode!==a.texture.baseTexture.scaleMode&&(this.scaleMode=a.texture.baseTexture.scaleMode,this.context[this.smoothProperty]=this.scaleMode===b.BaseTexture.SCALE_MODE.LINEAR),this.context.drawImage(a.texture.baseTexture.source,a.texture.frame.x,a.texture.frame.y,a.texture.frame.width,a.texture.frame.height,Math.floor(a.anchor.x*-a.texture.frame.width),Math.floor(a.anchor.y*-a.texture.frame.height),a.texture.frame.width,a.texture.frame.height));else if(a instanceof b.Strip)this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2],a.worldTransform[5]),this.renderStrip(a);else if(a instanceof b.TilingSprite)this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2],a.worldTransform[5]),this.renderTilingSprite(a);else if(a instanceof b.CustomRenderable)a.renderCanvas(this);else if(a instanceof b.Graphics)this.context.setTransform(a.worldTransform[0],a.worldTransform[3],a.worldTransform[1],a.worldTransform[4],a.worldTransform[2],a.worldTransform[5]),b.CanvasGraphics.renderGraphics(a,this.context);else if(a instanceof b.FilterBlock)if(a.open){this.context.save();var f=a.mask.alpha,g=a.mask.worldTransform;this.context.setTransform(g[0],g[3],g[1],g[4],g[2],g[5]),a.mask.worldAlpha=.5,this.context.worldAlpha=0,b.CanvasGraphics.renderGraphicsMask(a.mask,this.context),this.context.clip(),a.mask.worldAlpha=f}else this.context.restore();a=a._iNext}else a=a._iNext;else a=a.last._iNext;while(a!=e)},b.WebGLBatch.prototype.update=function(){for(var a,c,d,e,f,g,h,i,j,k,l,m,n,o,p,q,r=0,s=this.head;s;){if(s.vcount===b.visibleCount){if(c=s.texture.frame.width,d=s.texture.frame.height,e=s.anchor.x,f=s.anchor.y,g=c*(1-e),h=c*-e,i=d*(1-f),j=d*-f,k=8*r,a=s.worldTransform,l=a[0],m=a[3],n=a[1],o=a[4],p=a[2],q=a[5],s.texture.trimmed&&(p+=s.texture.trim.x,q+=s.texture.trim.y),this.verticies[k+0]=l*h+n*j+p,this.verticies[k+1]=o*j+m*h+q,this.verticies[k+2]=l*g+n*j+p,this.verticies[k+3]=o*j+m*g+q,this.verticies[k+4]=l*g+n*i+p,this.verticies[k+5]=o*i+m*g+q,this.verticies[k+6]=l*h+n*i+p,this.verticies[k+7]=o*i+m*h+q,s.updateFrame||s.texture.updateFrame){this.dirtyUVS=!0;var t=s.texture,u=t.frame,v=t.baseTexture.width,w=t.baseTexture.height;this.uvs[k+0]=u.x/v,this.uvs[k+1]=u.y/w,this.uvs[k+2]=(u.x+u.width)/v,this.uvs[k+3]=u.y/w,this.uvs[k+4]=(u.x+u.width)/v,this.uvs[k+5]=(u.y+u.height)/w,this.uvs[k+6]=u.x/v,this.uvs[k+7]=(u.y+u.height)/w,s.updateFrame=!1}if(s.cacheAlpha!=s.worldAlpha){s.cacheAlpha=s.worldAlpha;var x=4*r;this.colors[x]=this.colors[x+1]=this.colors[x+2]=this.colors[x+3]=s.worldAlpha,this.dirtyColors=!0}}else k=8*r,this.verticies[k+0]=0,this.verticies[k+1]=0,this.verticies[k+2]=0,this.verticies[k+3]=0,this.verticies[k+4]=0,this.verticies[k+5]=0,this.verticies[k+6]=0,this.verticies[k+7]=0;r++,s=s.__next}},c}); \ No newline at end of file diff --git a/changelog.md b/changelog.md index 58ff30ca..b8556ae2 100644 --- a/changelog.md +++ b/changelog.md @@ -1,7 +1,80 @@ Change Log ----------- +========== + +Version 1.1.3 - "Arafel" - November 29th 2013 +--------------------------------------------- + +New features: + +* Phaser.Filter. A new way to use the new WebGL shaders/filters that the new version of Pixi supports. +* Phaser.BitmapData object. A Canvas you can freely draw to with lots of functions. Can be used as a texture for Sprites. See the new examples and docs for details. +* The entire Phaser library has been updated to match the new JSHint configuration. +* Added a .jshintrc so contributions can be run through JSHint to help retain formatting across the library (thanks kevinthompson) +* Added a new in-built texture. Sprites now use __default if no texture was provided (a 32x32 transparent PNG) or __missing if one was given but not found (a 32x32 black box with a green cross through it) +* Loader can now load JavaScript files. Just use game.load.script('key', 'url') - the file will be turned into a script tag in the document head on successful load. +* RenderTexture.render now takes a Phaser.Group. Also added renderXY for when you don't want to make a new Point object. +* Physics.overlap now supports Sprites, Groups or Emitters and can perform group vs. group (etc) overlap checks with a custom callback and process handler. +* Added Sound.externalNode which allows you to connect a Sound to an external node input rather than the SoundManager gain node. +* Added SoundManager.connectToMaster boolean. Used in conjunction with Sound.externalNode you can easily configure audio nodes to connect together for special effects. +* PluginManager.remove, added PluginManager.removeAll (thanks crazysam) +* scrollFactorX/scrollFactorY have been added to TilemapLayers (thanks jcd-as) +* Phaser.Game parent can now be an HTMLElement or a string (thanks beeglebug) +* Now using the latest version of Pixi.js. Which means you can use all the sexy new WebGL filters :) +* Sprite.animations.getAnimation will return an animation instance which was added by name. +* Added Mouse.button which is set to the button that was pressed: Phaser.Mouse.LEFT_BUTTON, MIDDLE_BUTTON or RIGHT_BUTTON (thanks wKLV) +* Added Mouse.pointerLock signal which you can listen to whenever the browser enters or leaves pointer lock mode. +* StageScaleMode.forceOrientation allows you to lock your game to one orientation and display a Sprite (i.e. a "please rotate" screen) when incorrect. +* World.visible boolean added, toggles rendering of the world on/off entirely. +* Polygon class & drawPolygon method added to Graphics (thanks rjimenezda) +* Added Group.iterate, a powerful way to count or return children that match a certain criteria. Refactored Group to use iterate, lots of repeated code cut. +* Added Group.sort. You can now sort the Group based on any given numeric property (x, y, health), finally you can do depth-sorting :) Example created to show. +* Enhanced renderTexture so it can accept a Phaser.Group object and improved documentation and examples. +* Device.littleEndian boolean added. Only safe to use if the browser supports TypedArrays (which IE9 doesn't, but nearly all others do) +* You can now call game.sound.play() and simply pass it a key. The sound will play if the audio system is unlocked and optionally destroy itself on complete. +* Mouse.capture is a boolean. If set to true then DOM mouse events will have event.preventDefault() applied, if false they will propogate fully. +* The object returned by Math.sinCosGenerator now contains a length property. + +Updates: + +* Lots of documentation fixes and updates across nearly all files. Tilemap now documented for example and lots of instances of 'Description' filled out. +* ArcadePhysics.updateMotion applies the dt to the velocity calculations as well as position now (thanks jcs) +* RequestAnimationFrame now retains the callbackID which is passed to cancelRequestAnimationFrame. +* Button now goes back to over state when setFrames used in action (thanks beeglebug) +* plugins now have a postUpdate callback (thanks cocoademon) +* Tided up the Graphics object (thanks BorisKozo) +* If running in Canvas mode and you have a render function it will save the context and reset the transform before running your render function. +* Sprite will now check the exists property of the Group it is in, if the Group.exists = false the Sprite won't update. +* If you specify 'null' as a Group parent it will now revert to using the World as the parent (before only 'undefined' worked) +* Skip preupdate/update for PIXI hierarchies in which an ancestor doesn't exist (thanks cocoademon) +* Loader.audio can now accept either an array of URL strings or a single URL string (thanks crazysam + kevinthompson) +* MSPointer updated to support IE11 by dropping the prefix from the event listeners. +* Device.cocoonJS added to detect if the game is running under Cocoon or a native browser. +* Loader now uses a new queue system internally, meaning you can have assets with the same key spread across different types. + +Bug Fixes: + +* Lots of fixes to the TypeScript definitions file (many thanks gltovar) +* Tilemap commands use specified layer when one given (thanks Izzimach) +* Mouse.stop now uses the true useCapture, which means the event listeners stop listening correctly (thanks beeglebug) +* Input Keyboard example fix (thanks Atrodilla) +* BitmapText.destroy now checks if it has a canvas before calling parentNode on it. +* Group.swap had a hellish to find bug that only manifested when B-A upward swaps occured. Hours of debugging later = bug crushed. +* Point.rotate asDegrees fixed (thanks BorisKozo) +* ArcadePhysics.separateTile wasn't returning the value, so the custom process callback wasn't getting called (thanks flameiguana) +* StageScaleMode.forceOrientation now correctly stores the forcePortrait value (thanks haden) +* Fixes to Math and Loader (thanks theJare) +* Tween - isRunning not reset when non-looped tween completes (thanks crazysam + kevinthompson) +* Math.normalizeAngle and Math.wrapAngle (thanks theJare) +* Device.isTouch modified to test maxTouchPointers instead of MSPointer. +* InputHandler.checkPointerOver now checks the visible status of the Sprite Group before processing. +* The Sprite hulls (used for tile collision) were not being updated in sprite->sprite separations (thanks jcs) +* Plugins that had a postUpdate but no Update weren't being marked as active (thanks crazysam) +* StateManager.onPausedCallback function is not called when the game is paused (thanks haden) +* Fix for 'jitter' in scrolling where tilemaps & sprites are one frame off (thanks jcs) + Version 1.1.2 - November 1st 2013 +--------------------------------- * New: You'll now find a complete Basic project Template in the resources/Project Templates folder. Will add more complex ones soon. * New: Phaser.Button now has the ability to set over/out/up/down sound effects so they play automatically based on those events. @@ -33,12 +106,16 @@ Version 1.1.2 - November 1st 2013 * Fixed issue 88 - Incorrect game.input.x/y values on click with scaled stage (thanks DrHackenstein) * Fixed issue 143 - Entering full screen mode made the Input x/y coordinates go wrong. + Version 1.1.1 - October 26th 2013 +--------------------------------- * Quick patch to get Phaser.AUTO working again on Firefox / Android. * Any key added via addKey now automatically adds it to the capture list. + Version 1.1 - October 25th 2013 +------------------------------- What's New: @@ -164,7 +241,9 @@ What has been fixed: * Game.destroy will now stop the raf from running as well as close down all input related event listeners (issue 92, thanks astrism) * Pixel Perfect click detection now works even if the Sprite is part of a texture atlas. -Version 1.0.6 (September 24th 2013) + +Version 1.0.6 - September 24th 2013 +----------------------------------- * Added check into Pointer.move to always consider a Sprite that has pixelPerfect enabled, regardless of render ID. * BUG: The pixel perfect click check doesn't work if the sprite is part of a texture atlas yet. @@ -180,7 +259,9 @@ Version 1.0.6 (September 24th 2013) * Added time smoothing to Animation update to help frames hopefully not get too out of sync during long animations with high frame rates. * Added frame skip to Animation.update. If it gets too far behind it will now skip frames to try and catch up. -Version 1.0.5 (September 20th 2013) + +Version 1.0.5 - September 20th 2013 +----------------------------------- * Fixed issue in FrameData.getFrameIndexes where the input array was being ignored. * Added Math.numberArray - Returns an Array containing the numbers from min to max (inclusive), useful for animation frame construction. @@ -199,7 +280,9 @@ Version 1.0.5 (September 20th 2013) * Updated Sprite.update to set renderable to false when the object goes out of Camera, not 'visible' false, otherwise it stops the transform being updated by Pixi. * BUG: There is a known issue where the wrong rect coordinates are given to the QuadTree if the Sprite is a child of a Group or another Sprite which has an x/y offset. -Version 1.0.4 (September 18th 2013) + +Version 1.0.4 - September 18th 2013 +----------------------------------- * Small fix to Phaser.Canvas to stop it from setting overflow hidden if the parent DOM element doesn't exist. * Added Loader.setPreloadSprite(sprite, direction) - this will automatically apply a crop rect to the Sprite which is updated in line with the load progress. @@ -210,7 +293,9 @@ Version 1.0.4 (September 18th 2013) * Fixed issue in Sprite where boundsY wasn't set (thanks Cameron) * For some reason there were 2 copies of the Canvas class in the build file - fixed, a few KB saved :) -Version 1.0.3 (September 17th 2013) + +Version 1.0.3 - September 17th 2013 +----------------------------------- * FrameData.getFrameIndexes and getFrameIndexesByName refactored into a more versatile getFrames function. * Various fixes to looping parameters in the Sound system. @@ -218,7 +303,9 @@ Version 1.0.3 (September 17th 2013) * Optimised AnimationManager.add so it will only get the required frames rather than all of them and is now faster at parsing the frame data. * Fixed Phaser.Text and Phaser.BitmapText so they now render correctly and added several Text examples. -Version 1.0.2 (September 16th 2013) + +Version 1.0.2 - September 16th 2013 +----------------------------------- * Added optional parameter to Animation.stop: resetFrame. If true the animation will be stopped and then the current frame reset to the first frame in the animation. * Fixed an issue causing 'explode' particle bursts to ignore the quantity parameter. @@ -230,7 +317,9 @@ Version 1.0.2 (September 16th 2013) * Added in the start of a Breakout game * Added in the start of a Platformer game -Version 1.0.1 (September 15th 2013) + +Version 1.0.1 - September 15th 2013 +----------------------------------- * Added checks into every Group function to ensure that the Group has children before running them. * Added optional flag to Group.create which allows you to set the default exists state of the Sprites. @@ -238,7 +327,9 @@ Version 1.0.1 (September 15th 2013) * Fixed the license in package.json * Fixed a logic bug in the separateTileX function that would sometimes cause tunneling of big sprites through small tiles. + Version 0.9.8 +------------- * Massive refactoring across the entire codebase. * Removed Basic and GameObject and put Sprite on a diet. 127 properties and methods cut down to 32. @@ -347,6 +438,7 @@ Version 0.9.8 Version 0.9.6 +------------- * Virtually every class now has documentation - if you spot a typo or something missing please shout (thanks pixelpicosean). * Grunt file updated to produce the new Special FX JS file (thanks HackManiac). @@ -434,7 +526,9 @@ Version 0.9.6 * Added the GameObjectFactory to Phaser.State * Added new format parameter to Loader.addTextureAtlas defining the format. Currently supported: JSON Array and Starling/Sparrow XML. + Version 0.9.5 +------------- * Moved the BootScreen and PauseScreen out of Stage into their own classes (system/screens/BootScreen and PauseScreen). * Updated the PauseScreen to show a subtle animation effect, making it easier to create your own interesting pause screens. @@ -468,7 +562,9 @@ Version 0.9.5 * Added fun new "map draw" test - rebound those carrots! :) * Changed SoundManager class to respect volume on first play (thanks initials and hackmaniac) + Version 0.9.4 +-------------- * Added Tilemap.getTile, getTileFromWorldXY, getTileFromInputXY * Added Tilemap.setCollisionByIndex and setCollisionByRange @@ -480,7 +576,9 @@ Version 0.9.4 * Fixed: Circle.isEmpty properly checks diameter (thanks bapuna) * Updated Gruntfile to export new version of phaser.js wrapped in a UMD block for require.js/commonJS (thanks Hackmaniac) -V0.9.3 + +Version 0.9.3 +------------- * Added the new ScrollZone game object. Endlessly useful but especially for scrolling backdrops. Created 6 example tests. * Added GameObject.hideFromCamera(cameraID) to stop an object rendering to specific cameras (also showToCamera and clearCameraList) @@ -498,7 +596,9 @@ V0.9.3 * Removed the need for DynamicTextures to require a key property and updated test cases. * You can now pass an array or a single value to Input.Keyboard.addKeyCapture(). + Version 0.9.2 +------------- * Fixed issue with create not being called if there was an empty init method. * Added ability to flip a sprite (Sprite.flipped = true) + a test case for it. @@ -506,7 +606,9 @@ Version 0.9.2 * Sprite animations don't restart if you call play on them when they are already running. * Added Stage.disablePauseScreen. Set to true to stop your game pausing when the tab loses focus. + Version 0.9.1 +------------- * Added the new align property to GameObjects that controls placement when rendering. * Added an align example to the Sprites test group (click the mouse to change alignment position) @@ -517,6 +619,7 @@ for new collision system. * Updated the States examples to bring in-line with 0.9 release. Version 0.9 +----------- * Large refactoring. Everything now lives inside the Phaser module, so all code and all tests have been updated to reflect this. Makes coding a tiny bit more verbose but stops the framework from globbing up the global namespace. Also should make code-insight work in WebStorm and similar editors. * Added the new GeomSprite object. This is a sprite that uses a geometry class for display (Circle, Rectangle, Point, Line). It's extremely flexible! @@ -527,27 +630,35 @@ Version 0.9 * Added new Motion class which contains lots of handy functions like 'moveTowardsObject', 'velocityFromAngle' and more. * Tween Manager added. You can now create tweens via Game.createTween (or for more control game.tweens). All the usual suspects are here: Bounce, * Elastic, Quintic, etc and it's hooked into the core game clock, so if your game pauses and resumes your tweens adjust accordingly. + Version 0.8 +----------- * Added ability to set Sprite frame by name (sprite.frameName), useful when you've loaded a Texture Atlas with filename values set rather than using frame indexes. * Updated texture atlas 4 demo to show this. * Fixed a bug that would cause a run-time error if you tried to create a sprite using an invalid texture key. * Added in DynamicTexture support and a test case for it. + Version 0.7 +----------- * Renamed FullScreen to StageScaleMode as it's much more fitting. Tested across Android and iOS with the various scale modes. * Added in world x/y coordinates to the input class, and the ability to get world x/y input coordinates from any Camera. * Added the RandomDataGenerator for seeded random number generation. * Setting the game world size now resizes the default camera (optional bool flag) + Version 0.6 +----------- * Added in Touch support for mobile devices (and desktops that enable it) and populated x/y coords in Input with common values from touch and mouse. * Added new Circle geometry class (used by Touch) and moved them into a Geom folder. * Added in Device class for device inspection. * Added FullScreen class to enable full-screen support on mobile devices (scrolls URL bar out of the way on iOS and Android) + Version 0.5 +----------- * Initial release diff --git a/docs/Animation.js.html b/docs/Animation.js.html index 9234bde6..b367005b 100644 --- a/docs/Animation.js.html +++ b/docs/Animation.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -466,7 +460,7 @@ Phaser.Animation = function (game, parent, name, frameData, frames, delay, loope
         this.name = name;
     
         /**
    -    * @property {object} _frames
    +    * @property {array} _frames
         * @private
         */
         this._frames = [];
    @@ -483,7 +477,8 @@ Phaser.Animation = function (game, parent, name, frameData, frames, delay, loope
         this.looped = looped;
     
         /**
    -    * @property {boolean} looped - The loop state of the Animation.
    +    * @property {boolean} killOnComplete - Should the parent of this Animation be killed when the animation completes?
    +    * @default
         */
         this.killOnComplete = false;
     
    @@ -750,6 +745,8 @@ Phaser.Animation.prototype = {
     
     };
     
    +Phaser.Animation.prototype.constructor = Phaser.Animation;
    +
     /**
     * @name Phaser.Animation#paused
     * @property {boolean} paused - Gets and sets the paused state of this Animation.
    @@ -906,13 +903,13 @@ Phaser.Animation.generateFrameNames = function (prefix, start, stop, suffix, zer
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/AnimationManager.js.html b/docs/AnimationManager.js.html index 48a1f83a..7361a183 100644 --- a/docs/AnimationManager.js.html +++ b/docs/AnimationManager.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -734,6 +728,8 @@ Phaser.AnimationManager.prototype = {
     
     };
     
    +Phaser.AnimationManager.prototype.constructor = Phaser.AnimationManager;
    +
     /**
     * @name Phaser.AnimationManager#frameData
     * @property {Phaser.FrameData} frameData - The current animations FrameData.
    @@ -863,13 +859,13 @@ Object.defineProperty(Phaser.AnimationManager.prototype, 'frameName', {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/AnimationParser.js.html b/docs/AnimationParser.js.html index 7e14835d..63062ca5 100644 --- a/docs/AnimationParser.js.html +++ b/docs/AnimationParser.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -443,9 +437,11 @@ Phaser.AnimationParser = {
         * @param {number} frameWidth - The fixed width of each frame of the animation.
         * @param {number} frameHeight - The fixed height of each frame of the animation.
         * @param {number} [frameMax=-1] - The total number of animation frames to extact from the Sprite Sheet. The default value of -1 means "extract all frames".
    +    * @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here.
    +    * @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here.
         * @return {Phaser.FrameData} A FrameData object containing the parsed frames.
         */
    -    spriteSheet: function (game, key, frameWidth, frameHeight, frameMax) {
    +    spriteSheet: function (game, key, frameWidth, frameHeight, frameMax, margin, spacing) {
     
             //  How big is our image?
             var img = game.cache.getImage(key);
    @@ -486,8 +482,8 @@ Phaser.AnimationParser = {
     
             //  Let's create some frames then
             var data = new Phaser.FrameData();
    -        var x = 0;
    -        var y = 0;
    +        var x = margin;
    +        var y = margin;
     
             for (var i = 0; i < total; i++)
             {
    @@ -502,12 +498,12 @@ Phaser.AnimationParser = {
                     height: frameHeight
                 });
     
    -            x += frameWidth;
    +            x += frameWidth + spacing;
     
                 if (x === width)
                 {
    -                x = 0;
    -                y += frameHeight;
    +                x = margin;
    +                y += frameHeight + spacing;
                 }
             }
     
    @@ -761,13 +757,13 @@ Phaser.AnimationParser = {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/ArcadePhysics.js.html b/docs/ArcadePhysics.js.html index 0dd1246e..f1d2775b 100644 --- a/docs/ArcadePhysics.js.html +++ b/docs/ArcadePhysics.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -453,9 +447,34 @@ Phaser.Physics.Arcade = function (game) {
         this.gravity = new Phaser.Point();
     
         /**
    -    * @property {Phaser.Rectangle} bounds - The bounds inside of which the physics world exists. Defaults to match the world bounds.
    +    * @property {SAT.Box} worldLeft - The left hand side of the physics bounds.
         */
    -    this.bounds = new Phaser.Rectangle(0, 0, game.world.width, game.world.height);
    +    this.worldLeft = null;
    +
    +    /**
    +    * @property {SAT.Box} worldRight - The right hand side of the physics bounds.
    +    */
    +    this.worldRight = null;
    +
    +    /**
    +    * @property {SAT.Box} worldTop - The top side of the physics bounds.
    +    */
    +    this.worldTop = null;
    +
    +    /**
    +    * @property {SAT.Box} worldBottom - The bottom of the physics bounds.
    +    */
    +    this.worldBottom = null;
    +
    +    /**
    +    * @property {array<SAT.Polygon>} worldPolys - An array of the polygon data from the physics bounds.
    +    */
    +    this.worldPolys = [ null, null, null, null ];
    +
    +    /**
    +    * @property {Phaser.QuadTree} quadTree - The world QuadTree.
    +    */
    +    this.quadTree = new Phaser.QuadTree(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels);
     
         /**
         * @property {number} maxObjects - Used by the QuadTree to set the maximum number of objects per quad.
    @@ -467,77 +486,6 @@ Phaser.Physics.Arcade = function (game) {
         */
         this.maxLevels = 4;
     
    -    /**
    -    * @property {number} OVERLAP_BIAS - A value added to the delta values during collision checks.
    -    */
    -    this.OVERLAP_BIAS = 4;
    -
    -    /**
    -    * @property {Phaser.QuadTree} quadTree - The world QuadTree.
    -    */
    -    this.quadTree = new Phaser.QuadTree(this, this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels);
    -
    -    /**
    -    * @property {number} quadTreeID - The QuadTree ID.
    -    */
    -    this.quadTreeID = 0;
    -
    -    //  Avoid gc spikes by caching these values for re-use
    -
    -    /**
    -    * @property {Phaser.Rectangle} _bounds1 - Internal cache var.
    -    * @private
    -    */
    -    this._bounds1 = new Phaser.Rectangle();
    -
    -    /**
    -    * @property {Phaser.Rectangle} _bounds2 - Internal cache var.
    -    * @private
    -    */
    -    this._bounds2 = new Phaser.Rectangle();
    -
    -    /**
    -    * @property {number} _overlap - Internal cache var.
    -    * @private
    -    */
    -    this._overlap = 0;
    -
    -    /**
    -    * @property {number} _maxOverlap - Internal cache var.
    -    * @private
    -    */
    -    this._maxOverlap = 0;
    -
    -    /**
    -    * @property {number} _velocity1 - Internal cache var.
    -    * @private
    -    */
    -    this._velocity1 = 0;
    -
    -    /**
    -    * @property {number} _velocity2 - Internal cache var.
    -    * @private
    -    */
    -    this._velocity2 = 0;
    -
    -    /**
    -    * @property {number} _newVelocity1 - Internal cache var.
    -    * @private
    -    */
    -    this._newVelocity1 = 0;
    -
    -    /**
    -    * @property {number} _newVelocity2 - Internal cache var.
    -    * @private
    -    */
    -    this._newVelocity2 = 0;
    -
    -    /**
    -    * @property {number} _average - Internal cache var.
    -    * @private
    -    */
    -    this._average = 0;
    -
         /**
         * @property {Array} _mapData - Internal cache var.
         * @private
    @@ -568,6 +516,12 @@ Phaser.Physics.Arcade = function (game) {
         */
         this._angle = 0;
     
    +    /**
    +    * @property {number} _drag - Internal cache var.
    +    * @private
    +    */
    +    this._drag = 0;
    +
         /**
         * @property {number} _dx - Internal cache var.
         * @private
    @@ -580,10 +534,212 @@ Phaser.Physics.Arcade = function (game) {
         */
         this._dy = 0;
     
    +    /**
    +    * @property {Phaser.Point} _p - Internal cache var.
    +    * @private
    +    */
    +    this._p = new Phaser.Point(0, 0);
    +
    +    /**
    +    * @property {number} _intersection - Internal cache var.
    +    * @private
    +    */
    +    this._intersection = [0,0,0,0];
    +
    +    /**
    +    * @property {number} _gravityX - Internal cache var.
    +    * @private
    +    */
    +    this._gravityX = 0;
    +
    +    /**
    +    * @property {number} _gravityY - Internal cache var.
    +    * @private
    +    */
    +    this._gravityY = 0;
    +
    +    /**
    +    * @property {SAT.Response} _response - Internal cache var.
    +    * @private
    +    */
    +    this._response = new SAT.Response();
    +
    +    //  Set the bounds to the world as default
    +    this.setBoundsToWorld(true, true, true, true);
    +
     };
     
    +/**
    +* @constant
    +* @type {number}
    +*/
    +Phaser.Physics.Arcade.RECT = 0;
    +
    +/**
    +* @constant
    +* @type {number}
    +*/
    +Phaser.Physics.Arcade.CIRCLE = 1;
    +
    +/**
    +* @constant
    +* @type {number}
    +*/
    +Phaser.Physics.Arcade.POLYGON = 2;
    +
     Phaser.Physics.Arcade.prototype = {
     
    +    /**
    +    * Checks the given Physics.Body against the Physics Bounds, if any are set, and separates them, setting the blocked flags on the Body as it does so.
    +    *
    +    * @method Phaser.Physics.Arcade#checkBounds
    +    * @param {Phaser.Physics.Arcade.Body} The Body object to be checked.
    +    * @return {boolean} True if the body hit the bounds, otherwise false.
    +    */
    +    checkBounds: function (body) {
    +
    +        if (!body.collideWorldBounds || (!this.worldLeft && !this.worldRight && !this.worldTop && !this.worldBottom))
    +        {
    +            return false;
    +        }
    +
    +        this._response.clear();
    +
    +        var test = SAT.testPolygonPolygon;
    +        var part = body.polygon;
    +        var rebounded = false;
    +
    +        if (body.type === Phaser.Physics.Arcade.CIRCLE)
    +        {
    +            test = SAT.testPolygonCircle;
    +            part = body.shape;
    +        }
    +
    +        if (this.worldLeft && test(this.worldPolys[0], part, this._response))
    +        {
    +            body.blocked.left = true;
    +            part.pos.add(this._response.overlapV);
    +            body.blocked.x = Math.floor(body.x);
    +            body.blocked.y = Math.floor(body.y);
    +            rebounded = true;
    +        }
    +        else if (this.worldRight && test(this.worldPolys[1], part, this._response))
    +        {
    +            body.blocked.right = true;
    +            part.pos.add(this._response.overlapV);
    +            body.blocked.x = Math.floor(body.x);
    +            body.blocked.y = Math.floor(body.y);
    +            rebounded = true;
    +        }
    +
    +        this._response.clear();
    +
    +        if (this.worldTop && test(this.worldPolys[2], part, this._response))
    +        {
    +            body.blocked.up = true;
    +            part.pos.add(this._response.overlapV);
    +            body.blocked.x = Math.floor(body.x);
    +            body.blocked.y = Math.floor(body.y);
    +            rebounded = true;
    +        }
    +        else if (this.worldBottom && test(this.worldPolys[3], part, this._response))
    +        {
    +            body.blocked.down = true;
    +            part.pos.add(this._response.overlapV);
    +            body.blocked.x = Math.floor(body.x);
    +            body.blocked.y = Math.floor(body.y);
    +            rebounded = true;
    +        }
    +
    +        return rebounded;
    +
    +    },
    +
    +    /**
    +    * Sets the bounds of the Physics world to match the Game.World.
    +    * You can optionally set which 'walls' to create: left, right, top or bottom.
    +    *
    +    * @method Phaser.Physics.Arcade#setBoundsToWorld
    +    * @param {boolean} [left=true] - If true will create the left bounds wall.
    +    * @param {boolean} [right=true] - If true will create the right bounds wall.
    +    * @param {boolean} [top=true] - If true will create the top bounds wall.
    +    * @param {boolean} [bottom=true] - If true will create the bottom bounds wall.
    +    */
    +    setBoundsToWorld: function (left, right, top, bottom) {
    +
    +        this.setBounds(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, left, right, top, bottom);
    +
    +    },
    +
    +    /**
    +    * Sets the bounds of the Physics world to match the given world pixel dimensions.
    +    * You can optionally set which 'walls' to create: left, right, top or bottom.
    +    *
    +    * @method Phaser.Physics.Arcade#setBounds
    +    * @param {number} x - The x coordinate of the top-left corner of the bounds.
    +    * @param {number} y - The y coordinate of the top-left corner of the bounds.
    +    * @param {number} width - The width of the bounds.
    +    * @param {number} height - The height of the bounds.
    +    * @param {boolean} [left=true] - If true will create the left bounds wall.
    +    * @param {boolean} [right=true] - If true will create the right bounds wall.
    +    * @param {boolean} [top=true] - If true will create the top bounds wall.
    +    * @param {boolean} [bottom=true] - If true will create the bottom bounds wall.
    +    */
    +    setBounds: function (x, y, width, height, left, right, top, bottom) {
    +
    +        if (typeof left === 'undefined') { left = true; }
    +        if (typeof right === 'undefined') { right = true; }
    +        if (typeof top === 'undefined') { top = true; }
    +        if (typeof bottom === 'undefined') { bottom = true; }
    +
    +        var thickness = 100;
    +
    +        if (left)
    +        {
    +            this.worldLeft = new SAT.Box(new SAT.Vector(x - thickness, y), thickness, height);
    +            this.worldPolys[0] = this.worldLeft.toPolygon();
    +        }
    +        else
    +        {
    +            this.worldLeft = null;
    +            this.worldPolys[0] = null;
    +        }
    +
    +        if (right)
    +        {
    +            this.worldRight = new SAT.Box(new SAT.Vector(x + width, y), thickness, height);
    +            this.worldPolys[1] = this.worldRight.toPolygon();
    +        }
    +        else
    +        {
    +            this.worldRight = null;
    +            this.worldPolys[1] = null;
    +        }
    +
    +        if (top)
    +        {
    +            this.worldTop = new SAT.Box(new SAT.Vector(x, y - thickness), width, thickness);
    +            this.worldPolys[2] = this.worldTop.toPolygon();
    +        }
    +        else
    +        {
    +            this.worldTop = null;
    +            this.worldPolys[2] = null;
    +        }
    +
    +        if (bottom)
    +        {
    +            this.worldBottom = new SAT.Box(new SAT.Vector(x, y + height), width, thickness);
    +            this.worldPolys[3] = this.worldBottom.toPolygon();
    +        }
    +        else
    +        {
    +            this.worldBottom = null;
    +            this.worldPolys[3] = null;
    +        }
    +
    +    },
    +
         /**
         * Called automatically by a Physics body, it updates all motion related values on the Body.
         *
    @@ -594,113 +750,68 @@ Phaser.Physics.Arcade.prototype = {
     
             //  If you're wondering why the velocity is halved and applied twice, read this: http://www.niksula.hut.fi/~hkankaan/Homepages/gravity.html
     
    +        //  World gravity is allowed
    +        if (body.allowGravity)
    +        {
    +            this._gravityX = this.gravity.x + body.gravity.x;
    +            this._gravityY = this.gravity.y + body.gravity.y;
    +        }
    +        else
    +        {
    +            this._gravityX = body.gravity.x;
    +            this._gravityY = body.gravity.y;
    +        }
    +
    +        //  Don't apply gravity to any body that is blocked
    +        if ((this._gravityX < 0 && body.blocked.left) || (this._gravityX > 0 && body.blocked.right))
    +        {
    +            this._gravityX = 0;
    +        }
    +
    +        if ((this._gravityY < 0 && body.blocked.up) || (this._gravityY > 0 && body.blocked.down))
    +        {
    +            this._gravityY = 0;
    +        }
    +
             //  Rotation
    -        this._velocityDelta = (this.computeVelocity(0, body, body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) * this.game.time.physicsElapsed * 0.5 * 60;
    -        body.angularVelocity += this._velocityDelta;
    -        body.rotation += (body.angularVelocity * this.game.time.physicsElapsed);
    -        body.angularVelocity += this._velocityDelta;
    -
    -        //  Horizontal
    -        this._velocityDelta = (this.computeVelocity(1, body, body.velocity.x, body.acceleration.x, body.drag.x, body.maxVelocity.x) - body.velocity.x) * this.game.time.physicsElapsed * 0.5 * 60;
    -        body.velocity.x += this._velocityDelta;
    -        body.x += (body.velocity.x * this.game.time.physicsElapsed);
    -        body.velocity.x += this._velocityDelta;
    -
    -        //  Vertical
    -        this._velocityDelta = (this.computeVelocity(2, body, body.velocity.y, body.acceleration.y, body.drag.y, body.maxVelocity.y) - body.velocity.y) * this.game.time.physicsElapsed * 0.5 * 60;
    -        body.velocity.y += this._velocityDelta;
    -        body.y += (body.velocity.y * this.game.time.physicsElapsed);
    -        body.velocity.y += this._velocityDelta;
    -
    -    },
    -
    -    /**
    -    * A tween-like function that takes a starting velocity and some other factors and returns an altered velocity.
    -    *
    -    * @method Phaser.Physics.Arcade#computeVelocity
    -    * @param {number} axis - 1 for horizontal, 2 for vertical.
    -    * @param {Phaser.Physics.Arcade.Body} body - The Body object to be updated.
    -    * @param {number} velocity - Any component of velocity (e.g. 20).
    -    * @param {number} acceleration - Rate at which the velocity is changing.
    -    * @param {number} drag - Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set.
    -    * @param {number} mMax - An absolute value cap for the velocity.
    -    * @return {number} The altered Velocity value.
    -    */
    -    computeVelocity: function (axis, body, velocity, acceleration, drag, max) {
    -
    -        max = max || 10000;
    -
    -        if (axis == 1 && body.allowGravity)
    +        if (body.allowRotation)
             {
    -            velocity += this.gravity.x + body.gravity.x;
    -        }
    -        else if (axis == 2 && body.allowGravity)
    -        {
    -            velocity += this.gravity.y + body.gravity.y;
    -        }
    +            this._velocityDelta = body.angularAcceleration * this.game.time.physicsElapsed;
     
    -        if (acceleration !== 0)
    -        {
    -            velocity += acceleration * this.game.time.physicsElapsed;
    -        }
    -        else if (drag !== 0)
    -        {
    -            this._drag = drag * this.game.time.physicsElapsed;
    -
    -            if (velocity - this._drag > 0)
    +            if (body.angularDrag !== 0 && body.angularAcceleration === 0)
                 {
    -                velocity -= this._drag;
    +                this._drag = body.angularDrag * this.game.time.physicsElapsed;
    +
    +                if (body.angularVelocity > 0)
    +                {
    +                    body.angularVelocity -= this._drag;
    +                }
    +                else if (body.angularVelocity < 0)
    +                {
    +                    body.angularVelocity += this._drag;
    +                }
                 }
    -            else if (velocity + this._drag < 0)
    +
    +            body.rotation += this.game.time.physicsElapsed * (body.angularVelocity + this._velocityDelta / 2);
    +            body.angularVelocity += this._velocityDelta;
    +    
    +            if (body.angularVelocity > body.maxAngular)
                 {
    -                velocity += this._drag;
    +                body.angularVelocity = body.maxAngular;
                 }
    -            else
    +            else if (body.angularVelocity < -body.maxAngular)
                 {
    -                velocity = 0;
    +                body.angularVelocity = -body.maxAngular;
                 }
             }
     
    -        if (velocity > max)
    -        {
    -            velocity = max;
    -        }
    -        else if (velocity < -max)
    -        {
    -            velocity = -max;
    -        }
    +        // temp = acc*dt
    +        // pos = pos + dt*(vel + temp/2)
    +        // vel = vel + temp
     
    -        return velocity;
    +        this._p.setTo((body.acceleration.x + this._gravityX) * this.game.time.physicsElapsed, (body.acceleration.y + this._gravityY) * this.game.time.physicsElapsed);
     
    -    },
    -
    -    /**
    -    * Called automatically by the core game loop.
    -    *
    -    * @method Phaser.Physics.Arcade#preUpdate
    -    * @protected
    -    */
    -    preUpdate: function () {
    -
    -        //  Clear the tree
    -        this.quadTree.clear();
    -
    -        //  Create our tree which all of the Physics bodies will add themselves to
    -        this.quadTreeID = 0;
    -        this.quadTree = new Phaser.QuadTree(this, this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels);
    -
    -    },
    -
    -    /**
    -    * Called automatically by the core game loop.
    -    *
    -    * @method Phaser.Physics.Arcade#postUpdate
    -    * @protected
    -    */
    -    postUpdate: function () {
    -
    -        //  Clear the tree ready for the next update
    -        this.quadTree.clear();
    +        return this._p;
     
         },
     
    @@ -708,10 +819,11 @@ Phaser.Physics.Arcade.prototype = {
         * Checks for overlaps between two game objects. The objects can be Sprites, Groups or Emitters.
         * You can perform Sprite vs. Sprite, Sprite vs. Group and Group vs. Group overlap checks.
         * Unlike collide the objects are NOT automatically separated or have any physics applied, they merely test for overlap results.
    +    * The second parameter can be an array of objects, of differing types.
         *
         * @method Phaser.Physics.Arcade#overlap
         * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.
    -    * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.
    +    * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|array} object2 - The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.
         * @param {function} [overlapCallback=null] - An optional callback function that is called if the objects overlap. The two objects will be passed to this function in the same order in which you specified them.
         * @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then overlapCallback will only be called if processCallback returns true.
         * @param {object} [callbackContext] - The context in which to run the callbacks.
    @@ -726,83 +838,144 @@ Phaser.Physics.Arcade.prototype = {
             this._result = false;
             this._total = 0;
     
    -        //  Only test valid objects
    -        if (object1 && object2 && object1.exists && object2.exists)
    +        if (Array.isArray(object2))
             {
    -            //  SPRITES
    -            if (object1.type == Phaser.SPRITE)
    +            for (var i = 0,  len = object2.length; i < len; i++)
                 {
    -                if (object2.type == Phaser.SPRITE)
    -                {
    -                    this.overlapSpriteVsSprite(object1, object2, overlapCallback, processCallback, callbackContext);
    -                }
    -                else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
    -                {
    -                    this.overlapSpriteVsGroup(object1, object2, overlapCallback, processCallback, callbackContext);
    -                }
    -            }
    -            //  GROUPS
    -            else if (object1.type == Phaser.GROUP)
    -            {
    -                if (object2.type == Phaser.SPRITE)
    -                {
    -                    this.overlapSpriteVsGroup(object2, object1, overlapCallback, processCallback, callbackContext);
    -                }
    -                else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
    -                {
    -                    this.overlapGroupVsGroup(object1, object2, overlapCallback, processCallback, callbackContext);
    -                }
    -            }
    -            //  EMITTER
    -            else if (object1.type == Phaser.EMITTER)
    -            {
    -                if (object2.type == Phaser.SPRITE)
    -                {
    -                    this.overlapSpriteVsGroup(object2, object1, overlapCallback, processCallback, callbackContext);
    -                }
    -                else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
    -                {
    -                    this.overlapGroupVsGroup(object1, object2, overlapCallback, processCallback, callbackContext);
    -                }
    +                this.collideHandler(object1, object2[i], overlapCallback, processCallback, callbackContext, true);
                 }
             }
    +        else
    +        {
    +            this.collideHandler(object1, object2, overlapCallback, processCallback, callbackContext, true);
    +        }
     
             return (this._total > 0);
     
         },
     
         /**
    -    * An internal function. Use Phaser.Physics.Arcade.overlap instead.
    +    * Checks for collision between two game objects. You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions.
    +    * The second parameter can be an array of objects, of differing types.
    +    * The objects are also automatically separated. If you don't require separation then use ArcadePhysics.overlap instead.
    +    * An optional processCallback can be provided. If given this function will be called when two sprites are found to be colliding. It is called before any separation takes place,
    +    * giving you the chance to perform additional checks. If the function returns true then the collision and separation is carried out. If it returns false it is skipped.
    +    * The collideCallback is an optional function that is only called if two sprites collide. If a processCallback has been set then it needs to return true for collideCallback to be called.
         *
    -    * @method Phaser.Physics.Arcade#overlapSpriteVsSprite
    -    * @private
    +    * @method Phaser.Physics.Arcade#collide
    +    * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap.
    +    * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap|array} object2 - The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap.
    +    * @param {function} [collideCallback=null] - An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them.
    +    * @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them.
    +    * @param {object} [callbackContext] - The context in which to run the callbacks.
    +    * @returns {boolean} True if a collision occured otherwise false.
         */
    -    overlapSpriteVsSprite: function (sprite1, sprite2, overlapCallback, processCallback, callbackContext) {
    +    collide: function (object1, object2, collideCallback, processCallback, callbackContext) {
     
    -        this._result = Phaser.Rectangle.intersects(sprite1.body, sprite2.body);
    +        collideCallback = collideCallback || null;
    +        processCallback = processCallback || null;
    +        callbackContext = callbackContext || collideCallback;
     
    -        if (this._result)
    +        this._result = false;
    +        this._total = 0;
    +
    +        if (Array.isArray(object2))
             {
    -            //  They collided, is there a custom process callback?
    -            if (processCallback)
    +            for (var i = 0,  len = object2.length; i < len; i++)
                 {
    -                if (processCallback.call(callbackContext, sprite1, sprite2))
    -                {
    -                    this._total++;
    +                this.collideHandler(object1, object2[i], collideCallback, processCallback, callbackContext, false);
    +            }
    +        }
    +        else
    +        {
    +            this.collideHandler(object1, object2, collideCallback, processCallback, callbackContext, false);
    +        }
     
    -                    if (overlapCallback)
    -                    {
    -                        overlapCallback.call(callbackContext, sprite1, sprite2);
    -                    }
    +        return (this._total > 0);
    +
    +    },
    +
    +    /**
    +    * Internal collision handler.
    +    *
    +    * @method Phaser.Physics.Arcade#collideHandler
    +    * @private
    +    * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap.
    +    * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap. Can also be an array of objects to check.
    +    * @param {function} collideCallback - An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them.
    +    * @param {function} processCallback - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them.
    +    * @param {object} callbackContext - The context in which to run the callbacks.
    +    * @param {boolean} overlapOnly - Just run an overlap or a full collision.
    +    */
    +    collideHandler: function (object1, object2, collideCallback, processCallback, callbackContext, overlapOnly) {
    +
    +        //  Only collide valid objects
    +        if (typeof object2 === 'undefined' && (object1.type === Phaser.GROUP || object1.type === Phaser.EMITTER))
    +        {
    +            this.collideGroupVsSelf(object1, collideCallback, processCallback, callbackContext, overlapOnly);
    +            return;
    +        }
    +
    +        if (object1 && object2 && object1.exists && object2.exists)
    +        {
    +            //  SPRITES
    +            if (object1.type == Phaser.SPRITE || object1.type == Phaser.TILESPRITE)
    +            {
    +                if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
    +                {
    +                    this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
    +                }
    +                else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
    +                {
    +                    this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
    +                }
    +                else if (object2.type == Phaser.TILEMAPLAYER)
    +                {
    +                    this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
                     }
                 }
    -            else
    +            //  GROUPS
    +            else if (object1.type == Phaser.GROUP)
                 {
    -                this._total++;
    -
    -                if (overlapCallback)
    +                if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
                     {
    -                    overlapCallback.call(callbackContext, sprite1, sprite2);
    +                    this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly);
    +                }
    +                else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
    +                {
    +                    this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
    +                }
    +                else if (object2.type == Phaser.TILEMAPLAYER)
    +                {
    +                    this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
    +                }
    +            }
    +            //  TILEMAP LAYERS
    +            else if (object1.type == Phaser.TILEMAPLAYER)
    +            {
    +                if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
    +                {
    +                    this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext);
    +                }
    +                else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
    +                {
    +                    this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext);
    +                }
    +            }
    +            //  EMITTER
    +            else if (object1.type == Phaser.EMITTER)
    +            {
    +                if (object2.type == Phaser.SPRITE || object2.type == Phaser.TILESPRITE)
    +                {
    +                    this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext, overlapOnly);
    +                }
    +                else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
    +                {
    +                    this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext, overlapOnly);
    +                }
    +                else if (object2.type == Phaser.TILEMAPLAYER)
    +                {
    +                    this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
                     }
                 }
             }
    @@ -810,12 +983,32 @@ Phaser.Physics.Arcade.prototype = {
         },
     
         /**
    -    * An internal function. Use Phaser.Physics.Arcade.overlap instead.
    +    * An internal function. Use Phaser.Physics.Arcade.collide instead.
         *
    -    * @method Phaser.Physics.Arcade#overlapSpriteVsGroup
    +    * @method Phaser.Physics.Arcade#collideSpriteVsSprite
         * @private
         */
    -    overlapSpriteVsGroup: function (sprite, group, overlapCallback, processCallback, callbackContext) {
    +    collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext, overlapOnly) {
    +
    +        if (this.separate(sprite1.body, sprite2.body, processCallback, callbackContext, overlapOnly))
    +        {
    +            if (collideCallback)
    +            {
    +                collideCallback.call(callbackContext, sprite1, sprite2);
    +            }
    +
    +            this._total++;
    +        }
    +
    +    },
    +
    +    /**
    +    * An internal function. Use Phaser.Physics.Arcade.collide instead.
    +    *
    +    * @method Phaser.Physics.Arcade#collideSpriteVsGroup
    +    * @private
    +    */
    +    collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext, overlapOnly) {
     
             if (group.length === 0)
             {
    @@ -823,28 +1016,52 @@ Phaser.Physics.Arcade.prototype = {
             }
     
             //  What is the sprite colliding with in the quadtree?
    +        this.quadTree.clear();
    +
    +        this.quadTree = new Phaser.QuadTree(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height, this.maxObjects, this.maxLevels);
    +
    +        this.quadTree.populate(group);
    +
             this._potentials = this.quadTree.retrieve(sprite);
     
             for (var i = 0, len = this._potentials.length; i < len; i++)
             {
                 //  We have our potential suspects, are they in this group?
    -            if (this._potentials[i].sprite.group == group)
    +            if (this.separate(sprite.body, this._potentials[i], processCallback, callbackContext, overlapOnly))
                 {
    -                this._result = Phaser.Rectangle.intersects(sprite.body, this._potentials[i]);
    -
    -                if (this._result && processCallback)
    +                if (collideCallback)
                     {
    -                    this._result = processCallback.call(callbackContext, sprite, this._potentials[i].sprite);
    +                    collideCallback.call(callbackContext, sprite, this._potentials[i].sprite);
                     }
     
    -                if (this._result)
    -                {
    -                    this._total++;
    +                this._total++;
    +            }
    +        }
     
    -                    if (overlapCallback)
    -                    {
    -                        overlapCallback.call(callbackContext, sprite, this._potentials[i].sprite);
    -                    }
    +    },
    +
    +    /**
    +    * An internal function. Use Phaser.Physics.Arcade.collide instead.
    +    *
    +    * @method Phaser.Physics.Arcade#collideGroupVsSelf
    +    * @private
    +    */
    +    collideGroupVsSelf: function (group, collideCallback, processCallback, callbackContext, overlapOnly) {
    +
    +        if (group.length === 0)
    +        {
    +            return;
    +        }
    +
    +        var len = group._container.children.length;
    +
    +        for (var i = 0; i < len; i++)
    +        {
    +            for (var j = i + 1; j <= len; j++)
    +            {
    +                if (group._container.children[i] && group._container.children[j] && group._container.children[i].exists && group._container.children[j].exists)
    +                {
    +                    this.collideSpriteVsSprite(group._container.children[i], group._container.children[j], collideCallback, processCallback, callbackContext, overlapOnly);
                     }
                 }
             }
    @@ -852,12 +1069,12 @@ Phaser.Physics.Arcade.prototype = {
         },
     
         /**
    -    * An internal function. Use Phaser.Physics.Arcade.overlap instead.
    +    * An internal function. Use Phaser.Physics.Arcade.collide instead.
         *
    -    * @method Phaser.Physics.Arcade#overlapGroupVsGroup
    +    * @method Phaser.Physics.Arcade#collideGroupVsGroup
         * @private
         */
    -    overlapGroupVsGroup: function (group1, group2, overlapCallback, processCallback, callbackContext) {
    +    collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext, overlapOnly) {
     
             if (group1.length === 0 || group2.length === 0)
             {
    @@ -872,7 +1089,7 @@ Phaser.Physics.Arcade.prototype = {
                 {
                     if (currentNode.exists)
                     {
    -                    this.overlapSpriteVsGroup(currentNode, group2, overlapCallback, processCallback, callbackContext);
    +                    this.collideSpriteVsGroup(currentNode, group2, collideCallback, processCallback, callbackContext, overlapOnly);
                     }
                     currentNode = currentNode._iNext;
                 }
    @@ -881,99 +1098,6 @@ Phaser.Physics.Arcade.prototype = {
     
         },
     
    -    /**
    -    * Checks for collision between two game objects. The objects can be Sprites, Groups, Emitters or Tilemap Layers.
    -    * You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions.
    -    * The objects are also automatically separated.
    -    *
    -    * @method Phaser.Physics.Arcade#collide
    -    * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object1 - The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap
    -    * @param {Phaser.Sprite|Phaser.Group|Phaser.Particles.Emitter|Phaser.Tilemap} object2 - The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap
    -    * @param {function} [collideCallback=null] - An optional callback function that is called if the objects overlap. The two objects will be passed to this function in the same order in which you specified them.
    -    * @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collideCallback will only be called if processCallback returns true.
    -    * @param {object} [callbackContext] - The context in which to run the callbacks.
    -    * @returns {boolean} True if a collision occured otherwise false.
    -    */
    -    collide: function (object1, object2, collideCallback, processCallback, callbackContext) {
    -
    -        collideCallback = collideCallback || null;
    -        processCallback = processCallback || null;
    -        callbackContext = callbackContext || collideCallback;
    -
    -        this._result = false;
    -        this._total = 0;
    -
    -        //  Only collide valid objects
    -        if (object1 && object2 && object1.exists && object2.exists)
    -        {
    -            //  Can expand to support Buttons, Text, etc at a later date. For now these are the essentials.
    -
    -            //  SPRITES
    -            if (object1.type == Phaser.SPRITE)
    -            {
    -                if (object2.type == Phaser.SPRITE)
    -                {
    -                    this.collideSpriteVsSprite(object1, object2, collideCallback, processCallback, callbackContext);
    -                }
    -                else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
    -                {
    -                    this.collideSpriteVsGroup(object1, object2, collideCallback, processCallback, callbackContext);
    -                }
    -                else if (object2.type == Phaser.TILEMAPLAYER)
    -                {
    -                    this.collideSpriteVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
    -                }
    -            }
    -            //  GROUPS
    -            else if (object1.type == Phaser.GROUP)
    -            {
    -                if (object2.type == Phaser.SPRITE)
    -                {
    -                    this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext);
    -                }
    -                else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
    -                {
    -                    this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext);
    -                }
    -                else if (object2.type == Phaser.TILEMAPLAYER)
    -                {
    -                    this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
    -                }
    -            }
    -            //  TILEMAP LAYERS
    -            else if (object1.type == Phaser.TILEMAPLAYER)
    -            {
    -                if (object2.type == Phaser.SPRITE)
    -                {
    -                    this.collideSpriteVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext);
    -                }
    -                else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
    -                {
    -                    this.collideGroupVsTilemapLayer(object2, object1, collideCallback, processCallback, callbackContext);
    -                }
    -            }
    -            //  EMITTER
    -            else if (object1.type == Phaser.EMITTER)
    -            {
    -                if (object2.type == Phaser.SPRITE)
    -                {
    -                    this.collideSpriteVsGroup(object2, object1, collideCallback, processCallback, callbackContext);
    -                }
    -                else if (object2.type == Phaser.GROUP || object2.type == Phaser.EMITTER)
    -                {
    -                    this.collideGroupVsGroup(object1, object2, collideCallback, processCallback, callbackContext);
    -                }
    -                else if (object2.type == Phaser.TILEMAPLAYER)
    -                {
    -                    this.collideGroupVsTilemapLayer(object1, object2, collideCallback, processCallback, callbackContext);
    -                }
    -            }
    -        }
    -
    -        return (this._total > 0);
    -
    -    },
    -
         /**
         * An internal function. Use Phaser.Physics.Arcade.collide instead.
         *
    @@ -982,15 +1106,21 @@ Phaser.Physics.Arcade.prototype = {
         */
         collideSpriteVsTilemapLayer: function (sprite, tilemapLayer, collideCallback, processCallback, callbackContext) {
     
    -        this._mapData = tilemapLayer.getTiles(sprite.body.x, sprite.body.y, sprite.body.width, sprite.body.height, true);
    +        this._mapData = tilemapLayer.getTiles(sprite.body.left, sprite.body.top, sprite.body.width, sprite.body.height, true);
     
             if (this._mapData.length === 0)
             {
                 return;
             }
     
    -        for (var i = 0; i < this._mapData.length; i++)
    +        if (this._mapData.length > 1)
             {
    +            this.separateTiles(sprite.body, this._mapData);
    +        }
    +        else
    +        {
    +            var i = 0;
    +
                 if (this.separateTile(sprite.body, this._mapData[i]))
                 {
                     //  They collided, is there a custom process callback?
    @@ -1033,11 +1163,6 @@ Phaser.Physics.Arcade.prototype = {
                 return;
             }
     
    -        if (group.length === 0)
    -        {
    -            return;
    -        }
    -
             if (group._container.first._iNext)
             {
                 var currentNode = group._container.first._iNext;
    @@ -1055,232 +1180,39 @@ Phaser.Physics.Arcade.prototype = {
     
         },
     
    -    /**
    -    * An internal function. Use Phaser.Physics.Arcade.collide instead.
    -    *
    -    * @method Phaser.Physics.Arcade#collideSpriteVsSprite
    -    * @private
    -    */
    -    collideSpriteVsSprite: function (sprite1, sprite2, collideCallback, processCallback, callbackContext) {
    -
    -        this.separate(sprite1.body, sprite2.body);
    -
    -        if (this._result)
    -        {
    -            //  They collided, is there a custom process callback?
    -            if (processCallback)
    -            {
    -                if (processCallback.call(callbackContext, sprite1, sprite2))
    -                {
    -                    this._total++;
    -
    -                    if (collideCallback)
    -                    {
    -                        collideCallback.call(callbackContext, sprite1, sprite2);
    -                    }
    -                }
    -            }
    -            else
    -            {
    -                this._total++;
    -
    -                if (collideCallback)
    -                {
    -                    collideCallback.call(callbackContext, sprite1, sprite2);
    -                }
    -            }
    -        }
    -
    -    },
    -
    -    /**
    -    * An internal function. Use Phaser.Physics.Arcade.collide instead.
    -    *
    -    * @method Phaser.Physics.Arcade#collideSpriteVsGroup
    -    * @private
    -    */
    -    collideSpriteVsGroup: function (sprite, group, collideCallback, processCallback, callbackContext) {
    -
    -        if (group.length === 0)
    -        {
    -            return;
    -        }
    -
    -        //  What is the sprite colliding with in the quadtree?
    -        this._potentials = this.quadTree.retrieve(sprite);
    -
    -        for (var i = 0, len = this._potentials.length; i < len; i++)
    -        {
    -            //  We have our potential suspects, are they in this group?
    -            if (this._potentials[i].sprite.group == group)
    -            {
    -                this.separate(sprite.body, this._potentials[i]);
    -
    -                if (this._result && processCallback)
    -                {
    -                    this._result = processCallback.call(callbackContext, sprite, this._potentials[i].sprite);
    -                }
    -
    -                if (this._result)
    -                {
    -                    this._total++;
    -
    -                    if (collideCallback)
    -                    {
    -                        collideCallback.call(callbackContext, sprite, this._potentials[i].sprite);
    -                    }
    -                }
    -            }
    -        }
    -
    -    },
    -
    -    /**
    -    * An internal function. Use Phaser.Physics.Arcade.collide instead.
    -    *
    -    * @method Phaser.Physics.Arcade#collideGroupVsGroup
    -    * @private
    -    */
    -    collideGroupVsGroup: function (group1, group2, collideCallback, processCallback, callbackContext) {
    -
    -        if (group1.length === 0 || group2.length === 0)
    -        {
    -            return;
    -        }
    -
    -        if (group1._container.first._iNext)
    -        {
    -            var currentNode = group1._container.first._iNext;
    -                
    -            do
    -            {
    -                if (currentNode.exists)
    -                {
    -                    this.collideSpriteVsGroup(currentNode, group2, collideCallback, processCallback, callbackContext);
    -                }
    -                currentNode = currentNode._iNext;
    -            }
    -            while (currentNode != group1._container.last._iNext);
    -        }
    -
    -    },
    -
         /**
         * The core separation function to separate two physics bodies.
         * @method Phaser.Physics.Arcade#separate
         * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
         * @param {Phaser.Physics.Arcade.Body} body2 - The Body object to separate.
    -    * @returns {boolean} Returns true if the bodies were separated, otherwise false.
    +    * @param {function} [processCallback=null] - A callback function that lets you perform additional checks against the two objects if they overlap. If this function is set then the sprites will only be collided if it returns true.
    +    * @param {object} [callbackContext] - The context in which to run the process callback.
    +    * @returns {boolean} Returns true if the bodies collided, otherwise false.
         */
    -    separate: function (body1, body2) {
    +    separate: function (body1, body2, processCallback, callbackContext, overlapOnly) {
     
    -        this._result = (this.separateX(body1, body2) || this.separateY(body1, body2));
    -
    -    },
    -
    -    /**
    -    * The core separation function to separate two physics bodies on the x axis.
    -    * @method Phaser.Physics.Arcade#separateX
    -    * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
    -    * @param {Phaser.Physics.Arcade.Body} body2 - The Body object to separate.
    -    * @returns {boolean} Returns true if the bodies were separated, otherwise false.
    -    */
    -    separateX: function (body1, body2) {
    -
    -        //  Can't separate two immovable bodies
    -        if (body1.immovable && body2.immovable)
    +        if (body1 === body2 || this.intersects(body1, body2) === false)
             {
                 return false;
             }
     
    -        this._overlap = 0;
    -
    -        //  Check if the hulls actually overlap
    -        if (Phaser.Rectangle.intersects(body1, body2))
    +        //  They overlap. Is there a custom process callback? If it returns true then we can carry on, otherwise we should abort.
    +        if (processCallback && processCallback.call(callbackContext, body1.sprite, body2.sprite) === false)
             {
    -            this._maxOverlap = body1.deltaAbsX() + body2.deltaAbsX() + this.OVERLAP_BIAS;
    +            return false;
    +        }
     
    -            if (body1.deltaX() === 0 && body2.deltaX() === 0)
    +        this._response.clear();
    +
    +        if (overlapOnly)
    +        {
    +            return body1.overlap(body2, this._response);
    +        }
    +        else
    +        {
    +            if (body1.overlap(body2, this._response))
                 {
    -                //  They overlap but neither of them are moving
    -                body1.embedded = true;
    -                body2.embedded = true;
    -            }
    -            else if (body1.deltaX() > body2.deltaX())
    -            {
    -                //  Body1 is moving right and/or Body2 is moving left
    -                this._overlap = body1.x + body1.width - body2.x;
    -
    -                if ((this._overlap > this._maxOverlap) || body1.allowCollision.right === false || body2.allowCollision.left === false)
    -                {
    -                    this._overlap = 0;
    -                }
    -                else
    -                {
    -                    body1.touching.right = true;
    -                    body2.touching.left = true;
    -                }
    -            }
    -            else if (body1.deltaX() < body2.deltaX())
    -            {
    -                //  Body1 is moving left and/or Body2 is moving right
    -                this._overlap = body1.x - body2.width - body2.x;
    -
    -                if ((-this._overlap > this._maxOverlap) || body1.allowCollision.left === false || body2.allowCollision.right === false)
    -                {
    -                    this._overlap = 0;
    -                }
    -                else
    -                {
    -                    body1.touching.left = true;
    -                    body2.touching.right = true;
    -                }
    -            }
    -
    -            //  Then adjust their positions and velocities accordingly (if there was any overlap)
    -            if (this._overlap !== 0)
    -            {
    -                body1.overlapX = this._overlap;
    -                body2.overlapX = this._overlap;
    -
    -                if (body1.customSeparateX || body2.customSeparateX)
    -                {
    -                    return true;
    -                }
    -
    -                this._velocity1 = body1.velocity.x;
    -                this._velocity2 = body2.velocity.x;
    -
    -                if (!body1.immovable && !body2.immovable)
    -                {
    -                    this._overlap *= 0.5;
    -
    -                    body1.x = body1.x - this._overlap;
    -                    body2.x += this._overlap;
    -
    -                    this._newVelocity1 = Math.sqrt((this._velocity2 * this._velocity2 * body2.mass) / body1.mass) * ((this._velocity2 > 0) ? 1 : -1);
    -                    this._newVelocity2 = Math.sqrt((this._velocity1 * this._velocity1 * body1.mass) / body2.mass) * ((this._velocity1 > 0) ? 1 : -1);
    -                    this._average = (this._newVelocity1 + this._newVelocity2) * 0.5;
    -                    this._newVelocity1 -= this._average;
    -                    this._newVelocity2 -= this._average;
    -
    -                    body1.velocity.x = this._average + this._newVelocity1 * body1.bounce.x;
    -                    body2.velocity.x = this._average + this._newVelocity2 * body2.bounce.x;
    -                }
    -                else if (!body1.immovable)
    -                {
    -                    body1.x = body1.x - this._overlap;
    -                    body1.velocity.x = this._velocity2 - this._velocity1 * body1.bounce.x;
    -                }
    -                else if (!body2.immovable)
    -                {
    -                    body2.x += this._overlap;
    -                    body2.velocity.x = this._velocity1 - this._velocity2 * body2.bounce.x;
    -                }
    -				body1.updateHulls();
    -				body2.updateHulls();
    -
    -                return true;
    +                return body1.separate(body2, this._response);
                 }
             }
     
    @@ -1289,221 +1221,203 @@ Phaser.Physics.Arcade.prototype = {
         },
     
         /**
    -    * The core separation function to separate two physics bodies on the y axis.
    -    * @method Phaser.Physics.Arcade#separateY
    -    * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
    -    * @param {Phaser.Physics.Arcade.Body} body2 - The Body object to separate.
    -    * @returns {boolean} Returns true if the bodies were separated, otherwise false.
    +    * Performs a rect intersection test against the two objects.
    +    * Objects must expose properties: width, height, left, right, top, bottom.
    +    * @method Phaser.Physics.Arcade#intersects
    +    * @param {object} a - The first object to test.
    +    * @param {object} b - The second object to test.
    +    * @returns {boolean} Returns true if the objects intersect, otherwise false.
         */
    -    separateY: function (body1, body2) {
    +    intersects: function (a, b) {
     
    -        //  Can't separate two immovable or non-existing bodys
    -        if (body1.immovable && body2.immovable)
    +        var result = false;
    +
    +        if (a.width <= 0 || a.height <= 0 || b.width <= 0 || b.height <= 0)
             {
    -            return false;
    +            result = false;
             }
     
    -        this._overlap = 0;
    +        result = !(a.right < b.left || a.bottom < b.top || a.left > b.right || a.top > b.bottom);
     
    -        //  Check if the hulls actually overlap
    -        if (Phaser.Rectangle.intersects(body1, body2))
    +        if (!result && a.inContact(b))
             {
    -            this._maxOverlap = body1.deltaAbsY() + body2.deltaAbsY() + this.OVERLAP_BIAS;
    -
    -            if (body1.deltaY() === 0 && body2.deltaY() === 0)
    -            {
    -                //  They overlap but neither of them are moving
    -                body1.embedded = true;
    -                body2.embedded = true;
    -            }
    -            else if (body1.deltaY() > body2.deltaY())
    -            {
    -                //  Body1 is moving down and/or Body2 is moving up
    -                this._overlap = body1.y + body1.height - body2.y;
    -
    -                if ((this._overlap > this._maxOverlap) || body1.allowCollision.down === false || body2.allowCollision.up === false)
    -                {
    -                    this._overlap = 0;
    -                }
    -                else
    -                {
    -                    body1.touching.down = true;
    -                    body2.touching.up = true;
    -                }
    -            }
    -            else if (body1.deltaY() < body2.deltaY())
    -            {
    -                //  Body1 is moving up and/or Body2 is moving down
    -                this._overlap = body1.y - body2.height - body2.y;
    -
    -                if ((-this._overlap > this._maxOverlap) || body1.allowCollision.up === false || body2.allowCollision.down === false)
    -                {
    -                    this._overlap = 0;
    -                }
    -                else
    -                {
    -                    body1.touching.up = true;
    -                    body2.touching.down = true;
    -                }
    -            }
    -
    -            //  Then adjust their positions and velocities accordingly (if there was any overlap)
    -            if (this._overlap !== 0)
    -            {
    -                body1.overlapY = this._overlap;
    -                body2.overlapY = this._overlap;
    -
    -                if (body1.customSeparateY || body2.customSeparateY)
    -                {
    -                    return true;
    -                }
    -
    -                this._velocity1 = body1.velocity.y;
    -                this._velocity2 = body2.velocity.y;
    -
    -                if (!body1.immovable && !body2.immovable)
    -                {
    -                    this._overlap *= 0.5;
    -
    -                    body1.y = body1.y - this._overlap;
    -                    body2.y += this._overlap;
    -
    -                    this._newVelocity1 = Math.sqrt((this._velocity2 * this._velocity2 * body2.mass) / body1.mass) * ((this._velocity2 > 0) ? 1 : -1);
    -                    this._newVelocity2 = Math.sqrt((this._velocity1 * this._velocity1 * body1.mass) / body2.mass) * ((this._velocity1 > 0) ? 1 : -1);
    -                    this._average = (this._newVelocity1 + this._newVelocity2) * 0.5;
    -                    this._newVelocity1 -= this._average;
    -                    this._newVelocity2 -= this._average;
    -
    -                    body1.velocity.y = this._average + this._newVelocity1 * body1.bounce.y;
    -                    body2.velocity.y = this._average + this._newVelocity2 * body2.bounce.y;
    -                }
    -                else if (!body1.immovable)
    -                {
    -                    body1.y = body1.y - this._overlap;
    -                    body1.velocity.y = this._velocity2 - this._velocity1 * body1.bounce.y;
    -
    -                    //  This is special case code that handles things like horizontal moving platforms you can ride
    -                    if (body2.active && body2.moves && (body1.deltaY() > body2.deltaY()))
    -                    {
    -                        body1.x += body2.x - body2.lastX;
    -                    }
    -                }
    -                else if (!body2.immovable)
    -                {
    -                    body2.y += this._overlap;
    -                    body2.velocity.y = this._velocity1 - this._velocity2 * body2.bounce.y;
    -
    -                    //  This is special case code that handles things like horizontal moving platforms you can ride
    -                    if (body1.sprite.active && body1.moves && (body1.deltaY() < body2.deltaY()))
    -                    {
    -                        body2.x += body1.x - body1.lastX;
    -                    }
    -                }
    -				body1.updateHulls();
    -				body2.updateHulls();
    -
    -                return true;
    -            }
    -
    +            a.removeContact(b);
             }
     
    -        return false;
    +    },
    +
    +    /**
    +    * Performs a rect intersection test against the two objects.
    +    * Objects must expose properties: width, height, left, right, top, bottom.
    +    * @method Phaser.Physics.Arcade#tileIntersects
    +    * @param {object} body - The Body to test.
    +    * @param {object} tile - The Tile to test.
    +    * @returns {boolean} Returns true if the objects intersect, otherwise false.
    +    */
    +    tileIntersects: function (body, tile) {
    +
    +        if (body.width <= 0 || body.height <= 0 || tile.width <= 0 || tile.height <= 0)
    +        {
    +            this._intersection[4] = 0;
    +            return this._intersection;
    +        }
    +
    +        if (!(body.right < tile.x || body.bottom < tile.y || body.left > tile.right || body.top > tile.bottom))
    +        {
    +            this._intersection[0] = Math.max(body.left, tile.x);                                    // x
    +            this._intersection[1] = Math.max(body.top, tile.y);                                     // y
    +            this._intersection[2] = Math.min(body.right, tile.right) - this._intersection[0];       // width
    +            this._intersection[3] = Math.min(body.bottom, tile.bottom) - this._intersection[1];     // height
    +            this._intersection[4] = 1;
    +
    +            return this._intersection;
    +        }
    +
    +        this._intersection[4] = 0;
    +
    +        return this._intersection;
    +
    +    },
    +
    +    /**
    +    * The core separation function to separate a physics body and an array of tiles.
    +    * @method Phaser.Physics.Arcade#separateTiles
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
    +    * @param {array<Phaser.Tile>} tiles - The array of tiles to collide against.
    +    * @returns {boolean} Returns true if the body was separated, otherwise false.
    +    */
    +    separateTiles: function (body, tiles) {
    +
    +        var tile;
    +        var result = false;
    +
    +        for (var i = 0; i < tiles.length; i++)
    +        {
    +            tile = tiles[i];
    +
    +            if (this.separateTile(body, tile))
    +            {
    +                result = true;
    +            }
    +        }
    +
    +        return result;
     
         },
     
         /**
         * The core separation function to separate a physics body and a tile.
         * @method Phaser.Physics.Arcade#separateTile
    -    * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body object to separate.
         * @param {Phaser.Tile} tile - The tile to collide against.
    -    * @returns {boolean} Returns true if the bodies were separated, otherwise false.
    +    * @returns {boolean} Returns true if the body was separated, otherwise false.
         */
         separateTile: function (body, tile) {
     
    -        this._result = (this.separateTileX(body, tile, true) || this.separateTileY(body, tile, true));
    +        this._intersection = this.tileIntersects(body, tile);
     
    -        return this._result;
    -
    -    },
    -
    -    /**
    -    * The core separation function to separate a physics body and a tile on the x axis.
    -    * @method Phaser.Physics.Arcade#separateTileX
    -    * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
    -    * @param {Phaser.Tile} tile - The tile to collide against.
    -    * @returns {boolean} Returns true if the bodies were separated, otherwise false.
    -    */
    -    separateTileX: function (body, tile, separate) {
    -
    -        //  Can't separate two immovable objects (tiles are always immovable)
    -        if (body.immovable || body.deltaX() === 0 || Phaser.Rectangle.intersects(body.hullX, tile) === false)
    +        //  If the intersection area is either entirely null, or has a width/height of zero, we bail out now
    +        if (this._intersection[4] === 0 || this._intersection[2] === 0 || this._intersection[3] === 0)
             {
                 return false;
             }
     
    -        this._overlap = 0;
    -
    -        //  The hulls overlap, let's process it
    -        // this._maxOverlap = body.deltaAbsX() + this.OVERLAP_BIAS;
    -
    -        if (body.deltaX() < 0)
    +        //  They overlap. Any custom callbacks?
    +        if (tile.tile.callback || tile.layer.callbacks[tile.tile.index])
             {
    -            //  Moving left
    -            this._overlap = tile.right - body.hullX.x;
    -
    -            // if ((this._overlap > this._maxOverlap) || body.allowCollision.left === false || tile.tile.collideRight === false)
    -            if (body.allowCollision.left === false || tile.tile.collideRight === false)
    +            //  A local callback takes priority over a global callback.
    +            if (tile.tile.callback && tile.tile.callback.call(tile.tile.callbackContext, body.sprite, tile) === false)
                 {
    -                this._overlap = 0;
    +                //  Is there a tile specific collision callback? If it returns true then we can carry on, otherwise we should abort.
    +                return false;
                 }
    -            else
    +            else if (tile.layer.callbacks[tile.tile.index] && tile.layer.callbacks[tile.tile.index].callback.call(tile.layer.callbacks[tile.tile.index].callbackContext, body.sprite, tile) === false)
                 {
    -                body.touching.left = true;
    -            }
    -        }
    -        else
    -        {
    -            //  Moving right
    -            this._overlap = body.hullX.right - tile.x;
    -
    -            // if ((this._overlap > this._maxOverlap) || body.allowCollision.right === false || tile.tile.collideLeft === false)
    -            if (body.allowCollision.right === false || tile.tile.collideLeft === false)
    -            {
    -                this._overlap = 0;
    -            }
    -            else
    -            {
    -                body.touching.right = true;
    +                //  Is there a tile index collision callback? If it returns true then we can carry on, otherwise we should abort.
    +                return false;
                 }
             }
     
    -        //  Then adjust their positions and velocities accordingly (if there was any overlap)
    -        if (this._overlap !== 0)
    +        body.overlapX = 0;
    +        body.overlapY = 0;
    +
    +        var process = false;
    +
    +        if (body.deltaX() < 0 && body.checkCollision.left && tile.tile.faceRight && !body.blocked.left)
             {
    -            if (separate)
    +            //  LEFT
    +            body.overlapX = body.left - tile.right;
    +
    +            if (body.overlapX < 0)
                 {
    -                if (body.deltaX() < 0)
    -                {
    -                    body.x = body.x + this._overlap;
    -                }
    -                else
    -                {
    -                    body.x = body.x - this._overlap;
    -                }
    -
    -                if (body.bounce.x === 0)
    -                {
    -                    body.velocity.x = 0;
    -                }
    -                else
    -                {
    -                    body.velocity.x = -body.velocity.x * body.bounce.x;
    -                }
    -
    -                body.updateHulls();
    +                process = true;
                 }
    +            else
    +            {
    +                body.overlapX = 0;
    +            }
    +        }
    +        else if (body.deltaX() > 0 && body.checkCollision.right && tile.tile.faceLeft && !body.blocked.right)
    +        {
    +            //  RIGHT
    +            body.overlapX = body.right - tile.x;
     
    -            return true;
    +            if (body.overlapX > 0)
    +            {
    +                process = true;
    +            }
    +            else
    +            {
    +                body.overlapX = 0;
    +            }
    +        }
    +
    +        if (body.deltaY() < 0 && body.checkCollision.up && tile.tile.faceBottom && !body.blocked.up)
    +        {
    +            //  UP
    +            body.overlapY = body.top - tile.bottom;
    +
    +            if (body.overlapY < 0)
    +            {
    +                process = true;
    +            }
    +            else
    +            {
    +                body.overlapY = 0;
    +            }
    +        }
    +        else if (body.deltaY() > 0 && body.checkCollision.down && tile.tile.faceTop && !body.blocked.down)
    +        {
    +            //  DOWN
    +            body.overlapY = body.bottom - tile.y;
    +
    +            if (body.overlapY > 0)
    +            {
    +                process = true;
    +            }
    +            else
    +            {
    +                body.overlapY = 0;
    +            }
    +        }
    +
    +        //  Only separate on the smallest of the two values if it's a single tile
    +        if (body.overlapX !== 0 && body.overlapY !== 0)
    +        {
    +            if (Math.abs(body.overlapX) > Math.abs(body.overlapY))
    +            {
    +                body.overlapX = 0;
    +            }
    +            else
    +            {
    +                body.overlapY = 0;
    +            }
    +        }
    +
    +        //  Separate in a single sweep
    +        if (process)
    +        {
    +            return this.processTileSeparation(body);
             }
             else
             {
    @@ -1513,88 +1427,53 @@ Phaser.Physics.Arcade.prototype = {
         },
     
         /**
    -    * The core separation function to separate a physics body and a tile on the x axis.
    -    * @method Phaser.Physics.Arcade#separateTileY
    +    * Internal function to process the separation of a physics body from a tile.
    +    * @method Phaser.Physics.Arcade#processTileSeparation
    +    * @protected
         * @param {Phaser.Physics.Arcade.Body} body1 - The Body object to separate.
    -    * @param {Phaser.Tile} tile - The tile to collide against.
    -    * @returns {boolean} Returns true if the bodies were separated, otherwise false.
    +    * @returns {boolean} Returns true if separated, false if not.
         */
    -    separateTileY: function (body, tile, separate) {
    +    processTileSeparation: function (body) {
     
    -        //  Can't separate two immovable objects (tiles are always immovable)
    -        if (body.immovable || body.deltaY() === 0 || Phaser.Rectangle.intersects(body.hullY, tile) === false)
    +        if (body.overlapX < 0)
             {
    -            return false;
    +            body.x -= body.overlapX;
    +            body.left -= body.overlapX;
    +            body.right -= body.overlapX;
    +            body.blocked.x = Math.floor(body.x);
    +            body.blocked.y = Math.floor(body.y);
    +            body.blocked.left = true;
    +        }
    +        else if (body.overlapX > 0)
    +        {
    +            body.x -= body.overlapX;
    +            body.left -= body.overlapX;
    +            body.right -= body.overlapX;
    +            body.blocked.x = Math.floor(body.x);
    +            body.blocked.y = Math.floor(body.y);
    +            body.blocked.right = true;
             }
     
    -        this._overlap = 0;
    -
    -        //  The hulls overlap, let's process it
    -        // this._maxOverlap = body.deltaAbsY() + this.OVERLAP_BIAS;
    -
    -        if (body.deltaY() < 0)
    +        if (body.overlapY < 0)
             {
    -            //  Moving up
    -            this._overlap = tile.bottom - body.hullY.y;
    -
    -            // if ((this._overlap > this._maxOverlap) || body.allowCollision.up === false || tile.tile.collideDown === false)
    -            if (body.allowCollision.up === false || tile.tile.collideDown === false)
    -            {
    -                this._overlap = 0;
    -            }
    -            else
    -            {
    -                body.touching.up = true;
    -            }
    +            body.y -= body.overlapY;
    +            body.top -= body.overlapY;
    +            body.bottom -= body.overlapY;
    +            body.blocked.x = Math.floor(body.x);
    +            body.blocked.y = Math.floor(body.y);
    +            body.blocked.up = true;
             }
    -        else
    +        else if (body.overlapY > 0)
             {
    -            //  Moving down
    -            this._overlap = body.hullY.bottom - tile.y;
    -
    -            // if ((this._overlap > this._maxOverlap) || body.allowCollision.down === false || tile.tile.collideUp === false)
    -            if (body.allowCollision.down === false || tile.tile.collideUp === false)
    -            {
    -                this._overlap = 0;
    -            }
    -            else
    -            {
    -                body.touching.down = true;
    -            }
    +            body.y -= body.overlapY;
    +            body.top -= body.overlapY;
    +            body.bottom -= body.overlapY;
    +            body.blocked.x = Math.floor(body.x);
    +            body.blocked.y = Math.floor(body.y);
    +            body.blocked.down = true;
             }
     
    -        //  Then adjust their positions and velocities accordingly (if there was any overlap)
    -        if (this._overlap !== 0)
    -        {
    -            if (separate)
    -            {
    -                if (body.deltaY() < 0)
    -                {
    -                    body.y = body.y + this._overlap;
    -                }
    -                else
    -                {
    -                    body.y = body.y - this._overlap;
    -                }
    -
    -                if (body.bounce.y === 0)
    -                {
    -                    body.velocity.y = 0;
    -                }
    -                else
    -                {
    -                    body.velocity.y = -body.velocity.y * body.bounce.y;
    -                }
    -
    -                body.updateHulls();
    -            }
    -            
    -            return true;
    -        }
    -        else
    -        {
    -            return false;
    -        }
    +        return true;
     
         },
     
    @@ -1744,7 +1623,7 @@ Phaser.Physics.Arcade.prototype = {
     
         /**
         * Given the rotation (in radians) and speed calculate the acceleration and return it as a Point object, or set it to the given point object.
    -    * One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) which will set the values directly to the sprites velocity and not create a new Point object.
    +    * One way to use this is: accelerationFromRotation(rotation, 200, sprite.acceleration) which will set the values directly to the sprites acceleration and not create a new Point object.
         * 
         * @method Phaser.Physics.Arcade#accelerationFromRotation
         * @param {number} rotation - The angle in radians.
    @@ -1963,6 +1842,8 @@ Phaser.Physics.Arcade.prototype = {
         }
     
     };
    +
    +Phaser.Physics.Arcade.prototype.constructor = Phaser.Physics.Arcade;
     
    @@ -1978,13 +1859,13 @@ Phaser.Physics.Arcade.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/BitmapData.js.html b/docs/BitmapData.js.html index b38a31c2..f1e849a9 100644 --- a/docs/BitmapData.js.html +++ b/docs/BitmapData.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -1380,7 +1374,9 @@ Phaser.BitmapData.prototype = {
     
         }
     
    -}
    +};
    +
    +Phaser.BitmapData.prototype.constructor = Phaser.BitmapData;
     
     //  EaselJS Tiny API emulation
     
    @@ -1554,13 +1550,13 @@ Phaser.BitmapData.prototype.de = Phaser.BitmapData.prototype.ellipse;
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/BitmapText.js.html b/docs/BitmapText.js.html index 87502549..3f69ce4e 100644 --- a/docs/BitmapText.js.html +++ b/docs/BitmapText.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -543,11 +537,6 @@ Phaser.BitmapText = function (game, x, y, text, style) {
         this._cache.x = this.x;
         this._cache.y = this.y;
     
    -    /**
    -    * @property {boolean} renderable - A renderable object will be rendered to the context each frame.
    -    */
    -    this.renderable = true;
    -
     };
     
     Phaser.BitmapText.prototype = Object.create(PIXI.BitmapText.prototype);
    @@ -576,8 +565,8 @@ Phaser.BitmapText.prototype.update = function() {
             this._cache.dirty = true;
         }
     
    -    this.pivot.x = this.anchor.x*this.width;
    -    this.pivot.y = this.anchor.y*this.height;
    +    this.pivot.x = this.anchor.x * this.width;
    +    this.pivot.y = this.anchor.y * this.height;
     
     }
     
    @@ -674,13 +663,13 @@ Object.defineProperty(Phaser.BitmapText.prototype, 'y', {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Body.js.html b/docs/Body.js.html index 244d0230..0168e9ab 100644 --- a/docs/Body.js.html +++ b/docs/Body.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,13 +417,14 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
     /**
    -* The Physics Body is linked to a single Sprite. All physics operations should be performed against the body rather than
    -* the Sprite itself. For example you can set the velocity, acceleration, bounce values etc all on the Body.
    +* The Physics Body is linked to a single Sprite and defines properties that determine how the physics body is simulated.
    +* These properties affect how the body reacts to forces, what forces it generates on itself (to simulate friction), and how it reacts to collisions in the scene. In most cases, the properties are used to simulate physical effects.
    +* Each body also has its own property values that determine exactly how it reacts to forces and collisions in the scene.
     *
     * @class Phaser.Physics.Arcade.Body
     * @classdesc Arcade Physics Body Constructor
    @@ -453,29 +448,17 @@ Phaser.Physics.Arcade.Body = function (sprite) {
         */
         this.offset = new Phaser.Point();
     
    -    /**
    -    * @property {number} x - The x position of the physics body.
    -    * @readonly
    -    */
    -    this.x = sprite.x;
    -
    -    /**
    -    * @property {number} y - The y position of the physics body.
    -    * @readonly
    -    */
    -    this.y = sprite.y;
    -
         /**
         * @property {number} preX - The previous x position of the physics body.
         * @readonly
         */
    -    this.preX = sprite.x;
    +    this.preX = sprite.world.x;
     
         /**
         * @property {number} preY - The previous y position of the physics body.
         * @readonly
         */
    -    this.preY = sprite.y;
    +    this.preY = sprite.world.y;
     
         /**
         * @property {number} preRotation - The previous rotation of the physics body.
    @@ -484,53 +467,262 @@ Phaser.Physics.Arcade.Body = function (sprite) {
         this.preRotation = sprite.angle;
     
         /**
    -    * @property {number} screenX - The x position of the physics body translated to screen space.
    +    * @property {Phaser.Point} velocity - The velocity of the Body.
    +    */
    +    this.velocity = new Phaser.Point();
    +
    +    /**
    +    * @property {Phaser.Point} acceleration - The acceleration in pixels per second sq. of the Body.
    +    */
    +    this.acceleration = new Phaser.Point();
    +
    +    /**
    +    * @property {number} speed - The speed in pixels per second sq. of the Body.
    +    */
    +    this.speed = 0;
    +
    +    /**
    +    * @property {number} angle - The angle of the Body based on its velocity in radians.
    +    */
    +    this.angle = 0;
    +
    +    /**
    +    * @property {Phaser.Point} gravity - The gravity applied to the motion of the Body. This works in addition to any gravity set on the world.
    +    */
    +    this.gravity = new Phaser.Point();
    +
    +    /**
    +    * @property {Phaser.Point} bounce - The elasticitiy of the Body when colliding. This property determines how much energy a body maintains during a collision, i.e. its bounciness.
    +    */
    +    this.bounce = new Phaser.Point();
    +
    +    /**
    +    * @property {Phaser.Point} minVelocity - When a body rebounds off another body or a wall the minVelocity is checked. If the new velocity is lower than minVelocity the body is stopped.
    +    * @default
    +    */
    +    this.minVelocity = new Phaser.Point();
    +
    +    /**
    +    * @property {Phaser.Point} maxVelocity - The maximum velocity that the Body can reach.
    +    * @default
    +    */
    +    this.maxVelocity = new Phaser.Point(1000, 1000);
    +
    +    /**
    +    * @property {number} angularVelocity - The angular velocity of the Body.
    +    * @default
    +    */
    +    this.angularVelocity = 0;
    +
    +    /**
    +    * @property {number} angularAcceleration - The angular acceleration of the Body.
    +    * @default
    +    */
    +    this.angularAcceleration = 0;
    +
    +    /**
    +    * @property {number} angularDrag - angularDrag is used to calculate friction on the body as it rotates.
    +    * @default
    +    */
    +    this.angularDrag = 0;
    +
    +    /**
    +    * @property {number} maxAngular - The maximum angular velocity that the Body can reach.
    +    * @default
    +    */
    +    this.maxAngular = 1000;
    +
    +    /**
    +    * @property {number} mass - The mass property determines how forces affect the body, as well as how much momentum the body has when it is involved in a collision.
    +    * @default
    +    */
    +    this.mass = 1;
    +
    +    /**
    +    * @property {number} linearDamping - linearDamping is used to calculate friction on the body as it moves through the world. For example, this might be used to simulate air or water friction.
    +    * @default
    +    */
    +    this.linearDamping = 0.0;
    +
    +    /**
    +    * Set the checkCollision properties to control which directions collision is processed for this Body.
    +    * For example checkCollision.up = false means it won't collide when the collision happened while moving up.
    +    * @property {object} checkCollision - An object containing allowed collision.
    +    */
    +    this.checkCollision = { none: false, any: true, up: true, down: true, left: true, right: true };
    +
    +    /**
    +    * This object is populated with boolean values when the Body collides with another.
    +    * touching.up = true means the collision happened to the top of this Body for example.
    +    * @property {object} touching - An object containing touching results.
    +    */
    +    this.touching = { none: true, up: false, down: false, left: false, right: false };
    +
    +    /**
    +    * This object is populated with boolean values when the Body collides with the World bounds or a Tile.
    +    * For example if blocked.up is true then the Body cannot move up.
    +    * @property {object} blocked - An object containing on which faces this Body is blocked from moving, if any.
    +    */
    +    this.blocked = { x: 0, y: 0, up: false, down: false, left: false, right: false };
    +
    +    /**
    +    * @property {number} facing - A const reference to the direction the Body is traveling or facing.
    +    * @default
    +    */
    +    this.facing = Phaser.NONE;
    +
    +    /**
    +    * @property {boolean} rebound - A Body set to rebound will exchange velocity with another Body during collision. Set to false to allow this body to be 'pushed' rather than exchange velocity.
    +    * @default
    +    */
    +    this.rebound = true;
    +
    +    /**
    +    * @property {boolean} immovable - An immovable Body will not receive any impacts or exchanges of velocity from other bodies.
    +    * @default
    +    */
    +    this.immovable = false;
    +
    +    /**
    +    * @property {boolean} moves - Set to true to allow the Physics system (such as velocity) to move this Body, or false to move it manually.
    +    * @default
    +    */
    +    this.moves = true;
    +
    +    /**
    +    * @property {number} rotation - The amount the parent Sprite is rotated.
    +    * @default
    +    */
    +    this.rotation = 0;
    +
    +    /**
    +    * @property {boolean} allowRotation - Allow angular rotation? This will cause the Sprite to be rotated via angularVelocity, etc.
    +    * @default
    +    */
    +    this.allowRotation = true;
    +
    +    /**
    +    * @property {boolean} allowGravity - Allow this Body to be influenced by the global Gravity value? Note: It will always be influenced by the local gravity if set.
    +    * @default
    +    */
    +    this.allowGravity = true;
    +
    +    /**
    +    * @property {function} customSeparateCallback - If set this callback will be used for Body separation instead of the built-in one. Callback should return true if separated, otherwise false.
    +    * @default
    +    */
    +    this.customSeparateCallback = null;
    +
    +    /**
    +    * @property {object} customSeparateContext - The context in which the customSeparateCallback is called.
    +    * @default
    +    */
    +    this.customSeparateContext = null;
    +
    +    /**
    +    * @property {function} collideCallback - If set this callback will be fired whenever this Body is hit (on any face). It will send three parameters, the face it hit on, this Body and the Body that hit it.
    +    * @default
    +    */
    +    this.collideCallback = null;
    +
    +    /**
    +    * @property {object} collideCallbackContext - The context in which the collideCallback is called.
    +    * @default
    +    */
    +    this.collideCallbackContext = null;
    +
    +    /**
    +    * A Body can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World.
    +    * @property {boolean} collideWorldBounds - Should the Body collide with the World bounds?
    +    */
    +    this.collideWorldBounds = false;
    +
    +    /**
    +    * @property {Phaser.Physics.Arcade.RECT|Phaser.Physics.Arcade.CIRCLE} type - The type of SAT Shape.
    +    */
    +    this.type = Phaser.Physics.Arcade.RECT;
    +
    +    /**
    +    * @property {SAT.Box|SAT.Circle|SAT.Polygon} shape - The SAT Collision shape.
    +    */
    +    this.shape = null;
    +
    +    /**
    +    * @property {SAT.Polygon} polygon - The SAT Polygons, as derived from the Shape.
    +    */
    +    this.polygon = null;
    +
    +    /**
    +    * @property {number} left - The left-most point of this Body.
         * @readonly
         */
    -    this.screenX = sprite.x;
    +    this.left = 0;
     
         /**
    -    * @property {number} screenY - The y position of the physics body translated to screen space.
    +    * @property {number} right - The right-most point of this Body.
         * @readonly
         */
    -    this.screenY = sprite.y;
    +    this.right = 0;
     
         /**
    -    * @property {number} sourceWidth - The un-scaled original size.
    +    * @property {number} top - The top-most point of this Body.
         * @readonly
         */
    -    this.sourceWidth = sprite.currentFrame.sourceSizeW;
    +    this.top = 0;
     
         /**
    -    * @property {number} sourceHeight - The un-scaled original size.
    +    * @property {number} bottom - The bottom-most point of this Body.
         * @readonly
         */
    -    this.sourceHeight = sprite.currentFrame.sourceSizeH;
    +    this.bottom = 0;
     
         /**
    -    * @property {number} width - The calculated width of the physics body.
    +    * @property {number} width - The current width of the Body, taking into account the point rotation.
    +    * @readonly
         */
    -    this.width = sprite.currentFrame.sourceSizeW;
    +    this.width = 0;
     
         /**
    -    * @property .numInternal ID cache
    +    * @property {number} height - The current height of the Body, taking into account the point rotation.
    +    * @readonly
         */
    -    this.height = sprite.currentFrame.sourceSizeH;
    +    this.height = 0;
     
         /**
    -    * @property {number} halfWidth - The calculated width / 2 of the physics body.
    +    * @property {array<Phaser.Physics.Arcade.Body>} contacts - Used to store references to bodies this Body is in contact with.
    +    * @protected
         */
    -    this.halfWidth = Math.floor(sprite.currentFrame.sourceSizeW / 2);
    +    this.contacts = [];
     
         /**
    -    * @property {number} halfHeight - The calculated height / 2 of the physics body.
    +    * @property {number} overlapX - Mostly used internally to store the overlap values from Tile seperation.
    +    * @protected
         */
    -    this.halfHeight = Math.floor(sprite.currentFrame.sourceSizeH / 2);
    +    this.overlapX = 0;
     
         /**
    -    * @property {Phaser.Point} center - The center coordinate of the Physics Body.
    +    * @property {number} overlapY - Mostly used internally to store the overlap values from Tile seperation.
    +    * @protected
         */
    -    this.center = new Phaser.Point(this.x + this.halfWidth, this.y + this.halfHeight);
    +    this.overlapY = 0;
    +
    +    /**
    +    * @property {Phaser.Point} _temp - Internal cache var.
    +    * @private
    +    */
    +    this._temp = null;
    +
    +    /**
    +    * @property {number} _dx - Internal cache var.
    +    * @private
    +    */
    +    this._dx = 0;
    +
    +    /**
    +    * @property {number} _dy - Internal cache var.
    +    * @private
    +    */
    +    this._dy = 0;
     
         /**
         * @property {number} _sx - Internal cache var.
    @@ -545,231 +737,80 @@ Phaser.Physics.Arcade.Body = function (sprite) {
         this._sy = sprite.scale.y;
     
         /**
    -    * @property {Phaser.Point} velocity - The velocity in pixels per second sq. of the Body.
    +    * @property {array} _distances - Internal cache var.
    +    * @private
         */
    -    this.velocity = new Phaser.Point();
    +    this._distances = [0, 0, 0, 0];
     
         /**
    -    * @property {Phaser.Point} acceleration - The velocity in pixels per second sq. of the Body.
    +    * @property {number} _vx - Internal cache var.
    +    * @private
         */
    -    this.acceleration = new Phaser.Point();
    +    this._vx = 0;
     
         /**
    -    * @property {Phaser.Point} drag - The drag applied to the motion of the Body.
    +    * @property {number} _vy - Internal cache var.
    +    * @private
         */
    -    this.drag = new Phaser.Point();
    +    this._vy = 0;
     
    -    /**
    -    * @property {Phaser.Point} gravity - A private Gravity setting for the Body.
    -    */
    -    this.gravity = new Phaser.Point();
    +    //  Set-up the default shape
    +    this.setRectangle(sprite.width, sprite.height, 0, 0);
     
    -    /**
    -    * @property {Phaser.Point} bounce - The elasticitiy of the Body when colliding. bounce.x/y = 1 means full rebound, bounce.x/y = 0.5 means 50% rebound velocity.
    -    */
    -    this.bounce = new Phaser.Point();
    -
    -    /**
    -    * @property {Phaser.Point} maxVelocity - The maximum velocity in pixels per second sq. that the Body can reach.
    -    * @default
    -    */
    -    this.maxVelocity = new Phaser.Point(10000, 10000);
    -
    -    /**
    -    * @property {number} angularVelocity - The angular velocity in pixels per second sq. of the Body.
    -    * @default
    -    */
    -    this.angularVelocity = 0;
    -
    -    /**
    -    * @property {number} angularAcceleration - The angular acceleration in pixels per second sq. of the Body.
    -    * @default
    -    */
    -    this.angularAcceleration = 0;
    -
    -    /**
    -    * @property {number} angularDrag - The angular drag applied to the rotation of the Body.
    -    * @default
    -    */
    -    this.angularDrag = 0;
    -
    -    /**
    -    * @property {number} maxAngular - The maximum angular velocity in pixels per second sq. that the Body can reach.
    -    * @default
    -    */
    -    this.maxAngular = 1000;
    -
    -    /**
    -    * @property {number} mass - The mass of the Body.
    -    * @default
    -    */
    -    this.mass = 1;
    -
    -    /**
    -    * @property {boolean} skipQuadTree - If the Body is an irregular shape you can set this to true to avoid it being added to the World quad tree.
    -    * @default
    -    */
    -    this.skipQuadTree = false;
    -
    -    /**
    -    * @property {Array} quadTreeIDs - Internal ID cache.
    -    * @protected
    -    */
    -    this.quadTreeIDs = [];
    -
    -    /**
    -    * @property {number} quadTreeIndex - Internal ID cache.
    -    * @protected
    -    */
    -    this.quadTreeIndex = -1;
    -
    -    //  Allow collision
    -
    -    /**
    -    * Set the allowCollision properties to control which directions collision is processed for this Body.
    -    * For example allowCollision.up = false means it won't collide when the collision happened while moving up.
    -    * @property {object} allowCollision - An object containing allowed collision.
    -    */
    -    this.allowCollision = { none: false, any: true, up: true, down: true, left: true, right: true };
    -
    -    /**
    -    * This object is populated with boolean values when the Body collides with another.
    -    * touching.up = true means the collision happened to the top of this Body for example.
    -    * @property {object} touching - An object containing touching results.
    -    */
    -    this.touching = { none: true, up: false, down: false, left: false, right: false };
    -
    -    /**
    -    * This object is populated with previous touching values from the bodies previous collision.
    -    * @property {object} wasTouching - An object containing previous touching results.
    -    */
    -    this.wasTouching = { none: true, up: false, down: false, left: false, right: false };
    -
    -    /**
    -    * @property {number} facing - A const reference to the direction the Body is traveling or facing.
    -    * @default
    -    */
    -    this.facing = Phaser.NONE;
    -
    -    /**
    -    * @property {boolean} immovable - An immovable Body will not receive any impacts from other bodies.
    -    * @default
    -    */
    -    this.immovable = false;
    -
    -    /**
    -    * @property {boolean} moves - Set to true to allow the Physics system to move this Body, other false to move it manually.
    -    * @default
    -    */
    -    this.moves = true;
    -
    -    /**
    -    * @property {number} rotation - The amount the Body is rotated.
    -    * @default
    -    */
    -    this.rotation = 0;
    -
    -    /**
    -    * @property {boolean} allowRotation - Allow this Body to be rotated? (via angularVelocity, etc)
    -    * @default
    -    */
    -    this.allowRotation = true;
    -
    -    /**
    -    * @property {boolean} allowGravity - Allow this Body to be influenced by the global Gravity?
    -    * @default
    -    */
    -    this.allowGravity = true;
    -
    -    /**
    -    * This flag allows you to disable the custom x separation that takes place by Physics.Arcade.separate.
    -    * Used in combination with your own collision processHandler you can create whatever type of collision response you need.
    -    * @property {boolean} customSeparateX - Use a custom separation system or the built-in one?
    -    * @default
    -    */
    -    this.customSeparateX = false;
    -
    -    /**
    -    * This flag allows you to disable the custom y separation that takes place by Physics.Arcade.separate.
    -    * Used in combination with your own collision processHandler you can create whatever type of collision response you need.
    -    * @property {boolean} customSeparateY - Use a custom separation system or the built-in one?
    -    * @default
    -    */
    -    this.customSeparateY = false;
    -
    -    /**
    -    * When this body collides with another, the amount of overlap is stored here.
    -    * @property {number} overlapX - The amount of horizontal overlap during the collision.
    -    */
    -    this.overlapX = 0;
    -
    -    /**
    -    * When this body collides with another, the amount of overlap is stored here.
    -    * @property {number} overlapY - The amount of vertical overlap during the collision.
    -    */
    -    this.overlapY = 0;
    -
    -    /**
    -    * @property {Phaser.Rectangle} hullX - The dynamically calculated hull used during collision.
    -    */
    -    this.hullX = new Phaser.Rectangle();
    -
    -    /**
    -    * @property {Phaser.Rectangle} hullY - The dynamically calculated hull used during collision.
    -    */
    -    this.hullY = new Phaser.Rectangle();
    -
    -    /**
    -    * If a body is overlapping with another body, but neither of them are moving (maybe they spawned on-top of each other?) this is set to true.
    -    * @property {boolean} embedded - Body embed value.
    -    */
    -    this.embedded = false;
    -
    -    /**
    -    * A Body can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World.
    -    * @property {boolean} collideWorldBounds - Should the Body collide with the World bounds?
    -    */
    -    this.collideWorldBounds = false;
    +    //  Set-up contact events
    +    this.sprite.events.onBeginContact = new Phaser.Signal();
    +    this.sprite.events.onEndContact = new Phaser.Signal();
     
     };
     
     Phaser.Physics.Arcade.Body.prototype = {
     
         /**
    -    * Internal method.
    +    * Internal method that updates the Body scale in relation to the parent Sprite.
         *
    -    * @method Phaser.Physics.Arcade#updateBounds
    +    * @method Phaser.Physics.Arcade.Body#updateScale
         * @protected
         */
    -    updateBounds: function (centerX, centerY, scaleX, scaleY) {
    +    updateScale: function () {
     
    -        if (scaleX != this._sx || scaleY != this._sy)
    +        if (this.polygon)
             {
    -            this.width = this.sourceWidth * scaleX;
    -            this.height = this.sourceHeight * scaleY;
    -            this.halfWidth = Math.floor(this.width / 2);
    -            this.halfHeight = Math.floor(this.height / 2);
    -            this._sx = scaleX;
    -            this._sy = scaleY;
    -            this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
    +            this.polygon.scale(this.sprite.scale.x / this._sx, this.sprite.scale.y / this._sy);
             }
    +        else
    +        {
    +            this.shape.r *= Math.max(this.sprite.scale.x, this.sprite.scale.y);
    +        }
    +
    +        this._sx = this.sprite.scale.x;
    +        this._sy = this.sprite.scale.y;
     
         },
     
         /**
    -    * Internal method.
    +    * Internal method that updates the Body position in relation to the parent Sprite.
         *
    -    * @method Phaser.Physics.Arcade#preUpdate
    +    * @method Phaser.Physics.Arcade.Body#preUpdate
         * @protected
         */
         preUpdate: function () {
     
    -        //  Store and reset collision flags
    -        this.wasTouching.none = this.touching.none;
    -        this.wasTouching.up = this.touching.up;
    -        this.wasTouching.down = this.touching.down;
    -        this.wasTouching.left = this.touching.left;
    -        this.wasTouching.right = this.touching.right;
    +        this.x = (this.sprite.world.x - (this.sprite.anchor.x * this.sprite.width)) + this.offset.x;
    +        this.y = (this.sprite.world.y - (this.sprite.anchor.y * this.sprite.height)) + this.offset.y;
    +
    +        //  This covers any motion that happens during this frame, not since the last frame
    +        this.preX = this.x;
    +        this.preY = this.y;
    +        this.preRotation = this.sprite.angle;
    +
    +        this.rotation = this.preRotation;
    +
    +        if (this.sprite.scale.x !== this._sx || this.sprite.scale.y !== this._sy)
    +        {
    +            this.updateScale();
    +        }
    +
    +        this.checkBlocked();
     
             this.touching.none = true;
             this.touching.up = false;
    @@ -777,290 +818,1116 @@ Phaser.Physics.Arcade.Body.prototype = {
             this.touching.left = false;
             this.touching.right = false;
     
    -        this.embedded = false;
    -
    -        this.screenX = (this.sprite.worldTransform[2] - (this.sprite.anchor.x * this.width)) + this.offset.x;
    -        this.screenY = (this.sprite.worldTransform[5] - (this.sprite.anchor.y * this.height)) + this.offset.y;
    -
    -        this.preX = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x;
    -        this.preY = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y;
    -
    -        this.preRotation = this.sprite.angle;
    -
    -        this.x = this.preX;
    -        this.y = this.preY;
    -        this.rotation = this.preRotation;
    -
             if (this.moves)
             {
    -            this.game.physics.updateMotion(this);
    -
    -            if (this.collideWorldBounds)
    +            if (this._vx !== this.velocity.x || this._vy !== this.velocity.y)
                 {
    -                this.checkWorldBounds();
    +                //  No need to re-calc these if they haven't changed
    +                this._vx = this.velocity.x;
    +                this._vy = this.velocity.y;
    +                this.speed = Math.sqrt(this.velocity.x * this.velocity.x + this.velocity.y * this.velocity.y);
    +                this.angle = Math.atan2(this.velocity.y, this.velocity.x);
                 }
     
    -            this.updateHulls();
    -        }
    +            if (this.game.physics.checkBounds(this))
    +            {
    +                this.reboundCheck(true, true, true);
    +            }
     
    -        if (this.skipQuadTree === false && this.allowCollision.none === false && this.sprite.visible && this.sprite.alive)
    +            this.applyDamping();
    +
    +            this.integrateVelocity();
    +
    +            this.updateBounds();
    +
    +            this.checkBlocked();
    +        }
    +        else
             {
    -            this.quadTreeIDs = [];
    -            this.quadTreeIndex = -1;
    -            this.game.physics.quadTree.insert(this);
    +            this.updateBounds();
             }
     
         },
     
         /**
    -    * Internal method.
    +    * Internal method that checks and potentially resets the blocked status flags.
         *
    -    * @method Phaser.Physics.Arcade#postUpdate
    +    * @method Phaser.Physics.Arcade.Body#checkBlocked
    +    * @protected
    +    */
    +    checkBlocked: function () {
    +
    +        if ((this.blocked.left || this.blocked.right) && (Math.floor(this.x) !== this.blocked.x || Math.floor(this.y) !== this.blocked.y))
    +        {
    +            this.blocked.left = false;
    +            this.blocked.right = false;
    +        }
    +
    +        if ((this.blocked.up || this.blocked.down) && (Math.floor(this.x) !== this.blocked.x || Math.floor(this.y) !== this.blocked.y))
    +        {
    +            this.blocked.up = false;
    +            this.blocked.down = false;
    +        }
    +
    +    },
    +
    +    /**
    +    * Internal method that updates the left, right, top, bottom, width and height properties.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#updateBounds
    +    * @protected
    +    */
    +    updateBounds: function () {
    +
    +        if (this.type === Phaser.Physics.Arcade.CIRCLE)
    +        {
    +            this.left = this.shape.pos.x - this.shape.r;
    +            this.right = this.shape.pos.x + this.shape.r;
    +            this.top = this.shape.pos.y - this.shape.r;
    +            this.bottom = this.shape.pos.y + this.shape.r;
    +        }
    +        else
    +        {
    +            this.left = Phaser.Math.minProperty('x', this.polygon.points) + this.polygon.pos.x;
    +            this.right = Phaser.Math.maxProperty('x', this.polygon.points) + this.polygon.pos.x;
    +            this.top = Phaser.Math.minProperty('y', this.polygon.points) + this.polygon.pos.y;
    +            this.bottom = Phaser.Math.maxProperty('y', this.polygon.points) + this.polygon.pos.y;
    +        }
    +
    +        this.width = this.right - this.left;
    +        this.height = this.bottom - this.top;
    +
    +    },
    +
    +    /**
    +    * Internal method that checks the acceleration and applies damping if not set.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#applyDamping
    +    * @protected
    +    */
    +    applyDamping: function () {
    +
    +        if (this.linearDamping > 0 && this.acceleration.isZero())
    +        {
    +            if (this.speed > this.linearDamping)
    +            {
    +                this.speed -= this.linearDamping;
    +            }
    +            else
    +            {
    +                this.speed = 0;
    +            }
    +
    +            //  Don't bother if speed 0
    +            if (this.speed > 0)
    +            {
    +                this.velocity.x = Math.cos(this.angle) * this.speed;
    +                this.velocity.y = Math.sin(this.angle) * this.speed;
    +
    +                this.speed = Math.sqrt(this.velocity.x * this.velocity.x + this.velocity.y * this.velocity.y);
    +                this.angle = Math.atan2(this.velocity.y, this.velocity.x);
    +            }
    +        }
    +
    +    },
    +
    +    /**
    +    * Check if we're below minVelocity and gravity isn't trying to drag us in the opposite direction.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#reboundCheck
    +    * @protected
    +    * @param {boolean} x - Check the X axis?
    +    * @param {boolean} y - Check the Y axis?
    +    * @param {boolean} rebound - If true it will reverse the velocity on the given axis
    +    */
    +    reboundCheck: function (x, y, rebound) {
    +
    +        if (x)
    +        {
    +            if (rebound && this.bounce.x !== 0 && (this.blocked.left || this.blocked.right || this.touching.left || this.touching.right))
    +            {
    +                //  Don't rebound if they've already rebounded in this frame
    +                if (!(this._vx <= 0 && this.velocity.x > 0) && !(this._vx >= 0 && this.velocity.x < 0))
    +                {
    +                    this.velocity.x *= -this.bounce.x;
    +                    this.angle = Math.atan2(this.velocity.y, this.velocity.x);
    +                }
    +            }
    +
    +            if (this.bounce.x === 0 || Math.abs(this.velocity.x) < this.minVelocity.x)
    +            {
    +                var gx = this.getUpwardForce();
    +
    +                if (((this.blocked.left || this.touching.left) && (gx < 0 || this.velocity.x < 0)) || ((this.blocked.right || this.touching.right) && (gx > 0 || this.velocity.x > 0)))
    +                {
    +                    this.velocity.x = 0;
    +                }
    +            }
    +        }
    +
    +        if (y)
    +        {
    +            if (rebound && this.bounce.y !== 0 && (this.blocked.up || this.blocked.down || this.touching.up || this.touching.down))
    +            {
    +                //  Don't rebound if they've already rebounded in this frame
    +                if (!(this._vy <= 0 && this.velocity.y > 0) && !(this._vy >= 0 && this.velocity.y < 0))
    +                {
    +                    this.velocity.y *= -this.bounce.y;
    +                    this.angle = Math.atan2(this.velocity.y, this.velocity.x);
    +                }
    +            }
    +
    +            if (this.bounce.y === 0 || Math.abs(this.velocity.y) < this.minVelocity.y)
    +            {
    +                var gy = this.getDownwardForce();
    +
    +                if (((this.blocked.up || this.touching.up) && (gy < 0 || this.velocity.y < 0)) || ((this.blocked.down || this.touching.down) && (gy > 0 || this.velocity.y > 0)))
    +                {
    +                    this.velocity.y = 0;
    +                }
    +            }
    +        }
    +
    +    },
    +
    +    /**
    +    * Gets the total force being applied on the X axis, including gravity and velocity.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#getUpwardForce
    +    * @return {number} The total force being applied on the X axis.
    +    */
    +    getUpwardForce: function () {
    +
    +        if (this.allowGravity)
    +        {
    +            return this.gravity.x + this.game.physics.gravity.x + this.velocity.x;
    +        }
    +        else
    +        {
    +            return this.gravity.x + this.velocity.x;
    +        }
    +
    +    },
    +
    +    /**
    +    * Gets the total force being applied on the X axis, including gravity and velocity.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#getDownwardForce
    +    * @return {number} The total force being applied on the Y axis.
    +    */
    +    getDownwardForce: function () {
    +
    +        if (this.allowGravity)
    +        {
    +            return this.gravity.y + this.game.physics.gravity.y + this.velocity.y;
    +        }
    +        else
    +        {
    +            return this.gravity.y + this.velocity.y;
    +        }
    +
    +    },
    +
    +    /**
    +    * Subtracts the given Vector from this Body.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#sub
    +    * @protected
    +    * @param {SAT.Vector} v - The vector to substract from this Body.
    +    */
    +    sub: function (v) {
    +
    +        this.x -= v.x;
    +        this.y -= v.y;
    +
    +    },
    +
    +    /**
    +    * Adds the given Vector to this Body.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#add
    +    * @protected
    +    * @param {SAT.Vector} v - The vector to add to this Body.
    +    */
    +    add: function (v) {
    +
    +        this.x += v.x;
    +        this.y += v.y;
    +
    +    },
    +
    +    /**
    +    * Separation response handler.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#give
    +    * @protected
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
    +    * @param {SAT.Response} response - The SAT Response object containing the collision data.
    +    */
    +    give: function (body, response) {
    +
    +        this.add(response.overlapV);
    +
    +        if (this.rebound)
    +        {
    +            this.processRebound(body);
    +            this.reboundCheck(true, true, false);
    +            body.reboundCheck(true, true, false);
    +        }
    +
    +    },
    +
    +    /**
    +    * Separation response handler.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#take
    +    * @protected
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
    +    * @param {SAT.Response} response - The SAT Response object containing the collision data.
    +    */
    +    take: function (body, response) {
    +
    +        this.sub(response.overlapV);
    +
    +        if (this.rebound)
    +        {
    +            this.processRebound(body);
    +            this.reboundCheck(true, true, false);
    +            body.reboundCheck(true, true, false);
    +        }
    +
    +    },
    +
    +    /**
    +    * Split the collision response evenly between the two bodies.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#split
    +    * @protected
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
    +    * @param {SAT.Response} response - The SAT Response object containing the collision data.
    +    */
    +    split: function (body, response) {
    +    
    +        response.overlapV.scale(0.5);
    +        this.sub(response.overlapV);
    +        body.add(response.overlapV);
    +
    +        if (this.rebound)
    +        {
    +            this.exchange(body);
    +            this.reboundCheck(true, true, false);
    +            body.reboundCheck(true, true, false);
    +        }
    +
    +    },
    +
    +    /**
    +    * Exchange velocity with the given Body.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#exchange
    +    * @protected
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
    +    */
    +    exchange: function (body) {
    +
    +        if (this.mass === body.mass && this.speed > 0 && body.speed > 0)
    +        {
    +            //  A direct velocity exchange (as they are both moving and have the same mass)
    +            this._dx = body.velocity.x;
    +            this._dy = body.velocity.y;
    +
    +            body.velocity.x = this.velocity.x * body.bounce.x;
    +            body.velocity.y = this.velocity.y * body.bounce.x;
    +
    +            this.velocity.x = this._dx * this.bounce.x;
    +            this.velocity.y = this._dy * this.bounce.y;
    +        }
    +        else
    +        {
    +            var nv1 = Math.sqrt((body.velocity.x * body.velocity.x * body.mass) / this.mass) * ((body.velocity.x > 0) ? 1 : -1);
    +            var nv2 = Math.sqrt((this.velocity.x * this.velocity.x * this.mass) / body.mass) * ((this.velocity.x > 0) ? 1 : -1);
    +            var average = (nv1 + nv2) * 0.5;
    +            nv1 -= average;
    +            nv2 -= average;
    +
    +            this.velocity.x = nv1;
    +            body.velocity.x = nv2;
    +
    +            nv1 = Math.sqrt((body.velocity.y * body.velocity.y * body.mass) / this.mass) * ((body.velocity.y > 0) ? 1 : -1);
    +            nv2 = Math.sqrt((this.velocity.y * this.velocity.y * this.mass) / body.mass) * ((this.velocity.y > 0) ? 1 : -1);
    +            average = (nv1 + nv2) * 0.5;
    +            nv1 -= average;
    +            nv2 -= average;
    +
    +            this.velocity.y = nv1;
    +            body.velocity.y = nv2;
    +        }
    +
    +        //  update speed / angle?
    +
    +    },
    +
    +    /**
    +    * Rebound the velocity of this Body.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#processRebound
    +    * @protected
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
    +    */
    +    processRebound: function (body) {
    +
    +        //  Don't rebound again if they've already rebounded in this frame
    +        if (!(this._vx <= 0 && this.velocity.x > 0) && !(this._vx >= 0 && this.velocity.x < 0))
    +        {
    +            this.velocity.x = body.velocity.x - this.velocity.x * this.bounce.x;
    +        }
    +
    +        if (!(this._vy <= 0 && this.velocity.y > 0) && !(this._vy >= 0 && this.velocity.y < 0))
    +        {
    +            this.velocity.y = body.velocity.y - this.velocity.y * this.bounce.y;
    +        }
    +
    +        this.angle = Math.atan2(this.velocity.y, this.velocity.x);
    +
    +        this.reboundCheck(true, true, false);
    +
    +    },
    +
    +    /**
    +    * Checks for an overlap between this Body and the given Body.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#overlap
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body that is being checked against this Body.
    +    * @param {SAT.Response} response - SAT Response handler.
    +    * @return {boolean} True if the two bodies overlap, otherwise false.
    +    */
    +    overlap: function (body, response) {
    +
    +        var result = false;
    +
    +        if ((this.type === Phaser.Physics.Arcade.RECT || this.type === Phaser.Physics.Arcade.POLYGON) && (body.type === Phaser.Physics.Arcade.RECT || body.type === Phaser.Physics.Arcade.POLYGON))
    +        {
    +            result = SAT.testPolygonPolygon(this.polygon, body.polygon, response);
    +        }
    +        else if (this.type === Phaser.Physics.Arcade.CIRCLE && body.type === Phaser.Physics.Arcade.CIRCLE)
    +        {
    +            result = SAT.testCircleCircle(this.shape, body.shape, response);
    +        }
    +        else if ((this.type === Phaser.Physics.Arcade.RECT || this.type === Phaser.Physics.Arcade.POLYGON) && body.type === Phaser.Physics.Arcade.CIRCLE)
    +        {
    +            result = SAT.testPolygonCircle(this.polygon, body.shape, response);
    +        }
    +        else if (this.type === Phaser.Physics.Arcade.CIRCLE && (body.type === Phaser.Physics.Arcade.RECT || body.type === Phaser.Physics.Arcade.POLYGON))
    +        {
    +            result = SAT.testCirclePolygon(this.shape, body.polygon, response);
    +        }
    +
    +        if (!result)
    +        {
    +            this.removeContact(body);
    +        }
    +
    +        return result;
    +
    +    },
    +
    +    /**
    +    * Checks if this Body is already in contact with the given Body.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#inContact
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body to be checked.
    +    * @return {boolean} True if the given Body is already in contact with this Body.
    +    */
    +    inContact: function (body) {
    +
    +        return (this.contacts.indexOf(body) != -1);
    +
    +    },
    +
    +    /**
    +    * Adds the given Body to the contact list of this Body. Also adds this Body to the contact list of the given Body.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#addContact
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body to be added.
    +    * @return {boolean} True if the given Body was added to this contact list, false if already on it.
    +    */
    +    addContact: function (body) {
    +
    +        if (this.inContact(body))
    +        {
    +            return false;
    +        }
    +
    +        this.contacts.push(body);
    +
    +        this.sprite.events.onBeginContact.dispatch(this.sprite, body.sprite, this, body);
    +
    +        body.addContact(this);
    +
    +        return true;
    +
    +    },
    +
    +    /**
    +    * Removes the given Body from the contact list of this Body. Also removes this Body from the contact list of the given Body.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#removeContact
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body to be removed.
    +    * @return {boolean} True if the given Body was removed from this contact list, false if wasn't on it.
    +    */
    +    removeContact: function (body) {
    +
    +        if (!this.inContact(body))
    +        {
    +            return false;
    +        }
    +
    +        this.contacts.splice(this.contacts.indexOf(body), 1);
    +
    +        this.sprite.events.onEndContact.dispatch(this.sprite, body.sprite, this, body);
    +
    +        body.removeContact(this);
    +
    +        return true;
    +
    +    },
    +
    +    /**
    +    * This separates this Body from the given Body unless a customSeparateCallback is set.
    +    * It assumes they have already been overlap checked and the resulting overlap is stored in the SAT response.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#separate
    +    * @protected
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body to be separated from this one.
    +    * @param {SAT.Response} response - SAT Response handler.
    +    * @return {boolean} True if the bodies were separated, false if not (for example checkCollide allows them to pass through)
    +    */
    +    separate: function (body, response) {
    +
    +        if (this.inContact(body))
    +        {
    +            return false;
    +        }
    +
    +        this._distances[0] = body.right - this.x;   // Distance of B to face on left side of A
    +        this._distances[1] = this.right - body.x;   // Distance of B to face on right side of A
    +        this._distances[2] = body.bottom - this.y;  // Distance of B to face on bottom side of A
    +        this._distances[3] = this.bottom - body.y;  // Distance of B to face on top side of A
    +
    +        //  If we've zero distance then check for side-slicing
    +        if (response.overlapN.x && (this._distances[0] === 0 || this._distances[1] === 0))
    +        {
    +            response.overlapN.x = false;
    +            response.overlapN.y = true;
    +        }
    +        else if (response.overlapN.y && (this._distances[2] === 0 || this._distances[3] === 0))
    +        {
    +            response.overlapN.x = true;
    +            response.overlapN.y = false;
    +        }
    +
    +        if (this.customSeparateCallback)
    +        {
    +            return this.customSeparateCallback.call(this.customSeparateContext, this, response, this._distances);
    +        }
    +
    +        var hasSeparated = false;
    +
    +        if (response.overlapN.x)
    +        {
    +            //  Which is smaller? Left or Right?
    +            if (this._distances[0] < this._distances[1] && (body.checkCollision.right || this.checkCollision.left))
    +            {
    +                hasSeparated = this.hitLeft(body, response);
    +            }
    +            else if (this._distances[1] < this._distances[0] && (body.checkCollision.left || this.checkCollision.right))
    +            {
    +                hasSeparated = this.hitRight(body, response);
    +            }
    +        }
    +        else if (response.overlapN.y)
    +        {
    +            //  Which is smaller? Top or Bottom?
    +            if (this._distances[2] < this._distances[3] && (body.checkCollision.down || this.checkCollision.up))
    +            {
    +                hasSeparated = this.hitTop(body, response);
    +            }
    +            else if (this._distances[3] < this._distances[2] && (body.checkCollision.up || this.checkCollision.down))
    +            {
    +                hasSeparated = this.hitBottom(body, response);
    +            }
    +        }
    +
    +        if (hasSeparated)
    +        {
    +            this.game.physics.checkBounds(this);
    +            this.game.physics.checkBounds(body);
    +        }
    +        else
    +        {
    +            //  They can only contact like this if at least one of their sides is open, otherwise it's a separation
    +            if (!this.checkCollision.up || !this.checkCollision.down || !this.checkCollision.left || !this.checkCollision.right || !body.checkCollision.up || !body.checkCollision.down || !body.checkCollision.left || !body.checkCollision.right)
    +            {
    +                this.addContact(body);
    +            }
    +        }
    +
    +        return hasSeparated;
    +
    +    },
    +
    +    /**
    +    * Process a collision with the left face of this Body.
    +    * Collision and separation can be further checked by setting a collideCallback.
    +    * This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response.
    +    * If the callback returns true then separation, rebounds and the touching flags will all be set.
    +    * If it returns false this will be skipped and must be handled manually.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#hitLeft
    +    * @protected
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
    +    * @param {SAT.Response} response - The SAT Response object containing the collision data.
    +    */
    +    hitLeft: function (body, response) {
    +
    +        if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.LEFT, this, body, response))
    +        {
    +            return;
    +        }
    +
    +        if (!this.moves || this.immovable || this.blocked.right || this.touching.right)
    +        {
    +            body.give(this, response);
    +        }
    +        else
    +        {
    +            if (body.immovable || body.blocked.left || body.touching.left)
    +            {
    +                //  We take the full separation
    +                this.take(body, response);
    +            }
    +            else
    +            {
    +                //  Share out the separation
    +                this.split(body, response);
    +            }
    +        }
    +
    +        this.touching.left = true;
    +        body.touching.right = true;
    +
    +    },
    +
    +    /**
    +    * Process a collision with the right face of this Body.
    +    * Collision and separation can be further checked by setting a collideCallback.
    +    * This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response.
    +    * If the callback returns true then separation, rebounds and the touching flags will all be set.
    +    * If it returns false this will be skipped and must be handled manually.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#hitRight
    +    * @protected
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
    +    * @param {SAT.Response} response - The SAT Response object containing the collision data.
    +    */
    +    hitRight: function (body, response) {
    +
    +        if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.RIGHT, this, body))
    +        {
    +            return;
    +        }
    +
    +        if (!this.moves || this.immovable || this.blocked.left || this.touching.left)
    +        {
    +            body.give(this, response);
    +        }
    +        else
    +        {
    +            if (body.immovable || body.blocked.right || body.touching.right)
    +            {
    +                //  We take the full separation
    +                this.take(body, response);
    +            }
    +            else
    +            {
    +                //  Share out the separation
    +                this.split(body, response);
    +            }
    +        }
    +
    +        this.touching.right = true;
    +        body.touching.left = true;
    +
    +    },
    +
    +    /**
    +    * Process a collision with the top face of this Body.
    +    * Collision and separation can be further checked by setting a collideCallback.
    +    * This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response.
    +    * If the callback returns true then separation, rebounds and the touching flags will all be set.
    +    * If it returns false this will be skipped and must be handled manually.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#hitTop
    +    * @protected
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
    +    * @param {SAT.Response} response - The SAT Response object containing the collision data.
    +    */
    +    hitTop: function (body, response) {
    +
    +        if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.UP, this, body))
    +        {
    +            return false;
    +        }
    +
    +        if (!this.moves || this.immovable || this.blocked.down || this.touching.down)
    +        {
    +            body.give(this, response);
    +        }
    +        else
    +        {
    +            if (body.immovable || body.blocked.up || body.touching.up)
    +            {
    +                //  We take the full separation
    +                this.take(body, response);
    +            }
    +            else
    +            {
    +                //  Share out the separation
    +                this.split(body, response);
    +            }
    +        }
    +
    +        this.touching.up = true;
    +        body.touching.down = true;
    +
    +        return true;
    +
    +    },
    +
    +    /**
    +    * Process a collision with the bottom face of this Body.
    +    * Collision and separation can be further checked by setting a collideCallback.
    +    * This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response.
    +    * If the callback returns true then separation, rebounds and the touching flags will all be set.
    +    * If it returns false this will be skipped and must be handled manually.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#hitBottom
    +    * @protected
    +    * @param {Phaser.Physics.Arcade.Body} body - The Body that collided.
    +    * @param {SAT.Response} response - The SAT Response object containing the collision data.
    +    */
    +    hitBottom: function (body, response) {
    +
    +        if (this.collideCallback && !this.collideCallback.call(this.collideCallbackContext, Phaser.DOWN, this, body))
    +        {
    +            return false;
    +        }
    +
    +        if (!this.moves || this.immovable || this.blocked.up || this.touching.up)
    +        {
    +            body.give(this, response);
    +        }
    +        else
    +        {
    +            if (body.immovable || body.blocked.down || body.touching.down)
    +            {
    +                //  We take the full separation
    +                this.take(body, response);
    +            }
    +            else
    +            {
    +                //  Share out the separation
    +                this.split(body, response);
    +            }
    +        }
    +
    +        this.touching.down = true;
    +        body.touching.up = true;
    +
    +        return true;
    +
    +    },
    +
    +    /**
    +    * Internal method. Integrates velocity, global gravity and the delta timer.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#integrateVelocity
    +    * @protected
    +    */
    +    integrateVelocity: function () {
    +
    +        this._temp = this.game.physics.updateMotion(this);
    +        this._dx = this.game.time.physicsElapsed * (this.velocity.x + this._temp.x / 2);
    +        this._dy = this.game.time.physicsElapsed * (this.velocity.y + this._temp.y / 2);
    +
    +        //  positive = RIGHT / DOWN
    +        //  negative = LEFT / UP
    +
    +        if ((this._dx < 0 && !this.blocked.left && !this.touching.left) || (this._dx > 0 && !this.blocked.right && !this.touching.right))
    +        {
    +            this.x += this._dx;
    +            this.velocity.x += this._temp.x;
    +        }
    +
    +        if ((this._dy < 0 && !this.blocked.up && !this.touching.up) || (this._dy > 0 && !this.blocked.down && !this.touching.down))
    +        {
    +            this.y += this._dy;
    +            this.velocity.y += this._temp.y;
    +        }
    +
    +        if (this.velocity.x > this.maxVelocity.x)
    +        {
    +            this.velocity.x = this.maxVelocity.x;
    +        }
    +        else if (this.velocity.x < -this.maxVelocity.x)
    +        {
    +            this.velocity.x = -this.maxVelocity.x;
    +        }
    +
    +        if (this.velocity.y > this.maxVelocity.y)
    +        {
    +            this.velocity.y = this.maxVelocity.y;
    +        }
    +        else if (this.velocity.y < -this.maxVelocity.y)
    +        {
    +            this.velocity.y = -this.maxVelocity.y;
    +        }
    +
    +    },
    +
    +    /**
    +    * Internal method. This is called directly before the sprites are sent to the renderer and after the update function has finished.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#postUpdate
         * @protected
         */
         postUpdate: function () {
     
    -        if (this.deltaX() < 0)
    +        if (this.moves)
             {
    -            this.facing = Phaser.LEFT;
    -        }
    -        else if (this.deltaX() > 0)
    -        {
    -            this.facing = Phaser.RIGHT;
    -        }
    +            this.reboundCheck(true, true, true);
     
    -        if (this.deltaY() < 0)
    -        {
    -            this.facing = Phaser.UP;
    -        }
    -        else if (this.deltaY() > 0)
    -        {
    -            this.facing = Phaser.DOWN;
    -        }
    +            this.game.physics.checkBounds(this);
     
    -        if (this.deltaX() !== 0 || this.deltaY() !== 0)
    -        {
    -            this.sprite.x += this.deltaX();
    -            this.sprite.y += this.deltaY();
    -            this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
    -        }
    +            this._dx = this.deltaX();
    +            this._dy = this.deltaY();
    +
    +            if (this._dx < 0)
    +            {
    +                this.facing = Phaser.LEFT;
    +            }
    +            else if (this._dx > 0)
    +            {
    +                this.facing = Phaser.RIGHT;
    +            }
    +
    +            if (this._dy < 0)
    +            {
    +                this.facing = Phaser.UP;
    +            }
    +            else if (this._dy > 0)
    +            {
    +                this.facing = Phaser.DOWN;
    +            }
    +
    +            if (this._dx !== 0 || this._dy !== 0)
    +            {
    +                this.sprite.x += this._dx;
    +                this.sprite.y += this._dy;
    +            }
    +
    +            if (this.allowRotation && this.deltaZ() !== 0)
    +            {
    +                this.sprite.angle += this.deltaZ();
    +            }
    +
    +            if (this.sprite.scale.x !== this._sx || this.sprite.scale.y !== this._sy)
    +            {
    +                this.updateScale();
    +            }
     
    -        if (this.allowRotation)
    -        {
    -            this.sprite.angle += this.deltaZ();
             }
     
         },
     
         /**
    -    * Internal method.
    +    * Resets the Body motion values: velocity, acceleration, angularVelocity and angularAcceleration.
    +    * Also resets the forces to defaults: gravity, bounce, minVelocity,maxVelocity, angularDrag, maxAngular, mass, friction and checkCollision if 'full' specified.
         *
    -    * @method Phaser.Physics.Arcade#updateHulls
    -    * @protected
    +    * @method Phaser.Physics.Arcade.Body#reset
    +    * @param {boolean} [full=false] - A full reset clears down settings you may have set, such as gravity, bounce and drag. A non-full reset just clears motion values.
         */
    -    updateHulls: function () {
    +    reset: function (full) {
     
    -        this.hullX.setTo(this.x, this.preY, this.width, this.height);
    -        this.hullY.setTo(this.preX, this.y, this.width, this.height);
    +        if (typeof full === 'undefined') { full = false; }
     
    -    },
    -
    -    /**
    -    * Internal method.
    -    *
    -    * @method Phaser.Physics.Arcade#checkWorldBounds
    -    * @protected
    -    */
    -    checkWorldBounds: function () {
    -
    -        if (this.x < this.game.world.bounds.x)
    +        if (full)
             {
    -            this.x = this.game.world.bounds.x;
    -            this.velocity.x *= -this.bounce.x;
    +            this.gravity.setTo(0, 0);
    +            this.bounce.setTo(0, 0);
    +            this.minVelocity.setTo(5, 5);
    +            this.maxVelocity.setTo(1000, 1000);
    +            this.angularDrag = 0;
    +            this.maxAngular = 1000;
    +            this.mass = 1;
    +            this.friction = 0.0;
    +            this.checkCollision = { none: false, any: true, up: true, down: true, left: true, right: true };
             }
    -        else if (this.right > this.game.world.bounds.right)
    -        {
    -            this.x = this.game.world.bounds.right - this.width;
    -            this.velocity.x *= -this.bounce.x;
    -        }
    -
    -        if (this.y < this.game.world.bounds.y)
    -        {
    -            this.y = this.game.world.bounds.y;
    -            this.velocity.y *= -this.bounce.y;
    -        }
    -        else if (this.bottom > this.game.world.bounds.bottom)
    -        {
    -            this.y = this.game.world.bounds.bottom - this.height;
    -            this.velocity.y *= -this.bounce.y;
    -        }
    -
    -    },
    -
    -    /**
    -    * You can modify the size of the physics Body to be any dimension you need.
    -    * So it could be smaller or larger than the parent Sprite. You can also control the x and y offset, which
    -    * is the position of the Body relative to the top-left of the Sprite.
    -    *
    -    * @method Phaser.Physics.Arcade#setSize
    -    * @param {number} width - The width of the Body.
    -    * @param {number} height - The height of the Body.
    -    * @param {number} offsetX - The X offset of the Body from the Sprite position.
    -    * @param {number} offsetY - The Y offset of the Body from the Sprite position.
    -    */
    -    setSize: function (width, height, offsetX, offsetY) {
    -
    -        offsetX = offsetX || this.offset.x;
    -        offsetY = offsetY || this.offset.y;
    -
    -        this.sourceWidth = width;
    -        this.sourceHeight = height;
    -        this.width = this.sourceWidth * this._sx;
    -        this.height = this.sourceHeight * this._sy;
    -        this.halfWidth = Math.floor(this.width / 2);
    -        this.halfHeight = Math.floor(this.height / 2);
    -        this.offset.setTo(offsetX, offsetY);
    -
    -        this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
    -
    -    },
    -
    -    /**
    -    * Resets all Body values (velocity, acceleration, rotation, etc)
    -    *
    -    * @method Phaser.Physics.Arcade#reset
    -    */
    -    reset: function () {
     
             this.velocity.setTo(0, 0);
             this.acceleration.setTo(0, 0);
    -
             this.angularVelocity = 0;
             this.angularAcceleration = 0;
    -        this.preX = (this.sprite.world.x - (this.sprite.anchor.x * this.width)) + this.offset.x;
    -        this.preY = (this.sprite.world.y - (this.sprite.anchor.y * this.height)) + this.offset.y;
    -        this.preRotation = this.sprite.angle;
    +        this.blocked = { x: 0, y: 0, up: false, down: false, left: false, right: false };
    +        this.x = (this.sprite.world.x - (this.sprite.anchor.x * this.sprite.width)) + this.offset.x;
    +        this.y = (this.sprite.world.y - (this.sprite.anchor.y * this.sprite.height)) + this.offset.y;
    +        this.preX = this.x;
    +        this.preY = this.y;
    +        this.updateBounds();
     
    -        this.x = this.preX;
    -        this.y = this.preY;
    -        this.rotation = this.preRotation;
    -        
    -        this.center.setTo(this.x + this.halfWidth, this.y + this.halfHeight);
    +        this.contacts.length = 0;
     
         },
     
         /**
    -    * Returns the absolute delta x value.
    +    * Destroys this Body and all references it holds to other objects.
         *
    -    * @method Phaser.Physics.Arcade.Body#deltaAbsX
    -    * @return {number} The absolute delta value.
    +    * @method Phaser.Physics.Arcade.Body#destroy
         */
    -    deltaAbsX: function () {
    -        return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX());
    +    destroy: function () {
    +
    +        this.sprite = null;
    +
    +        this.collideCallback = null;
    +        this.collideCallbackContext = null;
    +
    +        this.customSeparateCallback = null;
    +        this.customSeparateContext = null;
    +
    +        this.contacts.length = 0;
    +
         },
     
         /**
    -    * Returns the absolute delta y value.
    +    * Sets this Body to use a circle of the given radius for all collision.
    +    * The Circle will be centered on the center of the Sprite by default, but can be adjusted via the Body.offset property and the setCircle x/y parameters.
         *
    -    * @method Phaser.Physics.Arcade.Body#deltaAbsY
    -    * @return {number} The absolute delta value.
    +    * @method Phaser.Physics.Arcade.Body#setCircle
    +    * @param {number} radius - The radius of this circle (in pixels)
    +    * @param {number} [offsetX=0] - The x amount the circle will be offset from the Sprites center.
    +    * @param {number} [offsetY=0] - The y amount the circle will be offset from the Sprites center.
         */
    -    deltaAbsY: function () {
    -        return (this.deltaY() > 0 ? this.deltaY() : -this.deltaY());
    +    setCircle: function (radius, offsetX, offsetY) {
    +
    +        if (typeof offsetX === 'undefined') { offsetX = this.sprite._cache.halfWidth; }
    +        if (typeof offsetY === 'undefined') { offsetY = this.sprite._cache.halfHeight; }
    +
    +        this.type = Phaser.Physics.Arcade.CIRCLE;
    +        this.shape = new SAT.Circle(new SAT.Vector(this.sprite.x, this.sprite.y), radius);
    +        this.polygon = null;
    +
    +        this.offset.setTo(offsetX, offsetY);
    +
         },
     
         /**
    -    * Returns the delta x value. The difference between Body.x now and in the previous step.
    +    * Sets this Body to use a rectangle for all collision.
    +    * If you don't specify any parameters it will be sized to match the parent Sprites current width and height (including scale factor) and centered on the sprite.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#setRectangle
    +    * @param {number} [width] - The width of the rectangle. If not specified it will default to the width of the parent Sprite.
    +    * @param {number} [height] - The height of the rectangle. If not specified it will default to the height of the parent Sprite.
    +    * @param {number} [translateX] - The x amount the rectangle will be translated from the Sprites center.
    +    * @param {number} [translateY] - The y amount the rectangle will be translated from the Sprites center.
    +    */
    +    setRectangle: function (width, height, translateX, translateY) {
    +
    +        if (typeof width === 'undefined') { width = this.sprite.width; }
    +        if (typeof height === 'undefined') { height = this.sprite.height; }
    +        if (typeof translateX === 'undefined') { translateX = -this.sprite._cache.halfWidth; }
    +        if (typeof translateY === 'undefined') { translateY = -this.sprite._cache.halfHeight; }
    +
    +        this.type = Phaser.Physics.Arcade.RECT;
    +        this.shape = new SAT.Box(new SAT.Vector(this.sprite.world.x, this.sprite.world.y), width, height);
    +        this.polygon = this.shape.toPolygon();
    +        this.polygon.translate(translateX, translateY);
    +
    +        this.offset.setTo(0, 0);
    +
    +    },
    +
    +    /**
    +    * Sets this Body to use a convex polygon for collision.
    +    * The points are specified in a counter-clockwise direction and must create a convex polygon.
    +    * Use Body.translate and/or Body.offset to re-position the polygon from the Sprite origin.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#setPolygon
    +    * @param {(SAT.Vector[]|number[]|...SAT.Vector|...number)} points - This can be an array of Vectors that form the polygon,
    +    *      a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
    +    *      all the points of the polygon e.g. `setPolygon(new SAT.Vector(), new SAT.Vector(), ...)`, or the
    +    *      arguments passed can be flat x,y values e.g. `setPolygon(x,y, x,y, x,y, ...)` where `x` and `y` are Numbers.
    +    */
    +    setPolygon: function (points) {
    +
    +        this.type = Phaser.Physics.Arcade.POLYGON;
    +        this.shape = null;
    +
    +        if (!Array.isArray(points))
    +        {
    +            points = Array.prototype.slice.call(arguments);
    +        }
    +
    +        if (typeof points[0] === 'number')
    +        {
    +            var p = [];
    +
    +            for (var i = 0, len = points.length; i < len; i += 2)
    +            {
    +                p.push(new SAT.Vector(points[i], points[i + 1]));
    +            }
    +
    +            points = p;
    +        }
    +
    +        this.polygon = new SAT.Polygon(new SAT.Vector(this.sprite.center.x, this.sprite.center.y), points);
    +
    +        this.offset.setTo(0, 0);
    +
    +    },
    +
    +    /**
    +    * Used for translating rectangle and polygon bodies from the Sprite parent. Doesn't apply to Circles.
    +    * See also the Body.offset property.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#translate
    +    * @param {number} x - The x amount the polygon or rectangle will be translated by from the Sprite.
    +    * @param {number} y - The y amount the polygon or rectangle will be translated by from the Sprite.
    +    */
    +    translate: function (x, y) {
    +
    +        if (this.polygon)
    +        {
    +            this.polygon.translate(x, y);
    +        }
    +
    +    },
    +
    +    /**
    +    * Determines if this Body is 'on the floor', which means in contact with a Tile or World bounds, or other object that has set 'down' as blocked.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#onFloor
    +    * @return {boolean} True if this Body is 'on the floor', which means in contact with a Tile or World bounds, or object that has set 'down' as blocked.
    +    */
    +    onFloor: function () {
    +        return this.blocked.down;
    +    },
    +
    +    /**
    +    * Determins if this Body is 'on a wall', which means horizontally in contact with a Tile or World bounds, or other object but not the ground.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#onWall
    +    * @return {boolean} True if this Body is 'on a wall', which means horizontally in contact with a Tile or World bounds, or other object but not the ground.
    +    */
    +    onWall: function () {
    +        return (!this.blocked.down && (this.blocked.left || this.blocked.right));
    +    },
    +
    +    /**
    +    * Returns the delta x value. The amount the Body has moved horizontally in the current step.
         *
         * @method Phaser.Physics.Arcade.Body#deltaX
    -    * @return {number} The delta value.
    +    * @return {number} The delta value. Positive if the motion was to the right, negative if to the left.
         */
         deltaX: function () {
             return this.x - this.preX;
         },
     
         /**
    -    * Returns the delta y value. The difference between Body.y now and in the previous step.
    +    * Returns the delta y value. The amount the Body has moved vertically in the current step.
         *
         * @method Phaser.Physics.Arcade.Body#deltaY
    -    * @return {number} The delta value.
    +    * @return {number} The delta value. Positive if the motion was downwards, negative if upwards.
         */
         deltaY: function () {
             return this.y - this.preY;
         },
     
    +    /**
    +    * Returns the delta z value. The amount the Body has rotated in the current step.
    +    *
    +    * @method Phaser.Physics.Arcade.Body#deltaZ
    +    * @return {number} The delta value.
    +    */
         deltaZ: function () {
             return this.rotation - this.preRotation;
         }
     
     };
     
    +Phaser.Physics.Arcade.Body.prototype.constructor = Phaser.Physics.Arcade.Body;
    +
     /**
    -* @name Phaser.Physics.Arcade.Body#bottom
    -* @property {number} bottom - The bottom value of this Body (same as Body.y + Body.height)
    +* @name Phaser.Physics.Arcade.Body#x
    +* @property {number} x - The x coordinate of this Body.
     */
    -Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "bottom", {
    +Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "x", {
         
    -    /**
    -    * The sum of the y and height properties. Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.
    -    * @method bottom
    -    * @return {number}
    -    */
         get: function () {
    -        return this.y + this.height;
    -    },
    -
    -    /**
    -    * The sum of the y and height properties. Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.
    -    * @method bottom
    -    * @param {number} value
    -    */
    -    set: function (value) {
    -
    -        if (value <= this.y)
    +        
    +        if (this.type === Phaser.Physics.Arcade.CIRCLE)
             {
    -            this.height = 0;
    +            return this.shape.pos.x;
             }
             else
             {
    -            this.height = (this.y - value);
    +            return this.polygon.pos.x;
             }
    -        
    +
    +    },
    +
    +    set: function (value) {
    +
    +        if (this.type === Phaser.Physics.Arcade.CIRCLE)
    +        {
    +            this.shape.pos.x = value;
    +        }
    +        else
    +        {
    +            this.polygon.pos.x = value;
    +        }
    +
         }
     
     });
     
     /**
    -* @name Phaser.Physics.Arcade.Body#right
    -* @property {number} right - The right value of this Body (same as Body.x + Body.width)
    +* @name Phaser.Physics.Arcade.Body#y
    +* @property {number} y - The y coordinate of this Body.
     */
    -Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "right", {
    +Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "y", {
         
    -    /**
    -    * The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties.
    -    * However it does affect the width property.
    -    * @method right
    -    * @return {number}
    -    */
         get: function () {
    -        return this.x + this.width;
    -    },
    -
    -    /**
    -    * The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties.
    -    * However it does affect the width property.
    -    * @method right
    -    * @param {number} value
    -    */
    -    set: function (value) {
    -
    -        if (value <= this.x)
    +        
    +        if (this.type === Phaser.Physics.Arcade.CIRCLE)
             {
    -            this.width = 0;
    +            return this.shape.pos.y;
             }
             else
             {
    -            this.width = this.x + value;
    +            return this.polygon.pos.y;
    +        }
    +
    +    },
    +
    +    set: function (value) {
    +
    +        if (this.type === Phaser.Physics.Arcade.CIRCLE)
    +        {
    +            this.shape.pos.y = value;
    +        }
    +        else
    +        {
    +            this.polygon.pos.y = value;
             }
     
         }
    @@ -1081,13 +1948,13 @@ Object.defineProperty(Phaser.Physics.Arcade.Body.prototype, "right", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Button.js.html b/docs/Button.js.html index fcdbc0b0..50feb1cd 100644 --- a/docs/Button.js.html +++ b/docs/Button.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -442,16 +436,17 @@
     * @constructor
     *
     * @param {Phaser.Game} game Current game instance.
    -* @param {number} [x] - X position of the Button.
    -* @param {number} [y] - Y position of the Button.
    +* @param {number} [x=0] - X position of the Button.
    +* @param {number} [y=0] - Y position of the Button.
     * @param {string} [key] - The image key as defined in the Game.Cache to use as the texture for this Button.
     * @param {function} [callback] - The function to call when this Button is pressed.
     * @param {object} [callbackContext] - The context in which the callback will be called (usually 'this').
     * @param {string|number} [overFrame] - This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name.
     * @param {string|number} [outFrame] - This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name.
     * @param {string|number} [downFrame] - This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name.
    +* @param {string|number} [upFrame] - This is the frame or frameName that will be set when this button is in an up state. Give either a number to use a frame ID or a string for a frame name.
     */
    -Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame) {
    +Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame, upFrame) {
     
         x = x || 0;
         y = y || 0;
    @@ -486,7 +481,7 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame,
         * @default
         */
         this._onDownFrameName = null;
    -    
    +
         /** 
         * @property {string} _onUpFrameName - Internal variable.
         * @private
    @@ -514,7 +509,7 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame,
         * @default
         */
         this._onDownFrameID = null;
    -    
    +
         /** 
         * @property {number} _onUpFrameID - Internal variable.
         * @private
    @@ -596,13 +591,13 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame,
         this.freezeFrames = false;
     
         /**
    -    * When the Button is clicked you can optionally force the state to "out".
    +    * When the Button is touched / clicked and then released you can force it to enter a state of "out" instead of "up".
         * @property {boolean} forceOut
         * @default
         */
    -    this.forceOut = true;
    +    this.forceOut = false;
     
    -    this.setFrames(overFrame, outFrame, downFrame);
    +    this.setFrames(overFrame, outFrame, downFrame, upFrame);
     
         if (callback !== null)
         {
    @@ -624,15 +619,38 @@ Phaser.Button.prototype = Phaser.Utils.extend(true, Phaser.Button.prototype, Pha
     Phaser.Button.prototype.constructor = Phaser.Button;
     
     /**
    -* Used to manually set the frames that will be used for the different states of the button
    -* exactly like setting them in the constructor.
    +* Clears all of the frames set on this Button.
    +*
    +* @method Phaser.Button.prototype.clearFrames
    +*/
    +Phaser.Button.prototype.clearFrames = function () {
    +
    +    this._onOverFrameName = null;
    +    this._onOverFrameID = null;
    +
    +    this._onOutFrameName = null;
    +    this._onOutFrameID = null;
    +
    +    this._onDownFrameName = null;
    +    this._onDownFrameID = null;
    +
    +    this._onUpFrameName = null;
    +    this._onUpFrameID = null;
    +
    +}
    +
    +/**
    +* Used to manually set the frames that will be used for the different states of the Button.
     *
     * @method Phaser.Button.prototype.setFrames
     * @param {string|number} [overFrame] - This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name.
     * @param {string|number} [outFrame] - This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name.
     * @param {string|number} [downFrame] - This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name.
    +* @param {string|number} [upFrame] - This is the frame or frameName that will be set when this button is in an up state. Give either a number to use a frame ID or a string for a frame name.
     */
    -Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) {
    +Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame, upFrame) {
    +
    +    this.clearFrames();
     
         if (overFrame !== null)
         {
    @@ -661,7 +679,6 @@ Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) {
             if (typeof outFrame === 'string')
             {
                 this._onOutFrameName = outFrame;
    -            this._onUpFrameName = outFrame;
     
                 if (this.input.pointerOver() === false)
                 {
    @@ -671,7 +688,6 @@ Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) {
             else
             {
                 this._onOutFrameID = outFrame;
    -            this._onUpFrameID = outFrame;
     
                 if (this.input.pointerOver() === false)
                 {
    @@ -702,6 +718,28 @@ Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) {
             }
         }
     
    +    if (upFrame !== null)
    +    {
    +        if (typeof upFrame === 'string')
    +        {
    +            this._onUpFrameName = upFrame;
    +
    +            if (this.input.pointerUp())
    +            {
    +                this.frameName = upFrame;
    +            }
    +        }
    +        else
    +        {
    +            this._onUpFrameID = upFrame;
    +
    +            if (this.input.pointerUp())
    +            {
    +                this.frame = upFrame;
    +            }
    +        }
    +    }
    +
     };
     
     /**
    @@ -723,8 +761,8 @@ Phaser.Button.prototype.setSounds = function (overSound, overMarker, downSound,
     
         this.setOverSound(overSound, overMarker);
         this.setOutSound(outSound, outMarker);
    -    this.setUpSound(upSound, upMarker);
         this.setDownSound(downSound, downMarker);
    +    this.setUpSound(upSound, upMarker);
     
     }
     
    @@ -777,31 +815,7 @@ Phaser.Button.prototype.setOutSound = function (sound, marker) {
     }
     
     /**
    -* The Sound to be played when a Pointer clicks on this Button.
    -*
    -* @method Phaser.Button.prototype.setUpSound
    -* @param {Phaser.Sound} sound - The Sound that will be played.
    -* @param {string} [marker] - A Sound Marker that will be used in the playback.
    -*/
    -Phaser.Button.prototype.setUpSound = function (sound, marker) {
    -
    -    this.onUpSound = null;
    -    this.onUpSoundMarker = '';
    -
    -    if (sound instanceof Phaser.Sound)
    -    {
    -        this.onUpSound = sound;
    -    }
    -
    -    if (typeof marker === 'string')
    -    {
    -        this.onUpSoundMarker = marker;
    -    }
    -
    -}
    -
    -/**
    -* The Sound to be played when a Pointer clicks on this Button.
    +* The Sound to be played when a Pointer presses down on this Button.
     *
     * @method Phaser.Button.prototype.setDownSound
     * @param {Phaser.Sound} sound - The Sound that will be played.
    @@ -824,25 +838,43 @@ Phaser.Button.prototype.setDownSound = function (sound, marker) {
     
     }
     
    +/**
    +* The Sound to be played when a Pointer has pressed down and is released from this Button.
    +*
    +* @method Phaser.Button.prototype.setUpSound
    +* @param {Phaser.Sound} sound - The Sound that will be played.
    +* @param {string} [marker] - A Sound Marker that will be used in the playback.
    +*/
    +Phaser.Button.prototype.setUpSound = function (sound, marker) {
    +
    +    this.onUpSound = null;
    +    this.onUpSoundMarker = '';
    +
    +    if (sound instanceof Phaser.Sound)
    +    {
    +        this.onUpSound = sound;
    +    }
    +
    +    if (typeof marker === 'string')
    +    {
    +        this.onUpSoundMarker = marker;
    +    }
    +
    +}
    +
     /**
     * Internal function that handles input events.
     *
     * @protected
     * @method Phaser.Button.prototype.onInputOverHandler
    +* @param {Phaser.Button} sprite - The Button that the event occured on.
     * @param {Phaser.Pointer} pointer - The Pointer that activated the Button.
     */
    -Phaser.Button.prototype.onInputOverHandler = function (pointer) {
    +Phaser.Button.prototype.onInputOverHandler = function (sprite, pointer) {
     
         if (this.freezeFrames === false)
         {
    -        if (this._onOverFrameName != null)
    -        {
    -            this.frameName = this._onOverFrameName;
    -        }
    -        else if (this._onOverFrameID != null)
    -        {
    -            this.frame = this._onOverFrameID;
    -        }
    +        this.setState(1);
         }
     
         if (this.onOverSound)
    @@ -861,20 +893,14 @@ Phaser.Button.prototype.onInputOverHandler = function (pointer) {
     *
     * @protected
     * @method Phaser.Button.prototype.onInputOverHandler
    +* @param {Phaser.Button} sprite - The Button that the event occured on.
     * @param {Phaser.Pointer} pointer - The Pointer that activated the Button.
     */
    -Phaser.Button.prototype.onInputOutHandler = function (pointer) {
    +Phaser.Button.prototype.onInputOutHandler = function (sprite, pointer) {
     
         if (this.freezeFrames === false)
         {
    -        if (this._onOutFrameName != null)
    -        {
    -            this.frameName = this._onOutFrameName;
    -        }
    -        else if (this._onOutFrameID != null)
    -        {
    -            this.frame = this._onOutFrameID;
    -        }
    +        this.setState(2);
         }
     
         if (this.onOutSound)
    @@ -893,20 +919,14 @@ Phaser.Button.prototype.onInputOutHandler = function (pointer) {
     *
     * @protected
     * @method Phaser.Button.prototype.onInputOverHandler
    +* @param {Phaser.Button} sprite - The Button that the event occured on.
     * @param {Phaser.Pointer} pointer - The Pointer that activated the Button.
     */
    -Phaser.Button.prototype.onInputDownHandler = function (pointer) {
    +Phaser.Button.prototype.onInputDownHandler = function (sprite, pointer) {
     
         if (this.freezeFrames === false)
         {
    -        if (this._onDownFrameName != null)
    -        {
    -            this.frameName = this._onDownFrameName;
    -        }
    -        else if (this._onDownFrameID != null)
    -        {
    -            this.frame = this._onDownFrameID;
    -        }
    +        this.setState(3);
         }
     
         if (this.onDownSound)
    @@ -925,29 +945,76 @@ Phaser.Button.prototype.onInputDownHandler = function (pointer) {
     *
     * @protected
     * @method Phaser.Button.prototype.onInputOverHandler
    +* @param {Phaser.Button} sprite - The Button that the event occured on.
     * @param {Phaser.Pointer} pointer - The Pointer that activated the Button.
     */
    -Phaser.Button.prototype.onInputUpHandler = function (pointer) {
    -
    -    if (this.freezeFrames === false)
    -    {
    -        if (this._onUpFrameName != null)
    -        {
    -            this.frameName = this._onUpFrameName;
    -        }
    -        else if (this._onUpFrameID != null)
    -        {
    -            this.frame = this._onUpFrameID;
    -        }
    -    }
    +Phaser.Button.prototype.onInputUpHandler = function (sprite, pointer, isOver) {
     
         if (this.onUpSound)
         {
             this.onUpSound.play(this.onUpSoundMarker);
         }
     
    -    if (this.forceOut && this.freezeFrames === false)
    +    if (this.onInputUp)
         {
    +        this.onInputUp.dispatch(this, pointer, isOver);
    +    }
    +
    +    if (this.freezeFrames)
    +    {
    +        return;
    +    }
    +
    +    if (this.forceOut)
    +    {
    +        //  Button should be forced to the Out frame when released.
    +        this.setState(2);
    +    }
    +    else
    +    {
    +        if (this._onUpFrameName || this._onUpFrameID)
    +        {
    +            this.setState(4);
    +        }
    +        else
    +        {
    +            if (isOver)
    +            {
    +                this.setState(1);
    +            }
    +            else
    +            {
    +                this.setState(2);
    +            }
    +        }
    +    }
    +
    +};
    +
    +/**
    +* Internal function that handles Button state changes.
    +*
    +* @protected
    +* @method Phaser.Button.prototype.setState
    +* @param {number} newState - The new State of the Button.
    +*/
    +Phaser.Button.prototype.setState = function (newState) {
    +
    +    if (newState === 1)
    +    {
    +        //  Over
    +        if (this._onOverFrameName != null)
    +        {
    +            this.frameName = this._onOverFrameName;
    +        }
    +        else if (this._onOverFrameID != null)
    +        {
    +            this.frame = this._onOverFrameID;
    +        }
    +    }
    +    else if (newState === 2)
    +    {
    +        //  Out
             if (this._onOutFrameName != null)
             {
                 this.frameName = this._onOutFrameName;
    @@ -957,10 +1024,29 @@ Phaser.Button.prototype.onInputUpHandler = function (pointer) {
                 this.frame = this._onOutFrameID;
             }
         }
    -
    -    if (this.onInputUp)
    +    else if (newState === 3)
         {
    -        this.onInputUp.dispatch(this, pointer);
    +        //  Down
    +        if (this._onDownFrameName != null)
    +        {
    +            this.frameName = this._onDownFrameName;
    +        }
    +        else if (this._onDownFrameID != null)
    +        {
    +            this.frame = this._onDownFrameID;
    +        }
    +    }
    +    else if (newState === 4)
    +    {
    +        //  Up
    +        if (this._onUpFrameName != null)
    +        {
    +            this.frameName = this._onUpFrameName;
    +        }
    +        else if (this._onUpFrameID != null)
    +        {
    +            this.frame = this._onUpFrameID;
    +        }
         }
     
     };
    @@ -979,13 +1065,13 @@ Phaser.Button.prototype.onInputUpHandler = function (pointer) {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Cache.js.html b/docs/Cache.js.html index b6f9b4f4..bc00d8b4 100644 --- a/docs/Cache.js.html +++ b/docs/Cache.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,16 +417,15 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
     /**
     * Phaser.Cache constructor.
     *
    -* @class    Phaser.Cache
    -* @classdesc A game only has one instance of a Cache and it is used to store all externally loaded assets such
    -* as images, sounds and data files as a result of Loader calls. Cache items use string based keys for look-up.
    +* @class Phaser.Cache
    +* @classdesc A game only has one instance of a Cache and it is used to store all externally loaded assets such as images, sounds and data files as a result of Loader calls. Cached items use string based keys for look-up.
     * @constructor
     * @param {Phaser.Game} game - A reference to the currently running game.
     */
    @@ -480,10 +473,10 @@ Phaser.Cache = function (game) {
         this._tilemaps = {};
     
         /**
    -    * @property {object} _tilesets - Tileset key-value container.
    +    * @property {object} _binary - Binary file key-value container.
         * @private
         */
    -    this._tilesets = {};
    +    this._binary = {};
     
         /**
         * @property {object} _bitmapDatas - BitmapData key-value container.
    @@ -516,6 +509,18 @@ Phaser.Cache.prototype = {
     
         },
     
    +    /**
    +    * Add a binary object in to the cache.
    +    * @method Phaser.Cache#addBinary
    +    * @param {string} key - Asset key for this binary data.
    +    * @param {object} binaryData - The binary object to be addded to the cache.
    +    */
    +    addBinary: function (key, binaryData) {
    +
    +        this._binary[key] = binaryData;
    +
    +    },
    +
         /**
         * Add a BitmapData object in to the cache.
         * @method Phaser.Cache#addBitmapData
    @@ -555,40 +560,18 @@ Phaser.Cache.prototype = {
         * @param {object} data - Extra sprite sheet data.
         * @param {number} frameWidth - Width of the sprite sheet.
         * @param {number} frameHeight - Height of the sprite sheet.
    -    * @param {number} frameMax - How many frames stored in the sprite sheet.
    +    * @param {number} [frameMax=-1] - How many frames stored in the sprite sheet. If -1 then it divides the whole sheet evenly.
    +    * @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here.
    +    * @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here.
         */
    -    addSpriteSheet: function (key, url, data, frameWidth, frameHeight, frameMax) {
    +    addSpriteSheet: function (key, url, data, frameWidth, frameHeight, frameMax, margin, spacing) {
     
    -        this._images[key] = { url: url, data: data, spriteSheet: true, frameWidth: frameWidth, frameHeight: frameHeight };
    +        this._images[key] = { url: url, data: data, spriteSheet: true, frameWidth: frameWidth, frameHeight: frameHeight, margin: margin, spacing: spacing };
     
             PIXI.BaseTextureCache[key] = new PIXI.BaseTexture(data);
             PIXI.TextureCache[key] = new PIXI.Texture(PIXI.BaseTextureCache[key]);
     
    -        this._images[key].frameData = Phaser.AnimationParser.spriteSheet(this.game, key, frameWidth, frameHeight, frameMax);
    -
    -    },
    -
    -    /**
    -    * Add a new tile set in to the cache.
    -    *
    -    * @method Phaser.Cache#addTileset
    -    * @param {string} key - The unique key by which you will reference this object.
    -    * @param {string} url - URL of this tile set file.
    -    * @param {object} data - Extra tile set data.
    -    * @param {number} tileWidth - Width of the sprite sheet.
    -    * @param {number} tileHeight - Height of the sprite sheet.
    -    * @param {number} tileMax - How many tiles stored in the sprite sheet.
    -    * @param {number} [tileMargin=0] - If the tiles have been drawn with a margin, specify the amount here.
    -    * @param {number} [tileSpacing=0] - If the tiles have been drawn with spacing between them, specify the amount here.
    -    */
    -    addTileset: function (key, url, data, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) {
    -
    -        this._tilesets[key] = { url: url, data: data, tileWidth: tileWidth, tileHeight: tileHeight, tileMargin: tileMargin, tileSpacing: tileSpacing };
    -
    -        PIXI.BaseTextureCache[key] = new PIXI.BaseTexture(data);
    -        PIXI.TextureCache[key] = new PIXI.Texture(PIXI.BaseTextureCache[key]);
    -
    -        this._tilesets[key].tileData = Phaser.TilemapParser.tileset(this.game, key, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing);
    +        this._images[key].frameData = Phaser.AnimationParser.spriteSheet(this.game, key, frameWidth, frameHeight, frameMax, margin, spacing);
     
         },
     
    @@ -598,15 +581,13 @@ Phaser.Cache.prototype = {
         * @method Phaser.Cache#addTilemap
         * @param {string} key - The unique key by which you will reference this object.
         * @param {string} url - URL of the tilemap image.
    -    * @param {object} mapData - The tilemap data object.
    +    * @param {object} mapData - The tilemap data object (either a CSV or JSON file).
         * @param {number} format - The format of the tilemap data.
         */
         addTilemap: function (key, url, mapData, format) {
     
             this._tilemaps[key] = { url: url, data: mapData, format: format };
     
    -        this._tilemaps[key].layers = Phaser.TilemapParser.parse(this.game, mapData, format);
    -
         },
     
         /**
    @@ -756,12 +737,13 @@ Phaser.Cache.prototype = {
                 decoded = true;
             }
     
    -        this._sounds[key] = { url: url, data: data, isDecoding: false, decoded: decoded, webAudio: webAudio, audioTag: audioTag };
    +        this._sounds[key] = { url: url, data: data, isDecoding: false, decoded: decoded, webAudio: webAudio, audioTag: audioTag, locked: this.game.sound.touchLocked };
     
         },
     
         /**
         * Reload a sound.
    +    *
         * @method Phaser.Cache#reloadSound
         * @param {string} key - Asset key for the sound.
         */
    @@ -782,7 +764,8 @@ Phaser.Cache.prototype = {
         },
     
         /**
    -    * Description.
    +    * Fires the onSoundUnlock event when the sound has completed reloading.
    +    *
         * @method Phaser.Cache#reloadSoundComplete
         * @param {string} key - Asset key for the sound.
         */
    @@ -797,7 +780,8 @@ Phaser.Cache.prototype = {
         },
     
         /**
    -    * Description.
    +    * Updates the sound object in the cache.
    +    *
         * @method Phaser.Cache#updateSound
         * @param {string} key - Asset key for the sound.
         */
    @@ -829,8 +813,8 @@ Phaser.Cache.prototype = {
         * Get a canvas object from the cache by its key.
         *
         * @method Phaser.Cache#getCanvas
    -    * @param {string} key - Asset key of the canvas you want.
    -    * @return {object} The canvas you want.
    +    * @param {string} key - Asset key of the canvas to retrieve from the Cache.
    +    * @return {object} The canvas object.
         */
         getCanvas: function (key) {
     
    @@ -838,8 +822,10 @@ Phaser.Cache.prototype = {
             {
                 return this._canvases[key].canvas;
             }
    -
    -        return null;
    +        else
    +        {
    +            console.warn('Phaser.Cache.getCanvas: Invalid key: "' + key + '"');
    +        }
     
         },
     
    @@ -847,7 +833,7 @@ Phaser.Cache.prototype = {
         * Get a BitmapData object from the cache by its key.
         *
         * @method Phaser.Cache#getBitmapData
    -    * @param {string} key - Asset key of the BitmapData object you want.
    +    * @param {string} key - Asset key of the BitmapData object to retrieve from the Cache.
         * @return {Phaser.BitmapData} The requested BitmapData object if found, or null if not.
         */
         getBitmapData: function (key) {
    @@ -856,8 +842,10 @@ Phaser.Cache.prototype = {
             {
                 return this._bitmapDatas[key];
             }
    -
    -        return null;
    +        else
    +        {
    +            console.warn('Phaser.Cache.getBitmapData: Invalid key: "' + key + '"');
    +        }
     
         },
     
    @@ -865,7 +853,7 @@ Phaser.Cache.prototype = {
         * Checks if an image key exists.
         *
         * @method Phaser.Cache#checkImageKey
    -    * @param {string} key - Asset key of the image you want.
    +    * @param {string} key - Asset key of the image to check is in the Cache.
         * @return {boolean} True if the key exists, otherwise false.
         */
         checkImageKey: function (key) {
    @@ -883,8 +871,8 @@ Phaser.Cache.prototype = {
         * Get image data by key.
         *
         * @method Phaser.Cache#getImage
    -    * @param {string} key - Asset key of the image you want.
    -    * @return {object} The image data you want.
    +    * @param {string} key - Asset key of the image to retrieve from the Cache.
    +    * @return {object} The image data.
         */
         getImage: function (key) {
     
    @@ -892,53 +880,19 @@ Phaser.Cache.prototype = {
             {
                 return this._images[key].data;
             }
    -
    -        return null;
    -
    -    },
    -
    -    /**
    -    * Get tile set image data by key.
    -    *
    -    * @method Phaser.Cache#getTileSetImage
    -    * @param {string} key - Asset key of the image you want.
    -    * @return {object} The image data you want.
    -    */
    -    getTilesetImage: function (key) {
    -
    -        if (this._tilesets[key])
    +        else
             {
    -            return this._tilesets[key].data;
    +            console.warn('Phaser.Cache.getImage: Invalid key: "' + key + '"');
             }
     
    -        return null;
    -
    -    },
    -
    -    /**
    -    * Get tile set image data by key.
    -    *
    -    * @method Phaser.Cache#getTileset
    -    * @param {string} key - Asset key of the image you want.
    -    * @return {Phaser.Tileset} The tileset data. The tileset image is in the data property, the tile data in tileData.
    -    */
    -    getTileset: function (key) {
    -
    -        if (this._tilesets[key])
    -        {
    -            return this._tilesets[key].tileData;
    -        }
    -
    -        return null;
    -
         },
     
         /**
         * Get tilemap data by key.
         *
         * @method Phaser.Cache#getTilemap
    -    * @param {string} key - Asset key of the tilemap you want.
    -    * @return {Object} The tilemap data. The tileset image is in the data property, the map data in mapData.
    +    * @param {string} key - Asset key of the tilemap data to retrieve from the Cache.
    +    * @return {Object} The raw tilemap data in CSV or JSON format.
         */
         getTilemapData: function (key) {
     
    @@ -946,16 +900,19 @@ Phaser.Cache.prototype = {
             {
                 return this._tilemaps[key];
             }
    +        else
    +        {
    +            console.warn('Phaser.Cache.getTilemapData: Invalid key: "' + key + '"');
    +        }
     
    -        return null;
         },
     
         /**
         * Get frame data by key.
         *
         * @method Phaser.Cache#getFrameData
    -    * @param {string} key - Asset key of the frame data you want.
    -    * @return {Phaser.FrameData} The frame data you want.
    +    * @param {string} key - Asset key of the frame data to retrieve from the Cache.
    +    * @return {Phaser.FrameData} The frame data.
         */
         getFrameData: function (key) {
     
    @@ -971,8 +928,8 @@ Phaser.Cache.prototype = {
         * Get a single frame out of a frameData set by key.
         *
         * @method Phaser.Cache#getFrameByIndex
    -    * @param {string} key - Asset key of the frame data you want.
    -    * @return {Phaser.Frame} The frame data you want.
    +    * @param {string} key - Asset key of the frame data to retrieve from the Cache.
    +    * @return {Phaser.Frame} The frame object.
         */
         getFrameByIndex: function (key, frame) {
     
    @@ -988,8 +945,8 @@ Phaser.Cache.prototype = {
         * Get a single frame out of a frameData set by key.
         *
         * @method Phaser.Cache#getFrameByName
    -    * @param {string} key - Asset key of the frame data you want.
    -    * @return {Phaser.Frame} The frame data you want.
    +    * @param {string} key - Asset key of the frame data to retrieve from the Cache.
    +    * @return {Phaser.Frame} The frame object.
         */
         getFrameByName: function (key, frame) {
     
    @@ -1005,8 +962,8 @@ Phaser.Cache.prototype = {
         * Get a single frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image.
         *
         * @method Phaser.Cache#getFrame
    -    * @param {string} key - Asset key of the frame data you want.
    -    * @return {Phaser.Frame} The frame data you want.
    +    * @param {string} key - Asset key of the frame data to retrieve from the Cache.
    +    * @return {Phaser.Frame} The frame data.
         */
         getFrame: function (key) {
     
    @@ -1019,11 +976,11 @@ Phaser.Cache.prototype = {
         },
     
         /**
    -    * Get a single frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image.
    +    * Get a single texture frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image.
         *
         * @method Phaser.Cache#getTextureFrame
    -    * @param {string} key - Asset key of the frame data you want.
    -    * @return {Phaser.Frame} The frame data you want.
    +    * @param {string} key - Asset key of the frame to retrieve from the Cache.
    +    * @return {Phaser.Frame} The frame data.
         */
         getTextureFrame: function (key) {
     
    @@ -1039,8 +996,8 @@ Phaser.Cache.prototype = {
         * Get a RenderTexture by key.
         *
         * @method Phaser.Cache#getTexture
    -    * @param {string} key - Asset key of the RenderTexture you want.
    -    * @return {Phaser.RenderTexture} The RenderTexture you want.
    +    * @param {string} key - Asset key of the RenderTexture to retrieve from the Cache.
    +    * @return {Phaser.RenderTexture} The RenderTexture object.
         */
         getTexture: function (key) {
     
    @@ -1048,8 +1005,10 @@ Phaser.Cache.prototype = {
             {
                 return this._textures[key];
             }
    -
    -        return null;
    +        else
    +        {
    +            console.warn('Phaser.Cache.getTexture: Invalid key: "' + key + '"');
    +        }
     
         },
     
    @@ -1057,8 +1016,8 @@ Phaser.Cache.prototype = {
         * Get sound by key.
         *
         * @method Phaser.Cache#getSound
    -    * @param {string} key - Asset key of the sound you want.
    -    * @return {Phaser.Sound} The sound you want.
    +    * @param {string} key - Asset key of the sound to retrieve from the Cache.
    +    * @return {Phaser.Sound} The sound object.
         */
         getSound: function (key) {
     
    @@ -1066,8 +1025,10 @@ Phaser.Cache.prototype = {
             {
                 return this._sounds[key];
             }
    -
    -        return null;
    +        else
    +        {
    +            console.warn('Phaser.Cache.getSound: Invalid key: "' + key + '"');
    +        }
     
         },
     
    @@ -1075,8 +1036,8 @@ Phaser.Cache.prototype = {
         * Get sound data by key.
         *
         * @method Phaser.Cache#getSoundData
    -    * @param {string} key - Asset key of the sound you want.
    -    * @return {object} The sound data you want.
    +    * @param {string} key - Asset key of the sound to retrieve from the Cache.
    +    * @return {object} The sound data.
         */
         getSoundData: function (key) {
     
    @@ -1084,8 +1045,10 @@ Phaser.Cache.prototype = {
             {
                 return this._sounds[key].data;
             }
    -
    -        return null;
    +        else
    +        {
    +            console.warn('Phaser.Cache.getSoundData: Invalid key: "' + key + '"');
    +        }
     
         },
     
    @@ -1093,7 +1056,7 @@ Phaser.Cache.prototype = {
         * Check if the given sound has finished decoding.
         *
         * @method Phaser.Cache#isSoundDecoded
    -    * @param {string} key - Asset key of the sound you want.
    +    * @param {string} key - Asset key of the sound in the Cache.
         * @return {boolean} The decoded state of the Sound object.
         */
         isSoundDecoded: function (key) {
    @@ -1109,7 +1072,7 @@ Phaser.Cache.prototype = {
         * Check if the given sound is ready for playback. A sound is considered ready when it has finished decoding and the device is no longer touch locked.
         *
         * @method Phaser.Cache#isSoundReady
    -    * @param {string} key - Asset key of the sound you want.
    +    * @param {string} key - Asset key of the sound in the Cache.
         * @return {boolean} True if the sound is decoded and the device is not touch locked.
         */
         isSoundReady: function (key) {
    @@ -1140,8 +1103,8 @@ Phaser.Cache.prototype = {
         * Get text data by key.
         *
         * @method Phaser.Cache#getText
    -    * @param {string} key - Asset key of the text data you want.
    -    * @return {object} The text data you want.
    +    * @param {string} key - Asset key of the text data to retrieve from the Cache.
    +    * @return {object} The text data.
         */
         getText: function (key) {
     
    @@ -1149,8 +1112,30 @@ Phaser.Cache.prototype = {
             {
                 return this._text[key].data;
             }
    +        else
    +        {
    +            console.warn('Phaser.Cache.getText: Invalid key: "' + key + '"');
    +        }
    +        
    +    },
     
    -        return null;
    +    /**
    +    * Get binary data by key.
    +    *
    +    * @method Phaser.Cache#getBinary
    +    * @param {string} key - Asset key of the binary data object to retrieve from the Cache.
    +    * @return {object} The binary data object.
    +    */
    +    getBinary: function (key) {
    +
    +        if (this._binary[key])
    +        {
    +            return this._binary[key];
    +        }
    +        else
    +        {
    +            console.warn('Phaser.Cache.getBinary: Invalid key: "' + key + '"');
    +        }
             
         },
     
    @@ -1168,7 +1153,7 @@ Phaser.Cache.prototype = {
     
             for (var item in array)
             {
    -            if (item !== '__default')
    +            if (item !== '__default' && item !== '__missing')
                 {
                     output.push(item);
                 }
    @@ -1277,6 +1262,8 @@ Phaser.Cache.prototype = {
         }
     
     };
    +
    +Phaser.Cache.prototype.constructor = Phaser.Cache;
     
    @@ -1292,13 +1279,13 @@ Phaser.Cache.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Camera.js.html b/docs/Camera.js.html index ee194b88..c91ddc80 100644 --- a/docs/Camera.js.html +++ b/docs/Camera.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -462,7 +456,7 @@ Phaser.Camera = function (game, id, x, y, width, height) {
         * Camera view. 
         * The view into the world we wish to render (by default the game dimensions).
         * The x/y values are in world coordinates, not screen coordinates, the width/height is how many pixels to render.
    -    * Objects outside of this view are not rendered (unless set to ignore the Camera, i.e. UI?).
    +    * Objects outside of this view are not rendered if set to camera cull.
         * @property {Phaser.Rectangle} view
         */
         this.view = new Phaser.Rectangle(x, y, width, height);
    @@ -509,6 +503,9 @@ Phaser.Camera = function (game, id, x, y, width, height) {
         */
         this._edge = 0;
     
    +    /**
    +    * @property {PIXI.DisplayObject} displayObject - The display object to which all game objects are added. Set by World.boot
    +    */
         this.displayObject = null;
         
     };
    @@ -626,6 +623,11 @@ Phaser.Camera.prototype = {
     
         },
     
    +    /**
    +    * Internal method
    +    * @method Phaser.Camera#updateTarget
    +    * @private
    +    */
         updateTarget: function () {
     
             if (this.deadzone)
    @@ -665,9 +667,13 @@ Phaser.Camera.prototype = {
     
         },
     
    +    /**
    +    * Update the Camera bounds to match the game world.
    +    * @method Phaser.Camera#setBoundsToWorld
    +    */
         setBoundsToWorld: function () {
     
    -        this.bounds.setTo(this.game.world.x, this.game.world.y, this.game.world.width, this.game.world.height);
    +        this.bounds.setTo(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height);
     
         },
     
    @@ -687,10 +693,10 @@ Phaser.Camera.prototype = {
                 this.view.x = this.bounds.x;
             }
     
    -        if (this.view.x > this.bounds.right - this.width)
    +        if (this.view.right > this.bounds.right)
             {
                 this.atLimit.x = true;
    -            this.view.x = (this.bounds.right - this.width) + 1;
    +            this.view.x = this.bounds.right - this.width;
             }
     
             if (this.view.y < this.bounds.top)
    @@ -699,10 +705,10 @@ Phaser.Camera.prototype = {
                 this.view.y = this.bounds.top;
             }
     
    -        if (this.view.y > this.bounds.bottom - this.height)
    +        if (this.view.bottom > this.bounds.bottom)
             {
                 this.atLimit.y = true;
    -            this.view.y = (this.bounds.bottom - this.height) + 1;
    +            this.view.y = this.bounds.bottom - this.height;
             }
     
             this.view.floor();
    @@ -745,6 +751,8 @@ Phaser.Camera.prototype = {
     
     };
     
    +Phaser.Camera.prototype.constructor = Phaser.Camera;
    +
     /**
     * The Cameras x coordinate. This value is automatically clamped if it falls outside of the World bounds.
     * @name Phaser.Camera#x
    @@ -839,13 +847,13 @@ Object.defineProperty(Phaser.Camera.prototype, "height", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Canvas.js.html b/docs/Canvas.js.html index a10e0bbe..a5a6e341 100644 --- a/docs/Canvas.js.html +++ b/docs/Canvas.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,12 +417,12 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
     /**
    -* The Canvas class handles everything related to the <canvas> tag as a DOM Element, like styles, offset, aspect ratio
    +* The Canvas class handles everything related to creating the `canvas` DOM tag that Phaser will use, including styles, offset and aspect ratio.
     *
     * @class Phaser.Canvas
     * @static
    @@ -436,21 +430,29 @@
     Phaser.Canvas = {
     
         /**
    -    * Creates the <canvas> tag
    +    * Creates a `canvas` DOM element. The element is not automatically added to the document.
         *
         * @method Phaser.Canvas.create
    -    * @param {number} width - The desired width.
    -    * @param {number} height - The desired height.
    -    * @return {HTMLCanvasElement} The newly created <canvas> tag.
    +    * @param {number} [width=256] - The width of the canvas element.
    +    * @param {number} [height=256] - The height of the canvas element..
    +    * @param {string} [id=''] - If given this will be set as the ID of the canvas element, otherwise no ID will be set.
    +    * @return {HTMLCanvasElement} The newly created canvas element.
         */
    -    create: function (width, height) {
    +    create: function (width, height, id) {
     
             width = width || 256;
             height = height || 256;
     
             var canvas = document.createElement('canvas');
    +
    +        if (typeof id === 'string')
    +        {
    +            canvas.id = id;
    +        }
    +
             canvas.width = width;
             canvas.height = height;
    +
             canvas.style.display = 'block';
     
             return canvas;
    @@ -471,8 +473,22 @@ Phaser.Canvas = {
             var box = element.getBoundingClientRect();
             var clientTop = element.clientTop || document.body.clientTop || 0;
             var clientLeft = element.clientLeft || document.body.clientLeft || 0;
    -        var scrollTop = window.pageYOffset || element.scrollTop || document.body.scrollTop;
    -        var scrollLeft = window.pageXOffset || element.scrollLeft || document.body.scrollLeft;
    +
    +        //  Without this check Chrome is now throwing console warnings about strict vs. quirks :(
    +
    +        var scrollTop = 0;
    +        var scrollLeft = 0;
    +
    +        if (document.compatMode === 'CSS1Compat')
    +        {
    +            scrollTop = window.pageYOffset || document.documentElement.scrollTop || element.scrollTop || 0;
    +            scrollLeft = window.pageXOffset || document.documentElement.scrollLeft || element.scrollLeft || 0;
    +        }
    +        else
    +        {
    +            scrollTop = window.pageYOffset || document.body.scrollTop || element.scrollTop || 0;
    +            scrollLeft = window.pageXOffset || document.body.scrollLeft || element.scrollLeft || 0;
    +        }
     
             point.x = box.left + scrollLeft - clientLeft;
             point.y = box.top + scrollTop - clientTop;
    @@ -560,8 +576,8 @@ Phaser.Canvas = {
         *
         * @method Phaser.Canvas.addToDOM
         * @param {HTMLCanvasElement} canvas - The canvas to set the touch action on.
    -    * @param {string|HTMLElement} parent - The DOM element to add the canvas to. Defaults to ''.
    -    * @param {boolean} overflowHidden - If set to true it will add the overflow='hidden' style to the parent DOM element.
    +    * @param {string|HTMLElement} parent - The DOM element to add the canvas to.
    +    * @param {boolean} [overflowHidden=true] - If set to true it will add the overflow='hidden' style to the parent DOM element.
         * @return {HTMLCanvasElement} Returns the source canvas.
         */
         addToDOM: function (canvas, parent, overflowHidden) {
    @@ -572,29 +588,29 @@ Phaser.Canvas = {
     
             if (parent)
             {
    -            // hopefully an element ID
                 if (typeof parent === 'string')
                 {
    +                // hopefully an element ID
                     target = document.getElementById(parent);
                 }
    -            // quick test for a HTMLelement
                 else if (typeof parent === 'object' && parent.nodeType === 1)
                 {
    +                // quick test for a HTMLelement
                     target = parent;
                 }
    -
    -            if (overflowHidden)
    -            {
    -                target.style.overflow = 'hidden';
    -            }
             }
     
    -        // fallback, covers an invalid ID and a none HTMLelement object
    -        if(!target)
    +        // Fallback, covers an invalid ID and a non HTMLelement object
    +        if (!target)
             {
                 target = document.body;
             }
     
    +        if (overflowHidden && target.style)
    +        {
    +            target.style.overflow = 'hidden';
    +        }
    +
             target.appendChild(canvas);
     
             return canvas;
    @@ -656,9 +672,11 @@ Phaser.Canvas = {
         */
         setImageRenderingCrisp: function (canvas) {
     
    +        canvas.style['image-rendering'] = 'optimizeSpeed';
             canvas.style['image-rendering'] = 'crisp-edges';
             canvas.style['image-rendering'] = '-moz-crisp-edges';
             canvas.style['image-rendering'] = '-webkit-optimize-contrast';
    +        canvas.style['image-rendering'] = 'optimize-contrast';
             canvas.style.msInterpolationMode = 'nearest-neighbor';
     
             return canvas;
    @@ -698,13 +716,13 @@ Phaser.Canvas = {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Circle.js.html b/docs/Circle.js.html index 41f1a8a5..b66a23cb 100644 --- a/docs/Circle.js.html +++ b/docs/Circle.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -432,9 +426,9 @@
     * @class Circle
     * @classdesc Phaser - Circle
     * @constructor
    -* @param {number} [x] The x coordinate of the center of the circle.
    -* @param {number} [y] The y coordinate of the center of the circle.
    -* @param {number} [diameter] The diameter of the circle.
    +* @param {number} [x=0] - The x coordinate of the center of the circle.
    +* @param {number} [y=0] - The y coordinate of the center of the circle.
    +* @param {number} [diameter=0] - The diameter of the circle.
     * @return {Phaser.Circle} This circle object
     */
     Phaser.Circle = function (x, y, diameter) {
    @@ -618,6 +612,8 @@ Phaser.Circle.prototype = {
     
     };
     
    +Phaser.Circle.prototype.constructor = Phaser.Circle;
    +
     /**
     * The largest distance between any two points on the circle. The same as the radius * 2.
     * @name Phaser.Circle#diameter
    @@ -911,13 +907,13 @@ Phaser.Circle.intersectsRectangle = function (c, r) {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Color.js.html b/docs/Color.js.html index 904f01d0..ed3362bd 100644 --- a/docs/Color.js.html +++ b/docs/Color.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -787,13 +781,13 @@ Phaser.Color = {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/DOMSprite.js.html b/docs/DOMSprite.js.html new file mode 100644 index 00000000..9bd6f200 --- /dev/null +++ b/docs/DOMSprite.js.html @@ -0,0 +1,567 @@ + + + + + + Phaser Source: gameobjects/DOMSprite.js + + + + + + + + + + +
    + + +
    + + +
    + +
    + + + +

    Source: gameobjects/DOMSprite.js

    + +
    +
    +
    /**
    +* @author       Richard Davey <rich@photonstorm.com>
    +* @copyright    2014 Photon Storm Ltd.
    +* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
    +*/
    +
    +/**
    +* Create a new DOMSprite.
    +* @class Phaser.DOMSprite
    +* @constructor
    +* @param {Phaser.Game} game - Current game instance.
    +* @param {string} id - DOM ID.
    +* @param {number} x - X position of the new text object.
    +* @param {number} y - Y position of the new text object.
    +* @param {string} text - The actual text that will be written.
    +* @param {object} style - The style object containing style attributes like font, font size ,
    +*/
    +Phaser.DOMSprite = function (game, element, x, y, style) {
    +
    +    x = x || 0;
    +    y = y || 0;
    +    style = style || '';
    +
    +    /**
    +    * @property {Phaser.Game} game - A reference to the currently running Game.
    +    */
    +    this.game = game;
    + 
    +    /**
    +    * @property {boolean} exists - If exists = false then the Text isn't updated by the core game loop.
    +    * @default
    +    */
    +    this.exists = true;
    +
    +    /**
    +    * @property {boolean} alive - This is a handy little var your game can use to determine if an object is alive or not, it doesn't effect rendering.
    +    * @default
    +    */
    +    this.alive = true;
    +
    +    /**
    +    * @property {Phaser.Group} group - The parent Group of this Text object.
    +    */
    +    this.group = null;
    +
    +    /**
    +    * @property {string} name - The user defined name given to this object.
    +    * @default
    +    */
    +    this.name = '';
    +
    +    /**
    +    * @property {number} type - The const type of this object.
    +    * @default
    +    */
    +    this.type = Phaser.DOMSPRITE;
    +
    +    /**
    +    * @property {boolean} visible - Sets the visible state of this DOMSprite.
    +    * @default
    +    */
    +    this.visible = true;
    +
    +    /*
    +    if (parent)
    +    {
    +        if (typeof parent === 'string')
    +        {
    +            // hopefully an element ID
    +            target = document.getElementById(parent);
    +        }
    +        else if (typeof parent === 'object' && parent.nodeType === 1)
    +        {
    +            // quick test for a HTMLelement
    +            target = parent;
    +        }
    +
    +        if (overflowHidden)
    +        {
    +            target.style.overflow = 'hidden';
    +        }
    +    }
    +    */
    +
    +};
    +
    +// Phaser.DOMSprite.prototype = Object.create(PIXI.DOMSprite.prototype);
    +// Phaser.DOMSprite.prototype.constructor = Phaser.DOMSprite;
    +
    +
    +
    + + + + + +
    + +
    +
    + + + + Phaser Copyright © 2012-2014 Photon Storm Ltd. + +
    + + + Documentation generated by JSDoc 3.3.0-dev + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + diff --git a/docs/Debug.js.html b/docs/Debug.js.html index 05fb0929..3db78003 100644 --- a/docs/Debug.js.html +++ b/docs/Debug.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -453,6 +447,11 @@ Phaser.Utils.Debug = function (game) {
         */
         this.font = '14px Courier';
        
    +    /**
    +    * @property {number} columnWidth - The spacing between columns.
    +    */
    +    this.columnWidth = 100;
    +
         /**
         * @property {number} lineHeight - The line height between the debug text.
         */
    @@ -488,11 +487,12 @@ Phaser.Utils.Debug.prototype = {
         /**
         * Internal method that resets and starts the debug output values.
         * @method Phaser.Utils.Debug#start
    -    * @param {number} x - The X value the debug info will start from.
    -    * @param {number} y - The Y value the debug info will start from.
    -    * @param {string} color - The color the debug info will drawn in.
    +    * @param {number} [x=0] - The X value the debug info will start from.
    +    * @param {number} [y=0] - The Y value the debug info will start from.
    +    * @param {string} [color='rgb(255,255,255)'] - The color the debug text will drawn in.
    +    * @param {number} [columnWidth=0] - The spacing between columns.
         */
    -    start: function (x, y, color) {
    +    start: function (x, y, color, columnWidth) {
     
             if (this.context == null)
             {
    @@ -501,16 +501,18 @@ Phaser.Utils.Debug.prototype = {
     
             if (typeof x !== 'number') { x = 0; }
             if (typeof y !== 'number') { y = 0; }
    -
             color = color || 'rgb(255,255,255)';
    +        if (typeof columnWidth === 'undefined') { columnWidth = 0; }
     
             this.currentX = x;
             this.currentY = y;
             this.currentColor = color;
             this.currentAlpha = this.context.globalAlpha;
    +        this.columnWidth = columnWidth;
     
             this.context.save();
             this.context.setTransform(1, 0, 0, 1, 0, 0);
    +        this.context.strokeStyle = color;
             this.context.fillStyle = color;
             this.context.font = this.font;
             this.context.globalAlpha = 1;
    @@ -523,7 +525,6 @@ Phaser.Utils.Debug.prototype = {
         */
         stop: function () {
     
    -
             this.context.restore();
             this.context.globalAlpha = this.currentAlpha;
     
    @@ -533,8 +534,8 @@ Phaser.Utils.Debug.prototype = {
         * Internal method that outputs a single line of text.
         * @method Phaser.Utils.Debug#line
         * @param {string} text - The line of text to draw.
    -    * @param {number} x - The X value the debug info will start from.
    -    * @param {number} y - The Y value the debug info will start from.
    +    * @param {number} [x] - The X value the debug info will start from.
    +    * @param {number} [y] - The Y value the debug info will start from.
         */
         line: function (text, x, y) {
     
    @@ -543,16 +544,8 @@ Phaser.Utils.Debug.prototype = {
                 return;
             }
     
    -        x = x || null;
    -        y = y || null;
    -
    -        if (x !== null) {
    -            this.currentX = x;
    -        }
    -
    -        if (y !== null) {
    -            this.currentY = y;
    -        }
    +        if (typeof x !== 'undefined') { this.currentX = x; }
    +        if (typeof y !== 'undefined') { this.currentY = y; }
     
             if (this.renderShadow)
             {
    @@ -566,6 +559,38 @@ Phaser.Utils.Debug.prototype = {
     
         },
     
    +    /**
    +    * Internal method that outputs a single line of text split over as many columns as needed, one per parameter.
    +    * @method Phaser.Utils.Debug#splitline
    +    * @param {string} text - The text to render. You can have as many columns of text as you want, just pass them as additional parameters.
    +    */
    +    splitline: function (text) {
    +
    +        if (this.context == null)
    +        {
    +            return;
    +        }
    +
    +        var x = this.currentX;
    +
    +        for (var i = 0; i < arguments.length; i++)
    +        {
    +            if (this.renderShadow)
    +            {
    +                this.context.fillStyle = 'rgb(0,0,0)';
    +                this.context.fillText(arguments[i], x + 1, this.currentY + 1);
    +                this.context.fillStyle = this.currentColor;
    +            }
    +
    +            this.context.fillText(arguments[i], x, this.currentY);
    +
    +            x += this.columnWidth;
    +        }
    +
    +        this.currentY += this.lineHeight;
    +
    +    },
    +
         /**
         * Visually renders a QuadTree to the display.
         * @method Phaser.Utils.Debug#renderQuadTree
    @@ -811,25 +836,27 @@ Phaser.Utils.Debug.prototype = {
         },
     
         /**
    -    * Render Sprite collision.
    -    * @method Phaser.Utils.Debug#renderSpriteCollision
    +    * Render Sprite Body Physics Data as text.
    +    * @method Phaser.Utils.Debug#renderBodyInfo
         * @param {Phaser.Sprite} sprite - The sprite to be rendered.
         * @param {number} x - X position of the debug info to be rendered.
         * @param {number} y - Y position of the debug info to be rendered.
         * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string).
         */
    -    renderSpriteCollision: function (sprite, x, y, color) {
    +    renderBodyInfo: function (sprite, x, y, color) {
     
             color = color || 'rgb(255,255,255)';
     
    -        this.start(x, y, color);
    -        this.line('Sprite Collision: (' + sprite.width + ' x ' + sprite.height + ')');
    -        this.line('left: ' + sprite.body.touching.left);
    -        this.line('right: ' + sprite.body.touching.right);
    -        this.line('up: ' + sprite.body.touching.up);
    -        this.line('down: ' + sprite.body.touching.down);
    -        this.line('velocity.x: ' + sprite.body.velocity.x);
    -        this.line('velocity.y: ' + sprite.body.velocity.y);
    +        this.start(x, y, color, 210);
    +
    +        this.splitline('x: ' + sprite.body.x.toFixed(2), 'y: ' + sprite.body.y.toFixed(2), 'width: ' + sprite.width, 'height: ' + sprite.height);
    +        this.splitline('speed: ' + sprite.body.speed.toFixed(2), 'angle: ' + sprite.body.angle.toFixed(2), 'linear damping: ' + sprite.body.linearDamping);
    +        this.splitline('blocked left: ' + sprite.body.blocked.left, 'right: ' + sprite.body.blocked.right, 'up: ' + sprite.body.blocked.up, 'down: ' + sprite.body.blocked.down);
    +        this.splitline('touching left: ' + sprite.body.touching.left, 'right: ' + sprite.body.touching.right, 'up: ' + sprite.body.touching.up, 'down: ' + sprite.body.touching.down);
    +        this.splitline('gravity x: ' + sprite.body.gravity.x, 'y: ' + sprite.body.gravity.y, 'world gravity x: ' + this.game.physics.gravity.x, 'y: ' + this.game.physics.gravity.y);
    +        this.splitline('acceleration x: ' + sprite.body.acceleration.x.toFixed(2), 'y: ' + sprite.body.acceleration.y.toFixed(2));
    +        this.splitline('velocity x: ' + sprite.body.velocity.x.toFixed(2), 'y: ' + sprite.body.velocity.y.toFixed(2), 'deltaX: ' + sprite.body.deltaX().toFixed(2), 'deltaY: ' + sprite.body.deltaY().toFixed(2));
    +        this.splitline('bounce x: ' + sprite.body.bounce.x.toFixed(2), 'y: ' + sprite.body.bounce.y.toFixed(2));
             this.stop();
     
         },
    @@ -892,17 +919,15 @@ Phaser.Utils.Debug.prototype = {
             //  4 = scaleY
             //  5 = translateY
     
    -        // this.line('id: ' + sprite._id);
    -        // this.line('scale x: ' + sprite.worldTransform[0]);
    -        // this.line('scale y: ' + sprite.worldTransform[4]);
    -        // this.line('tx: ' + sprite.worldTransform[2]);
    -        // this.line('ty: ' + sprite.worldTransform[5]);
    -        // this.line('skew x: ' + sprite.worldTransform[3]);
    -        // this.line('skew y: ' + sprite.worldTransform[1]);
    -        this.line('deltaX: ' + sprite.body.deltaX());
    -        this.line('deltaY: ' + sprite.body.deltaY());
    -        // this.line('sdx: ' + sprite.deltaX());
    -        // this.line('sdy: ' + sprite.deltaY());
    +        this.line('id: ' + sprite._id);
    +        this.line('scale x: ' + sprite.worldTransform[0]);
    +        this.line('scale y: ' + sprite.worldTransform[4]);
    +        this.line('tx: ' + sprite.worldTransform[2]);
    +        this.line('ty: ' + sprite.worldTransform[5]);
    +        this.line('skew x: ' + sprite.worldTransform[3]);
    +        this.line('skew y: ' + sprite.worldTransform[1]);
    +        this.line('sdx: ' + sprite.deltaX);
    +        this.line('sdy: ' + sprite.deltaY);
     
             // this.line('inCamera: ' + this.game.renderer.spriteRenderer.inCamera(this.game.camera, sprite));
             this.stop();
    @@ -910,65 +935,13 @@ Phaser.Utils.Debug.prototype = {
         },
     
         /**
    -    * Render the World Transform information of the given Sprite.
    -    * @method Phaser.Utils.Debug#renderWorldTransformInfo
    -    * @param {Phaser.Sprite} sprite - Description.
    +    * Renders the sprite coordinates in local, positional and world space.
    +    * @method Phaser.Utils.Debug#renderSpriteCoords
    +    * @param {Phaser.Sprite} line - The sprite to inspect.
         * @param {number} x - X position of the debug info to be rendered.
         * @param {number} y - Y position of the debug info to be rendered.
         * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string).
         */
    -    renderWorldTransformInfo: function (sprite, x, y, color) {
    -
    -        if (this.context == null)
    -        {
    -            return;
    -        }
    -
    -        color = color || 'rgb(255, 255, 255)';
    -
    -        this.start(x, y, color);
    -
    -        this.line('World Transform');
    -        this.line('skewX:  ' + sprite.worldTransform[3]);
    -        this.line('skewY:  ' + sprite.worldTransform[1]);
    -        this.line('scaleX: ' + sprite.worldTransform[0]);
    -        this.line('scaleY: ' + sprite.worldTransform[4]);
    -        this.line('transX: ' + sprite.worldTransform[2]);
    -        this.line('transY: ' + sprite.worldTransform[5]);
    -        this.stop();
    -
    -    },
    -
    -    /**
    -    * Render the Local Transform information of the given Sprite.
    -    * @method Phaser.Utils.Debug#renderLocalTransformInfo
    -    * @param {Phaser.Sprite} sprite - Description.
    -    * @param {number} x - X position of the debug info to be rendered.
    -    * @param {number} y - Y position of the debug info to be rendered.
    -    * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string).
    -    */
    -    renderLocalTransformInfo: function (sprite, x, y, color) {
    -
    -        if (this.context == null)
    -        {
    -            return;
    -        }
    -
    -        color = color || 'rgb(255, 255, 255)';
    -
    -        this.start(x, y, color);
    -
    -        this.line('Local Transform');
    -        this.line('skewX:  ' + sprite.localTransform[3]);
    -        this.line('skewY:  ' + sprite.localTransform[1]);
    -        this.line('scaleX: ' + sprite.localTransform[0]);
    -        this.line('scaleY: ' + sprite.localTransform[4]);
    -        this.line('transX: ' + sprite.localTransform[2]);
    -        this.line('transY: ' + sprite.localTransform[5]);
    -        this.stop();
    -
    -    },
    -
         renderSpriteCoords: function (sprite, x, y, color) {
     
             if (this.context == null)
    @@ -978,29 +951,28 @@ Phaser.Utils.Debug.prototype = {
     
             color = color || 'rgb(255, 255, 255)';
     
    -        this.start(x, y, color);
    +        this.start(x, y, color, 100);
     
             if (sprite.name)
             {
                 this.line(sprite.name);
             }
     
    -        this.line('x: ' + sprite.x);
    -        this.line('y: ' + sprite.y);
    -        this.line('pos x: ' + sprite.position.x);
    -        this.line('pos y: ' + sprite.position.y);
    -        this.line('local x: ' + sprite.localTransform[2]);
    -        this.line('local y: ' + sprite.localTransform[5]);
    -        this.line('t x: ' + sprite.worldTransform[2]);
    -        this.line('t y: ' + sprite.worldTransform[5]);
    -        this.line('world x: ' + sprite.world.x);
    -        this.line('world y: ' + sprite.world.y);
    +        this.splitline('x:', sprite.x.toFixed(2), 'y:', sprite.y.toFixed(2));
    +        this.splitline('pos x:', sprite.position.x.toFixed(2), 'pos y:', sprite.position.y.toFixed(2));
    +        this.splitline('world x:', sprite.world.x.toFixed(2), 'world y:', sprite.world.y.toFixed(2));
     
             this.stop();
     
         },
     
    -    renderGroupInfo: function (group, x, y, color) {
    +    /**
    +    * Renders a Line object in the given color.
    +    * @method Phaser.Utils.Debug#renderLine
    +    * @param {Phaser.Line} line - The Line to render.
    +    * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string).
    +    */
    +    renderLine: function (line, color) {
     
             if (this.context == null)
             {
    @@ -1009,12 +981,38 @@ Phaser.Utils.Debug.prototype = {
     
             color = color || 'rgb(255, 255, 255)';
     
    -        this.start(x, y, color);
    +        this.start(0, 0, color);
    +        this.context.lineWidth = 1;
    +        this.context.beginPath();
    +        this.context.moveTo(line.start.x + 0.5, line.start.y + 0.5);
    +        this.context.lineTo(line.end.x + 0.5, line.end.y + 0.5);
    +        this.context.closePath();
    +        this.context.stroke();
    +        this.stop();
     
    -        this.line('Group (size: ' + group.length + ')');
    -        this.line('x: ' + group.x);
    -        this.line('y: ' + group.y);
    +    },
     
    +    /**
    +    * Renders Line information in the given color.
    +    * @method Phaser.Utils.Debug#renderLineInfo
    +    * @param {Phaser.Line} line - The Line to render.
    +    * @param {number} x - X position of the debug info to be rendered.
    +    * @param {number} y - Y position of the debug info to be rendered.
    +    * @param {string} [color='rgb(255,255,255)'] - color of the debug info to be rendered. (format is css color string).
    +    */
    +    renderLineInfo: function (line, x, y, color) {
    +
    +        if (this.context == null)
    +        {
    +            return;
    +        }
    +
    +        color = color || 'rgb(255, 255, 255)';
    +
    +        this.start(x, y, color, 80);
    +        this.splitline('start.x:', line.start.x.toFixed(2), 'start.y:', line.start.y.toFixed(2));
    +        this.splitline('end.x:', line.end.x.toFixed(2), 'end.y:', line.end.y.toFixed(2));
    +        this.splitline('length:', line.length.toFixed(2), 'angle:', line.angle);
             this.stop();
     
         },
    @@ -1043,24 +1041,36 @@ Phaser.Utils.Debug.prototype = {
         },
     
         /**
    -    * Renders just the Sprite.body bounds.
    -    * @method Phaser.Utils.Debug#renderSpriteBody
    +    * Renders just the full Sprite bounds.
    +    * @method Phaser.Utils.Debug#renderSpriteBounds
         * @param {Phaser.Sprite} sprite - Description.
         * @param {string} [color] - Color of the debug info to be rendered (format is css color string).
    +    * @param {boolean} [fill=false] - If false the bounds outline is rendered, if true the whole rectangle is rendered.
         */
    -    renderSpriteBody: function (sprite, color) {
    +    renderSpriteBody: function (sprite, color, fill) {
     
             if (this.context == null)
             {
                 return;
             }
     
    -        color = color || 'rgba(255,0,255, 0.3)';
    +        color = color || 'rgb(255,0,255)';
    +
    +        if (typeof fill === 'undefined') { fill = false; }
     
             this.start(0, 0, color);
     
    -        this.context.fillStyle = color;
    -        this.context.fillRect(sprite.body.screenX, sprite.body.screenY, sprite.body.width, sprite.body.height);
    +        if (fill)
    +        {
    +            this.context.fillStyle = color;
    +            this.context.fillRect(sprite.body.left, sprite.body.top, sprite.body.width, sprite.body.height);
    +        }
    +        else
    +        {
    +            this.context.strokeStyle = color;
    +            this.context.strokeRect(sprite.body.left, sprite.body.top, sprite.body.width, sprite.body.height);
    +            this.context.stroke();
    +        }
     
             this.stop();
     
    @@ -1222,86 +1232,110 @@ Phaser.Utils.Debug.prototype = {
         },
     
         /**
    -    * Dumps the Linked List to the console.
    -    * 
    -    * @method Phaser.Utils.Debug#Phaser.LinkedList#dump 
    -    * @param {Phaser.LinkedList} list - The LinkedList to dump.
    +    * @method Phaser.Utils.Debug#renderPhysicsBody
    +    * @param {array} body
    +    * @param {string} [color='rgb(255,255,255)'] - The color the polygon is stroked in.
         */
    -    dumpLinkedList: function (list) {
    +    renderPhysicsBody: function (body, color, context) {
     
    -        var spacing = 20;
    -
    -        var output = "\n" + Phaser.Utils.pad('Node', spacing) + "|" + Phaser.Utils.pad('Next', spacing) + "|" + Phaser.Utils.pad('Previous', spacing) + "|" + Phaser.Utils.pad('First', spacing) + "|" + Phaser.Utils.pad('Last', spacing);
    -        console.log(output);
    -
    -        var output = Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing);
    -        console.log(output);
    -
    -        var entity = list;
    -
    -        var testObject = entity.last.next;
    -        entity = entity.first;
    -        
    -        do
    +        if (this.context === null && context === null)
             {
    -            var name = entity.sprite.name || '*';
    -            var nameNext = '-';
    -            var namePrev = '-';
    -            var nameFirst = '-';
    -            var nameLast = '-';
    -
    -            if (entity.next)
    -            {
    -                nameNext = entity.next.sprite.name;
    -            }
    -
    -            if (entity.prev)
    -            {
    -                namePrev = entity.prev.sprite.name;
    -            }
    -
    -            if (entity.first)
    -            {
    -                nameFirst = entity.first.sprite.name;
    -            }
    -
    -            if (entity.last)
    -            {
    -                nameLast = entity.last.sprite.name;
    -            }
    -
    -            if (typeof nameNext === 'undefined')
    -            {
    -                nameNext = '-';
    -            }
    -
    -            if (typeof namePrev === 'undefined')
    -            {
    -                namePrev = '-';
    -            }
    -
    -            if (typeof nameFirst === 'undefined')
    -            {
    -                nameFirst = '-';
    -            }
    -
    -            if (typeof nameLast === 'undefined')
    -            {
    -                nameLast = '-';
    -            }
    -
    -            var output = Phaser.Utils.pad(name, spacing) + "|" + Phaser.Utils.pad(nameNext, spacing) + "|" + Phaser.Utils.pad(namePrev, spacing) + "|" + Phaser.Utils.pad(nameFirst, spacing) + "|" + Phaser.Utils.pad(nameLast, spacing);
    -            console.log(output);
    -
    -            entity = entity.next;
    -
    +            return;
             }
    -        while(entity != testObject)
    +
    +        color = color || 'rgb(255,255,255)';
    +
    +        var x = body.x - this.game.camera.x;
    +        var y = body.y - this.game.camera.y;
    +
    +        if (body.type === Phaser.Physics.Arcade.CIRCLE)
    +        {
    +            this.start(0, 0, color);
    +            this.context.beginPath();
    +            this.context.strokeStyle = color;
    +            this.context.arc(x, y, body.shape.r, 0, Math.PI * 2, false);
    +            this.context.stroke();
    +            this.context.closePath();
    +
    +            // this.context.strokeStyle = 'rgb(0,0,255)';
    +            // this.context.strokeRect(body.left, body.top, body.width, body.height);
    +
    +            this.stop();
    +        }
    +        else
    +        {
    +            var points = body.polygon.points;
    +
    +            this.start(0, 0, color);
    +
    +            this.context.beginPath();
    +            this.context.moveTo(x + points[0].x, y + points[0].y);
    +
    +            for (var i = 1; i < points.length; i++)
    +            {
    +                this.context.lineTo(x + points[i].x, y + points[i].y);
    +            }
    +
    +            this.context.closePath();
    +            this.context.strokeStyle = color;
    +            this.context.stroke();
    +
    +            this.context.fillStyle = 'rgb(255,0,0)';
    +            this.context.fillRect(x + points[0].x - 2, y + points[0].y - 2, 5, 5);
    +
    +            for (var i = 1; i < points.length; i++)
    +            {
    +                this.context.fillStyle = 'rgb(255,' + (i * 40) + ',0)';
    +                this.context.fillRect(x + points[i].x - 2, y + points[i].y - 2, 5, 5);
    +            }
    +
    +            // this.context.strokeStyle = 'rgb(0,255,255)';
    +            // this.context.strokeRect(body.left, body.top, body.width, body.height);
    +
    +            this.stop();
    +        }
    +
    +    },
    +
    +    /**
    +    * @method Phaser.Utils.Debug#renderPolygon
    +    * @param {array} polygon
    +    * @param {string} [color='rgb(255,255,255)'] - The color the polygon is stroked in.
    +    */
    +    renderPolygon: function (polygon, color, context) {
    +
    +        if (this.context === null && context === null)
    +        {
    +            return;
    +        }
    +
    +        color = color || 'rgb(255,255,255)';
    +
    +        var points = polygon.points;
    +        var x = polygon.pos.x;
    +        var y = polygon.pos.y;
    +
    +        this.start(0, 0, color);
    +
    +        this.context.beginPath();
    +        this.context.moveTo(x + points[0].x, y + points[0].y);
    +
    +        for (var i = 1; i < points.length; i++)
    +        {
    +            this.context.lineTo(x + points[i].x, y + points[i].y);
    +        }
    +
    +        this.context.closePath();
    +        this.context.strokeStyle = color;
    +        this.context.stroke();
    +
    +        this.stop();
     
         }
     
    -
     };
    +
    +Phaser.Utils.Debug.prototype.constructor = Phaser.Utils.Debug;
     
    @@ -1317,13 +1351,13 @@ Phaser.Utils.Debug.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Device.js.html b/docs/Device.js.html index d2be1bb7..b5182378 100644 --- a/docs/Device.js.html +++ b/docs/Device.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -463,6 +457,12 @@ Phaser.Device = function () {
         */
         this.cocoonJS = false;
     
    +    /**
    +     * @property {boolean} ejecta - Is the game running under Ejecta?
    +     * @default
    +     */
    +    this.ejecta = false;
    +
         /**
         * @property {boolean} android - Is running on android?
         * @default
    @@ -561,6 +561,18 @@ Phaser.Device = function () {
         */
         this.typedArray = false;
     
    +    /**
    +    * @property {boolean} vibration - Does the device support the Vibration API?
    +    * @default
    +    */
    +    this.vibration = false;
    +
    +    /**
    +    * @property {boolean} quirksMode - Is the browser running in strict mode (false) or quirks mode? (true)
    +    * @default
    +    */
    +    this.quirksMode = false;
    +
         //  Browser
     
         /**
    @@ -599,6 +611,18 @@ Phaser.Device = function () {
         */
         this.ieVersion = 0;
     
    +    /**
    +    * @property {boolean} trident - Set to true if running a Trident version of Internet Explorer (IE11+)
    +    * @default
    +    */
    +    this.trident = false;
    +
    +    /**
    +    * @property {number} tridentVersion - If running in Internet Explorer 11 this will contain the major version number. See http://msdn.microsoft.com/en-us/library/ie/ms537503(v=vs.85).aspx
    +    * @default
    +    */
    +    this.tridentVersion = 0;
    +
         /**
         * @property {boolean} mobileSafari - Set to true if running in Mobile Safari.
         * @default
    @@ -629,6 +653,12 @@ Phaser.Device = function () {
         */
         this.webApp = false;
     
    +    /**
    +    * @property {boolean} silk - Set to true if running in the Silk browser (as used on the Amazon Kindle)
    +    * @default
    +    */
    +    this.silk = false;
    +
         //  Audio
     
         /**
    @@ -733,21 +763,33 @@ Phaser.Device.prototype = {
     
             var ua = navigator.userAgent;
     
    -        if (/Android/.test(ua)) {
    +        if (/Android/.test(ua))
    +        {
                 this.android = true;
    -        } else if (/CrOS/.test(ua)) {
    +        }
    +        else if (/CrOS/.test(ua))
    +        {
                 this.chromeOS = true;
    -        } else if (/iP[ao]d|iPhone/i.test(ua)) {
    +        }
    +        else if (/iP[ao]d|iPhone/i.test(ua))
    +        {
                 this.iOS = true;
    -        } else if (/Linux/.test(ua)) {
    +        }
    +        else if (/Linux/.test(ua))
    +        {
                 this.linux = true;
    -        } else if (/Mac OS/.test(ua)) {
    +        }
    +        else if (/Mac OS/.test(ua))
    +        {
                 this.macOS = true;
    -        } else if (/Windows/.test(ua)) {
    +        }
    +        else if (/Windows/.test(ua))
    +        {
                 this.windows = true;
             }
     
    -        if (this.windows || this.macOS || this.linux) {
    +        if (this.windows || this.macOS || (this.linux && this.silk === false))
    +        {
                 this.desktop = true;
             }
     
    @@ -783,16 +825,20 @@ Phaser.Device.prototype = {
     
             this.worker = !!window['Worker'];
             
    -        if ('ontouchstart' in document.documentElement || (window.navigator.maxTouchPoints && window.navigator.maxTouchPoints > 1)) {
    +        if ('ontouchstart' in document.documentElement || (window.navigator.maxTouchPoints && window.navigator.maxTouchPoints > 1))
    +        {
                 this.touch = true;
             }
     
    -        if (window.navigator.msPointerEnabled || window.navigator.pointerEnabled) {
    +        if (window.navigator.msPointerEnabled || window.navigator.pointerEnabled)
    +        {
                 this.mspointer = true;
             }
             
             this.pointerLock = 'pointerLockElement' in document || 'mozPointerLockElement' in document || 'webkitPointerLockElement' in document;
     
    +        this.quirksMode = (document.compatMode === 'CSS1Compat') ? false : true;
    +
         },
     
         /**
    @@ -804,36 +850,70 @@ Phaser.Device.prototype = {
     
             var ua = navigator.userAgent;
     
    -        if (/Arora/.test(ua)) {
    +        if (/Arora/.test(ua))
    +        {
                 this.arora = true;
    -        } else if (/Chrome/.test(ua)) {
    +        }
    +        else if (/Chrome/.test(ua))
    +        {
                 this.chrome = true;
    -        } else if (/Epiphany/.test(ua)) {
    +        }
    +        else if (/Epiphany/.test(ua))
    +        {
                 this.epiphany = true;
    -        } else if (/Firefox/.test(ua)) {
    +        }
    +        else if (/Firefox/.test(ua))
    +        {
                 this.firefox = true;
    -        } else if (/Mobile Safari/.test(ua)) {
    +        }
    +        else if (/Mobile Safari/.test(ua))
    +        {
                 this.mobileSafari = true;
    -        } else if (/MSIE (\d+\.\d+);/.test(ua)) {
    +        }
    +        else if (/MSIE (\d+\.\d+);/.test(ua))
    +        {
                 this.ie = true;
                 this.ieVersion = parseInt(RegExp.$1, 10);
    -        } else if (/Midori/.test(ua)) {
    +        }
    +        else if (/Midori/.test(ua))
    +        {
                 this.midori = true;
    -        } else if (/Opera/.test(ua)) {
    +        }
    +        else if (/Opera/.test(ua))
    +        {
                 this.opera = true;
    -        } else if (/Safari/.test(ua)) {
    +        }
    +        else if (/Safari/.test(ua))
    +        {
                 this.safari = true;
             }
    +        else if (/Silk/.test(ua))
    +        {
    +            this.silk = true;
    +        }
    +        else if (/Trident\/(\d+\.\d+);/.test(ua))
    +        {
    +            this.ie = true;
    +            this.trident = true;
    +            this.tridentVersion = parseInt(RegExp.$1, 10);
    +        }
     
             // WebApp mode in iOS
    -        if (navigator['standalone']) {
    +        if (navigator['standalone'])
    +        {
                 this.webApp = true;
             }
     
    -        if (navigator['isCocoonJS']) {
    +        if (navigator['isCocoonJS'])
    +        {
                 this.cocoonJS = true;
             }
     
    +        if (typeof window.ejecta !== "undefined")
    +        {
    +            this.ejecta = true;
    +        }
    +
         },
     
         /**
    @@ -906,6 +986,13 @@ Phaser.Device.prototype = {
                 this.typedArray = false;
             }
     
    +        navigator.vibrate = navigator.vibrate || navigator.webkitVibrate || navigator.mozVibrate || navigator.msVibrate;
    +         
    +        if (navigator.vibrate)
    +        {
    +            this.vibration = true;
    +        }
    +
         },
     
         /**
    @@ -928,8 +1015,10 @@ Phaser.Device.prototype = {
             // Add it to the body to get the computed style.
             document.body.insertBefore(el, null);
     
    -        for (var t in transforms) {
    -            if (el.style[t] !== undefined) {
    +        for (var t in transforms)
    +        {
    +            if (el.style[t] !== undefined)
    +            {
                     el.style[t] = "translate3d(1px,1px,1px)";
                     has3d = window.getComputedStyle(el).getPropertyValue(transforms[t]);
                 }
    @@ -1003,6 +1092,8 @@ Phaser.Device.prototype = {
         }
     
     };
    +
    +Phaser.Device.prototype.constructor = Phaser.Device;
     
    @@ -1018,13 +1109,13 @@ Phaser.Device.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Easing.js.html b/docs/Easing.js.html index f7b7fe22..4c9ee5bf 100644 --- a/docs/Easing.js.html +++ b/docs/Easing.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -425,7 +419,7 @@ /** * @author Richard Davey <rich@photonstorm.com> -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -999,13 +993,13 @@ Phaser.Easing = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Emitter.js.html b/docs/Emitter.js.html index fdd2c084..f12e2643 100644 --- a/docs/Emitter.js.html +++ b/docs/Emitter.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -445,7 +439,6 @@
     Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) {
     
         /**
    -    * The total number of particles in this emitter.
         * @property {number} maxParticles - The total number of particles in this emitter..
         * @default
         */
    @@ -459,7 +452,8 @@ Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) {
         this.name = 'emitter' + this.game.particles.ID++;
     
         /**
    -    * @property {Description} type - Description.
    +    * @property {number} type - Internal Phaser Type value.
    +    * @protected
         */
         this.type = Phaser.EMITTER;
     
    @@ -488,140 +482,114 @@ Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) {
         this.height = 1;
     
         /**
    -    * The minimum possible velocity of a particle.
    -    * The default value is (-100,-100).
    -    * @property {Phaser.Point} minParticleSpeed
    +    * @property {Phaser.Point} minParticleSpeed - The minimum possible velocity of a particle.
    +    * @default
         */
         this.minParticleSpeed = new Phaser.Point(-100, -100);
     
         /**
    -    * The maximum possible velocity of a particle.
    -    * The default value is (100,100).
    -    * @property {Phaser.Point} maxParticleSpeed
    +    * @property {Phaser.Point} maxParticleSpeed - The maximum possible velocity of a particle.
    +    * @default
         */
         this.maxParticleSpeed = new Phaser.Point(100, 100);
     
         /**
    -    * The minimum possible scale of a particle.
    -    * The default value is 1.
    -    * @property {number} minParticleScale
    +    * @property {number} minParticleScale - The minimum possible scale of a particle.
         * @default
         */
         this.minParticleScale = 1;
     
         /**
    -    * The maximum possible scale of a particle.
    -    * The default value is 1.
    -    * @property {number} maxParticleScale
    +    * @property {number} maxParticleScale - The maximum possible scale of a particle.
         * @default
         */
         this.maxParticleScale = 1;
     
         /**
    -    * The minimum possible angular velocity of a particle.  The default value is -360.
    -    * @property {number} minRotation
    +    * @property {number} minRotation - The minimum possible angular velocity of a particle.
         * @default
         */
         this.minRotation = -360;
     
         /**
    -    * The maximum possible angular velocity of a particle.  The default value is 360.
    -    * @property {number} maxRotation
    +    * @property {number} maxRotation - The maximum possible angular velocity of a particle.
         * @default
         */
         this.maxRotation = 360;
     
         /**
    -    * Sets the <code>gravity.y</code> of each particle to this value on launch.
    -    * @property {number} gravity
    +    * @property {number} gravity - Sets the `body.gravity.y` of each particle sprite to this value on launch.
         * @default
         */
    -    this.gravity = 2;
    +    this.gravity = 100;
     
         /**
    -    * Set your own particle class type here.
    -    * @property {Description} particleClass
    +    * @property {any} particleClass - For emitting your own particle class types.
         * @default
         */
         this.particleClass = null;
     
         /**
    -    * The X and Y drag component of particles launched from the emitter.
    -    * @property {Phaser.Point} particleDrag
    +    * @property {number} particleFriction - The friction component of particles launched from the emitter.
    +    * @default
         */
    -    this.particleDrag = new Phaser.Point();
    +    this.particleFriction = 0;
     
         /**
    -    * The angular drag component of particles launched from the emitter if they are rotating.
    -    * @property {number} angularDrag
    +    * @property {number} angularDrag - The angular drag component of particles launched from the emitter if they are rotating.
         * @default
         */
         this.angularDrag = 0;
     
         /**
    -    * How often a particle is emitted in ms (if emitter is started with Explode === false).
    -    * @property {boolean} frequency
    +    * @property {boolean} frequency - How often a particle is emitted in ms (if emitter is started with Explode === false).
         * @default
         */
         this.frequency = 100;
     
         /**
    -    * How long each particle lives once it is emitted in ms. Default is 2 seconds.
    -    * Set lifespan to 'zero' for particles to live forever.
    -    * @property {number} lifespan
    +    * @property {number} lifespan - How long each particle lives once it is emitted in ms. Default is 2 seconds. Set lifespan to 'zero' for particles to live forever.
         * @default
         */
         this.lifespan = 2000;
     
         /**
    -    * How much each particle should bounce on each axis.  1 = full bounce, 0 = no bounce.
    -    * @property {Phaser.Point} bounce
    +    * @property {Phaser.Point} bounce - How much each particle should bounce on each axis.  1 = full bounce, 0 = no bounce.
         */
         this.bounce = new Phaser.Point();
     
         /**
    -    * Internal helper for deciding how many particles to launch.
    -    * @property {number} _quantity
    +    * @property {number} _quantity - Internal helper for deciding how many particles to launch.
         * @private
    -    * @default
         */
         this._quantity = 0;
     
         /**
    -    * Internal helper for deciding when to launch particles or kill them.
    -    * @property {number} _timer
    +    * @property {number} _timer - Internal helper for deciding when to launch particles or kill them.
         * @private
    -    * @default
         */
         this._timer = 0;
     
         /**
    -    * Internal counter for figuring out how many particles to launch.
    -    * @property {number} _counter
    +    * @property {number} _counter - Internal counter for figuring out how many particles to launch.
         * @private
    -    * @default
         */
         this._counter = 0;
     
         /**
    -    * Internal helper for the style of particle emission (all at once, or one at a time).
    -    * @property {boolean} _explode
    +    * @property {boolean} _explode - Internal helper for the style of particle emission (all at once, or one at a time).
         * @private
    -    * @default
         */
         this._explode = true;
     
         /**
    -    * Determines whether the emitter is currently emitting particles.
    -    * It is totally safe to directly toggle this.
    -    * @property {boolean} on
    +    * @property {boolean} on - Determines whether the emitter is currently emitting particles. It is totally safe to directly toggle this.
         * @default
         */
         this.on = false;
     
         /**
    -    * Determines whether the emitter is being updated by the core game loop.
    -    * @property {boolean} exists
    +    * @property {boolean} exists - Determines whether the emitter is being updated by the core game loop.
         * @default
         */
         this.exists = true;
    @@ -695,43 +663,35 @@ Phaser.Particles.Arcade.Emitter.prototype.update = function () {
     * This function generates a new array of particle sprites to attach to the emitter.
     *
     * @method Phaser.Particles.Arcade.Emitter#makeParticles
    -* @param {Description} keys - Description.
    -* @param {number} frames - Description.
    -* @param {number} quantity - The number of particles to generate when using the "create from image" option.
    -* @param {number} collide - Description.
    -* @param {boolean} collideWorldBounds - Description.
    -* @return This Emitter instance (nice for chaining stuff together, if you're into that).
    +* @param {array|string} keys - A string or an array of strings that the particle sprites will use as their texture. If an array one is picked at random.
    +* @param {array|number} frames - A frame number, or array of frames that the sprite will use. If an array one is picked at random.
    +* @param {number} quantity - The number of particles to generate.
    +* @param {boolean} [collide=false] - Sets the checkCollision.none flag on the particle sprites body.
    +* @param {boolean} [collideWorldBounds=false] - A particle can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World.
    +* @return {Phaser.Particles.Arcade.Emitter} This Emitter instance.
     */
     Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames, quantity, collide, collideWorldBounds) {
     
    -    if (typeof frames == 'undefined')
    -    {
    -        frames = 0;
    -    }
    -
    -    quantity = quantity || this.maxParticles;
    -    collide = collide || 0;
    -
    -    if (typeof collideWorldBounds == 'undefined')
    -    {
    -        collideWorldBounds = false;
    -    }
    +    if (typeof frames === 'undefined') { frames = 0; }
    +    if (typeof quantity === 'undefined') { quantity = this.maxParticles; }
    +    if (typeof collide === 'undefined') { collide = false; }
    +    if (typeof collideWorldBounds === 'undefined') { collideWorldBounds = false; }
     
         var particle;
         var i = 0;
         var rndKey = keys;
    -    var rndFrame = 0;
    +    var rndFrame = frames;
     
         while (i < quantity)
         {
    -        if (this.particleClass == null)
    +        if (this.particleClass === null)
             {
    -            if (typeof keys == 'object')
    +            if (typeof keys === 'object')
                 {
                     rndKey = this.game.rnd.pick(keys);
                 }
     
    -            if (typeof frames == 'object')
    +            if (typeof frames === 'object')
                 {
                     rndFrame = this.game.rnd.pick(frames);
                 }
    @@ -743,14 +703,14 @@ Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames
                 // particle = new this.particleClass(this.game);
             // }
     
    -        if (collide > 0)
    +        if (collide)
             {
    -            particle.body.allowCollision.any = true;
    -            particle.body.allowCollision.none = false;
    +            particle.body.checkCollision.any = true;
    +            particle.body.checkCollision.none = false;
             }
             else
             {
    -            particle.body.allowCollision.none = true;
    +            particle.body.checkCollision.none = true;
             }
     
             particle.body.collideWorldBounds = collideWorldBounds;
    @@ -770,9 +730,9 @@ Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames
     }
     
     /**
    - * Call this function to turn off all the particles and the emitter.
    - * @method Phaser.Particles.Arcade.Emitter#kill
    - */
    +* Call this function to turn off all the particles and the emitter.
    +* @method Phaser.Particles.Arcade.Emitter#kill
    +*/
     Phaser.Particles.Arcade.Emitter.prototype.kill = function () {
     
         this.on = false;
    @@ -782,10 +742,9 @@ Phaser.Particles.Arcade.Emitter.prototype.kill = function () {
     }
     
     /**
    - * Handy for bringing game objects "back to life". Just sets alive and exists back to true.
    - * In practice, this is most often called by <code>Object.reset()</code>.
    - * @method Phaser.Particles.Arcade.Emitter#revive
    - */
    +* Handy for bringing game objects "back to life". Just sets alive and exists back to true.
    +* @method Phaser.Particles.Arcade.Emitter#revive
    +*/
     Phaser.Particles.Arcade.Emitter.prototype.revive = function () {
     
         this.alive = true;
    @@ -794,27 +753,19 @@ Phaser.Particles.Arcade.Emitter.prototype.revive = function () {
     }
     
     /**
    - * Call this function to start emitting particles.
    - * @method Phaser.Particles.Arcade.Emitter#start
    - * @param {boolean} explode - Whether the particles should all burst out at once.
    - * @param {number} lifespan - How long each particle lives once emitted. 0 = forever.
    - * @param {number} frequency - Ignored if Explode is set to true. Frequency is how often to emit a particle in ms.
    - * @param {number} quantity - How many particles to launch. 0 = "all of the particles".
    - */
    +* Call this function to start emitting particles.
    +* @method Phaser.Particles.Arcade.Emitter#start
    +* @param {boolean} [explode=true] - Whether the particles should all burst out at once.
    +* @param {number} [lifespan=0] - How long each particle lives once emitted. 0 = forever.
    +* @param {number} [frequency=250] - Ignored if Explode is set to true. Frequency is how often to emit a particle in ms.
    +* @param {number} [quantity=0] - How many particles to launch. 0 = "all of the particles".
    +*/
     Phaser.Particles.Arcade.Emitter.prototype.start = function (explode, lifespan, frequency, quantity) {
     
    -    if (typeof explode !== 'boolean')
    -    {
    -        explode = true;
    -    }
    -
    -    lifespan = lifespan || 0;
    -
    -    //  How many ms between emissions?
    -    frequency = frequency || 250;
    -
    -    //  Total number of particles to emit
    -    quantity = quantity || 0;
    +    if (typeof explode === 'undefined') { explode = true; }
    +    if (typeof lifespan === 'undefined') { lifespan = 0; }
    +    if (typeof frequency === 'undefined') { frequency = 250; }
    +    if (typeof quantity === 'undefined') { quantity = 0; }
     
         this.revive();
     
    @@ -840,9 +791,9 @@ Phaser.Particles.Arcade.Emitter.prototype.start = function (explode, lifespan, f
     }
     
     /**
    - * This function can be used both internally and externally to emit the next particle.
    - * @method Phaser.Particles.Arcade.Emitter#emitParticle
    - */
    +* This function can be used both internally and externally to emit the next particle.
    +* @method Phaser.Particles.Arcade.Emitter#emitParticle
    +*/
     Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () {
     
         var particle = this.getFirstExists(false);
    @@ -900,8 +851,7 @@ Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () {
             particle.scale.setTo(scale, scale);
         }
     
    -    particle.body.drag.x = this.particleDrag.x;
    -    particle.body.drag.y = this.particleDrag.y;
    +    particle.body.friction = this.particleFriction;
         particle.body.angularDrag = this.angularDrag;
     
     }
    @@ -909,8 +859,8 @@ Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () {
     /**
     * A more compact way of setting the width and height of the emitter.
     * @method Phaser.Particles.Arcade.Emitter#setSize
    -* @param  {number} width - The desired width of the emitter (particles are spawned randomly within these dimensions).
    -* @param  {number} height - The desired height of the emitter.
    +* @param {number} width - The desired width of the emitter (particles are spawned randomly within these dimensions).
    +* @param {number} height - The desired height of the emitter.
     */
     Phaser.Particles.Arcade.Emitter.prototype.setSize = function (width, height) {
     
    @@ -922,8 +872,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setSize = function (width, height) {
     /**
     * A more compact way of setting the X velocity range of the emitter.
     * @method Phaser.Particles.Arcade.Emitter#setXSpeed
    -* @param  {number} min - The minimum value for this range.
    -* @param  {number} max - The maximum value for this range.
    +* @param {number} [min=0] - The minimum value for this range.
    +* @param {number} [max=0] - The maximum value for this range.
     */
     Phaser.Particles.Arcade.Emitter.prototype.setXSpeed = function (min, max) {
     
    @@ -938,8 +888,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setXSpeed = function (min, max) {
     /**
     * A more compact way of setting the Y velocity range of the emitter.
     * @method Phaser.Particles.Arcade.Emitter#setYSpeed
    -* @param  {number} min - The minimum value for this range.
    -* @param  {number} max - The maximum value for this range.
    +* @param {number} [min=0] - The minimum value for this range.
    +* @param {number} [max=0] - The maximum value for this range.
     */
     Phaser.Particles.Arcade.Emitter.prototype.setYSpeed = function (min, max) {
     
    @@ -954,8 +904,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setYSpeed = function (min, max) {
     /**
     * A more compact way of setting the angular velocity constraints of the emitter.
     * @method Phaser.Particles.Arcade.Emitter#setRotation
    -* @param {number} min -  The minimum value for this range.
    -* @param {number} max -  The maximum value for this range.
    +* @param {number} [min=0] - The minimum value for this range.
    +* @param {number} [max=0] - The maximum value for this range.
     */
     Phaser.Particles.Arcade.Emitter.prototype.setRotation = function (min, max) {
     
    @@ -968,14 +918,17 @@ Phaser.Particles.Arcade.Emitter.prototype.setRotation = function (min, max) {
     }
     
     /**
    -* Change the emitter's midpoint to match the midpoint of a <code>Object</code>.
    +* Change the emitters center to match the center of any object with a `center` property, such as a Sprite.
     * @method Phaser.Particles.Arcade.Emitter#at
    -* @param  {object} object - The <code>Object</code> that you want to sync up with.
    +* @param {object|Phaser.Sprite} object - The object that you wish to match the center with.
     */
     Phaser.Particles.Arcade.Emitter.prototype.at = function (object) {
     
    -    this.emitX = object.center.x;
    -    this.emitY = object.center.y;
    +    if (object.center)
    +    {
    +        this.emitX = object.center.x;
    +        this.emitY = object.center.y;
    +    }
     
     }
     
    @@ -1111,13 +1064,13 @@ Object.defineProperty(Phaser.Particles.Arcade.Emitter.prototype, "bottom", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Events.js.html b/docs/Events.js.html index b49c7657..0e77e3f9 100644 --- a/docs/Events.js.html +++ b/docs/Events.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -447,6 +441,7 @@
     Phaser.Events = function (sprite) {
         
         this.parent = sprite;
    +
         this.onAddedToGroup = new Phaser.Signal();
         this.onRemovedFromGroup = new Phaser.Signal();
         this.onKilled = new Phaser.Signal();
    @@ -464,6 +459,9 @@ Phaser.Events = function (sprite) {
         this.onAnimationComplete = null;
         this.onAnimationLoop = null;
     
    +    this.onBeginContact = null;
    +    this.onEndContact = null;
    +
     };
     
     Phaser.Events.prototype = {
    @@ -496,7 +494,10 @@ Phaser.Events.prototype = {
     
         }
     
    -};
    +}; + +Phaser.Events.prototype.constructor = Phaser.Events; +
    @@ -511,13 +512,13 @@ Phaser.Events.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Filter.js.html b/docs/Filter.js.html index 32d52126..b187003d 100644 --- a/docs/Filter.js.html +++ b/docs/Filter.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -475,9 +469,9 @@ Phaser.Filter = function (game, uniforms, fragmentSrc) {
         */
         this.uniforms = {
     
    -        resolution: { type: '3f', value: { x: 256, y: 256, z: 0 }},
             time: { type: '1f', value: 0 },
    -        mouse: { type: '4f', value: { x: 0, y: 0, z: 0, w: 0 }}
    +        resolution: { type: '2f', value: { x: 256, y: 256 }},
    +        mouse: { type: '2f', value: { x: 0.0, y: 0.0 }}
     
         };
         
    @@ -520,8 +514,15 @@ Phaser.Filter.prototype = {
     
             if (typeof pointer !== 'undefined')
             {
    -            this.uniforms.mouse.x = pointer.x;
    -            this.uniforms.mouse.y = pointer.y;
    +            if (pointer.x > 0)
    +            {
    +                this.uniforms.mouse.x = pointer.x.toFixed(2);
    +            }
    +
    +            if (pointer.y > 0)
    +            {
    +                this.uniforms.mouse.y = pointer.y.toFixed(2);
    +            }
             }
     
             this.uniforms.time.value = this.game.time.totalElapsedSeconds();
    @@ -540,6 +541,8 @@ Phaser.Filter.prototype = {
     
     };
     
    +Phaser.Filter.prototype.constructor = Phaser.Filter;
    +
     /**
     * @name Phaser.Filter#width
     * @property {number} width - The width (resolution uniform)
    @@ -586,13 +589,13 @@ Object.defineProperty(Phaser.Filter.prototype, 'height', {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Frame.js.html b/docs/Frame.js.html index 85be511e..56b5e93c 100644 --- a/docs/Frame.js.html +++ b/docs/Frame.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -581,6 +575,8 @@ Phaser.Frame.prototype = {
         }
     
     };
    +
    +Phaser.Frame.prototype.constructor = Phaser.Frame;
     
    @@ -596,13 +592,13 @@ Phaser.Frame.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/FrameData.js.html b/docs/FrameData.js.html index da678000..a25b6514 100644 --- a/docs/FrameData.js.html +++ b/docs/FrameData.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -646,6 +640,8 @@ Phaser.FrameData.prototype = {
     
     };
     
    +Phaser.FrameData.prototype.constructor = Phaser.FrameData;
    +
     /**
     * @name Phaser.FrameData#total
     * @property {number} total - The total number of frames in this FrameData set.
    @@ -673,13 +669,13 @@ Object.defineProperty(Phaser.FrameData.prototype, "total", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Game.js.html b/docs/Game.js.html index 1bb2ffda..b075f156 100644 --- a/docs/Game.js.html +++ b/docs/Game.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -440,64 +434,68 @@
     * @param {number} [width=800] - The width of your game in game pixels.
     * @param {number} [height=600] - The height of your game in game pixels.
     * @param {number} [renderer=Phaser.AUTO] - Which renderer to use: Phaser.AUTO will auto-detect, Phaser.WEBGL, Phaser.CANVAS or Phaser.HEADLESS (no rendering at all).
    -* @param {HTMLElement} [parent=''] - The Games DOM parent.
    -* @param {any} [state=null] - Description.
    +* @param {string|HTMLElement} [parent=''] - The DOM element into which this games canvas will be injected. Either a DOM ID (string) or the element itself.
    +* @param {object} [state=null] - The default state object. A object consisting of Phaser.State functions (preload, create, update, render) or null.
     * @param {boolean} [transparent=false] - Use a transparent canvas background or not.
     * @param  {boolean} [antialias=true] - Anti-alias graphics.
     */
     Phaser.Game = function (width, height, renderer, parent, state, transparent, antialias) {
     
    -    width = width || 800;
    -    height = height || 600;
    -    renderer = renderer || Phaser.AUTO;
    -    parent = parent || '';
    -    state = state || null;
    -
    -    if (typeof transparent == 'undefined') { transparent = false; }
    -    if (typeof antialias == 'undefined') { antialias = true; }
    -
         /**
         * @property {number} id - Phaser Game ID (for when Pixi supports multiple instances).
         */
         this.id = Phaser.GAMES.push(this) - 1;
     
         /**
    -    * @property {HTMLElement} parent - The Games DOM parent.
    +    * @property {object} config - The Phaser.Game configuration object.
         */
    -    this.parent = parent;
    +    this.config = null;
     
    -    //  Do some more intelligent size parsing here, so they can set "100%" for example, maybe pass the scale mode in here too?
    +    /**
    +    * @property {HTMLElement} parent - The Games DOM parent.
    +    * @default
    +    */
    +    this.parent = '';
     
         /**
         * @property {number} width - The Game width (in pixels).
    +    * @default
         */
    -    this.width = width;
    +    this.width = 800;
     
         /**
         * @property {number} height - The Game height (in pixels).
    +    * @default
         */
    -    this.height = height;
    +    this.height = 600;
     
         /**
         * @property {boolean} transparent - Use a transparent canvas background or not.
    +    * @default
         */
    -    this.transparent = transparent;
    +    this.transparent = false;
     
         /**
         * @property {boolean} antialias - Anti-alias graphics (in WebGL this helps with edges, in Canvas2D it retains pixel-art quality).
    +    * @default
         */
    -    this.antialias = antialias;
    +    this.antialias = true;
     
         /**
         * @property {number} renderer - The Pixi Renderer
         * @default
         */
    -    this.renderer = null;
    +    this.renderer = Phaser.AUTO;
    +
    +    /**
    +    * @property {number} renderType - The Renderer this Phaser.Game will use. Either Phaser.RENDERER_AUTO, Phaser.RENDERER_CANVAS or Phaser.RENDERER_WEBGL.
    +    */
    +    this.renderType = Phaser.AUTO;
     
         /**
         * @property {number} state - The StateManager.
         */
    -    this.state = new Phaser.StateManager(this, state);
    +    this.state = null;
     
         /**
         * @property {boolean} _paused - Is game paused?
    @@ -506,11 +504,6 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant
         */
         this._paused = false;
     
    -    /**
    -    * @property {number} renderType - The Renderer this Phaser.Game will use. Either Phaser.RENDERER_AUTO, Phaser.RENDERER_CANVAS or Phaser.RENDERER_WEBGL.
    -    */
    -    this.renderType = renderer;
    -
         /**
         * @property {boolean} _loadComplete - Whether load complete loading or not.
         * @private
    @@ -650,6 +643,68 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant
         */
         this.particles = null;
     
    +    /**
    +    * @property {boolean} stepping - Enable core loop stepping with Game.enableStep().
    +    * @default
    +    * @readonly
    +    */
    +    this.stepping = false;
    +
    +    /**
    +    * @property {boolean} stepping - An internal property used by enableStep, but also useful to query from your own game objects.
    +    * @default
    +    * @readonly
    +    */
    +    this.pendingStep = false;
    +
    +    /**
    +    * @property {number} stepCount - When stepping is enabled this contains the current step cycle.
    +    * @default
    +    * @readonly
    +    */
    +    this.stepCount = 0;
    +
    +    //  Parse the configuration object (if any)
    +    if (arguments.length === 1 && typeof arguments[0] === 'object')
    +    {
    +        this.parseConfig(arguments[0]);
    +    }
    +    else
    +    {
    +        if (typeof width !== 'undefined')
    +        {
    +            this.width = width;
    +        }
    +
    +        if (typeof height !== 'undefined')
    +        {
    +            this.height = height;
    +        }
    +
    +        if (typeof renderer !== 'undefined')
    +        {
    +            this.renderer = renderer;
    +            this.renderType = renderer;
    +        }
    +
    +        if (typeof parent !== 'undefined')
    +        {
    +            this.parent = parent;
    +        }
    +
    +        if (typeof transparent !== 'undefined')
    +        {
    +            this.transparent = transparent;
    +        }
    +
    +        if (typeof antialias !== 'undefined')
    +        {
    +            this.antialias = antialias;
    +        }
    +
    +        this.state = new Phaser.StateManager(this, state);
    +    }
    +
         var _this = this;
     
         this._onBoot = function () {
    @@ -672,6 +727,99 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant
     
     Phaser.Game.prototype = {
     
    +    /**
    +    * Parses a Game configuration object.
    +    *
    +    * @method Phaser.Game#parseConfig
    +    * @protected
    +    */
    +    parseConfig: function (config) {
    +
    +        this.config = config;
    +
    +        if (config['width'])
    +        {
    +            this.width = this.parseDimension(config['width'], 0);
    +        }
    +
    +        if (config['height'])
    +        {
    +            this.height = this.parseDimension(config['height'], 1);
    +        }
    +
    +        if (config['renderer'])
    +        {
    +            this.renderer = config['renderer'];
    +            this.renderType = config['renderer'];
    +        }
    +
    +        if (config['parent'])
    +        {
    +            this.parent = config['parent'];
    +        }
    +
    +        if (config['transparent'])
    +        {
    +            this.transparent = config['transparent'];
    +        }
    +
    +        if (config['antialias'])
    +        {
    +            this.antialias = config['antialias'];
    +        }
    +
    +        var state = null;
    +
    +        if (config['state'])
    +        {
    +            state = config['state'];
    +        }
    +
    +        this.state = new Phaser.StateManager(this, state);
    +
    +    },
    +
    +    /**
    +    * Get dimension.
    +    *
    +    * @method Phaser.Game#parseDimension
    +    * @protected
    +    */
    +    parseDimension: function (size, dimension) {
    +
    +        var f = 0;
    +        var px = 0;
    +
    +        if (typeof size === 'string')
    +        {
    +            //  %?
    +            if (size.substr(-1) === '%')
    +            {
    +                f = parseInt(size, 10) / 100;
    +
    +                if (dimension === 0)
    +                {
    +                    px = window.innerWidth * f;
    +                }
    +                else
    +                {
    +                    px = window.innerHeight * f;
    +                }
    +            }
    +            else
    +            {
    +                px = parseInt(size, 10);
    +            }
    +        }
    +        else
    +        {
    +            px = size;
    +        }
    +
    +        return px;
    +
    +    },
    +
         /**
         * Initialize engine sub modules and start the game.
         *
    @@ -721,6 +869,7 @@ Phaser.Game.prototype = {
                 this.net = new Phaser.Net(this);
                 this.debug = new Phaser.Utils.Debug(this);
     
    +            this.time.boot();
                 this.stage.boot();
                 this.world.boot();
                 this.input.boot();
    @@ -795,6 +944,14 @@ Phaser.Game.prototype = {
         */
         setUpRenderer: function () {
     
    +        /*
    +        if (this.device.trident)
    +        {
    +            //  Pixi WebGL renderer on IE11 doesn't work correctly with masks, if you need them you may want to comment this block out
    +            this.renderType = Phaser.CANVAS;
    +        }
    +        */
    +
             if (this.renderType === Phaser.HEADLESS || this.renderType === Phaser.CANVAS || (this.renderType === Phaser.AUTO && this.device.webGL === false))
             {
                 if (this.device.canvas)
    @@ -861,20 +1018,28 @@ Phaser.Game.prototype = {
             }
             else
             {
    -            this.plugins.preUpdate();
    -            this.physics.preUpdate();
    +            if (!this.pendingStep)
    +            {
    +                if (this.stepping)
    +                {
    +                    this.pendingStep = true;
    +                }
     
    -            this.stage.update();
    -            this.input.update();
    -            this.tweens.update();
    -            this.sound.update();
    -            this.world.update();
    -            this.particles.update();
    -            this.state.update();
    -            this.plugins.update();
    +                this.plugins.preUpdate();
    +                this.world.preUpdate();
     
    -            this.world.postUpdate();
    -            this.plugins.postUpdate();
    +                this.stage.update();
    +                this.tweens.update();
    +                this.sound.update();
    +                this.input.update();
    +                this.state.update();
    +                this.world.update();
    +                this.particles.update();            
    +                this.plugins.update();
    +
    +                this.world.postUpdate();
    +                this.plugins.postUpdate();
    +            }
     
                 if (this.renderType !== Phaser.HEADLESS)
                 {
    @@ -884,11 +1049,49 @@ Phaser.Game.prototype = {
     
                     this.plugins.postRender();
                 }
    -
             }
     
         },
     
    +    /**
    +    * Enable core game loop stepping. When enabled you must call game.step() directly (perhaps via a DOM button?)
    +    * Calling step will advance the game loop by one frame. This is extremely useful to hard to track down errors!
    +    *
    +    * @method Phaser.Game#enableStep
    +    */
    +    enableStep: function () {
    +
    +        this.stepping = true;
    +        this.pendingStep = false;
    +        this.stepCount = 0;
    +
    +    },
    +
    +    /**
    +    * Disables core game loop stepping.
    +    *
    +    * @method Phaser.Game#disableStep
    +    */
    +    disableStep: function () {
    +
    +        this.stepping = false;
    +        this.pendingStep = false;
    +
    +    },
    +
    +    /**
    +    * When stepping is enabled you must call this function directly (perhaps via a DOM button?) to advance the game loop by one frame.
    +    * This is extremely useful to hard to track down errors! Use the internal stepCount property to monitor progress.
    +    *
    +    * @method Phaser.Game#step
    +    */
    +    step: function () {
    +
    +        this.pendingStep = false;
    +        this.stepCount++;
    +
    +    },
    +
         /**
         * Nuke the entire game from orbit
         *
    @@ -916,6 +1119,8 @@ Phaser.Game.prototype = {
     
     };
     
    +Phaser.Game.prototype.constructor = Phaser.Game;
    +
     /**
     * The paused state of the Game. A paused game doesn't update any of its subsystems.
     * When a game is paused the onPause event is dispatched. When it is resumed the onResume event is dispatched.
    @@ -969,13 +1174,13 @@ Object.defineProperty(Phaser.Game.prototype, "paused", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/GameObjectFactory.js.html b/docs/GameObjectFactory.js.html index d5083241..8665cdb7 100644 --- a/docs/GameObjectFactory.js.html +++ b/docs/GameObjectFactory.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -470,15 +464,19 @@ Phaser.GameObjectFactory.prototype = {
         * @param {number} y - Y position of the new sprite.
         * @param {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture.
         * @param {string|number} [frame] - If the sprite uses an image from a texture atlas or sprite sheet you can pass the frame here. Either a number for a frame ID or a string for a frame name.
    +    * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group.
         * @returns {Phaser.Sprite} the newly created sprite object.
         */
    -    sprite: function (x, y, key, frame) {
    +    sprite: function (x, y, key, frame, group) {
     
    -        return this.world.create(x, y, key, frame);
    +        if (typeof group === 'undefined') { group = this.world; }
    +
    +        return group.create(x, y, key, frame);
     
         },
     
         /**
    +    * DEPRECATED - will be removed in Phaser 1.2
         * Create a new Sprite with specific position and sprite sheet key that will automatically be added as a child of the given parent.
         *
         * @method Phaser.GameObjectFactory#child
    @@ -512,8 +510,8 @@ Phaser.GameObjectFactory.prototype = {
         * A Group is a container for display objects that allows for fast pooling, recycling and collision checks.
         *
         * @method Phaser.GameObjectFactory#group
    -    * @param {*} parent - The parent Group or DisplayObjectContainer that will hold this group, if any.
    -    * @param {string} [name=group] - A name for this Group. Not used internally but useful for debugging.
    +    * @param {any} parent - The parent Group or DisplayObjectContainer that will hold this group, if any.
    +    * @param {string} [name='group'] - A name for this Group. Not used internally but useful for debugging.
         * @return {Phaser.Group} The newly created group.
         */
         group: function (parent, name) {
    @@ -523,7 +521,7 @@ Phaser.GameObjectFactory.prototype = {
         },
     
         /**
    -    * Creates a new instance of the Sound class.
    +    * Creates a new Sound object.
         *
         * @method Phaser.GameObjectFactory#audio
         * @param {string} key - The Game.cache key of the sound that this object will use.
    @@ -539,7 +537,23 @@ Phaser.GameObjectFactory.prototype = {
         },
     
         /**
    -    * Creates a new <code>TileSprite</code>.
    +    * Creates a new Sound object.
    +    *
    +    * @method Phaser.GameObjectFactory#sound
    +    * @param {string} key - The Game.cache key of the sound that this object will use.
    +    * @param {number} [volume=1] - The volume at which the sound will be played.
    +    * @param {boolean} [loop=false] - Whether or not the sound will loop.
    +    * @param {boolean} [connect=true] - Controls if the created Sound object will connect to the master gainNode of the SoundManager when running under WebAudio.
    +    * @return {Phaser.Sound} The newly created text object.
    +    */
    +    sound: function (key, volume, loop, connect) {
    +
    +        return this.game.sound.add(key, volume, loop, connect);
    +        
    +    },
    +
    +    /**
    +    * Creates a new TileSprite object.
         *
         * @method Phaser.GameObjectFactory#tileSprite
         * @param {number} x - X position of the new tileSprite.
    @@ -547,33 +561,38 @@ Phaser.GameObjectFactory.prototype = {
         * @param {number} width - the width of the tilesprite.
         * @param {number} height - the height of the tilesprite.
         * @param {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture.
    -    * @param {string|number} frame - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
    +    * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group.
         * @return {Phaser.TileSprite} The newly created tileSprite object.
         */
    -    tileSprite: function (x, y, width, height, key, frame) {
    +    tileSprite: function (x, y, width, height, key, group) {
     
    -        return this.world.add(new Phaser.TileSprite(this.game, x, y, width, height, key, frame));
    +        if (typeof group === 'undefined') { group = this.world; }
    +
    +        return group.add(new Phaser.TileSprite(this.game, x, y, width, height, key));
     
         },
     
         /**
    -    * Creates a new <code>Text</code>.
    +    * Creates a new Text object.
         *
         * @method Phaser.GameObjectFactory#text
         * @param {number} x - X position of the new text object.
         * @param {number} y - Y position of the new text object.
         * @param {string} text - The actual text that will be written.
         * @param {object} style - The style object containing style attributes like font, font size , etc.
    +    * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group.
         * @return {Phaser.Text} The newly created text object.
         */
    -    text: function (x, y, text, style) {
    +    text: function (x, y, text, style, group) {
     
    -        return this.world.add(new Phaser.Text(this.game, x, y, text, style));
    +        if (typeof group === 'undefined') { group = this.world; }
    +
    +        return group.add(new Phaser.Text(this.game, x, y, text, style));
     
         },
     
         /**
    -    * Creates a new <code>Button</code> object.
    +    * Creates a new Button object.
         *
         * @method Phaser.GameObjectFactory#button
         * @param {number} [x] X position of the new button object.
    @@ -584,25 +603,32 @@ Phaser.GameObjectFactory.prototype = {
         * @param {string|number} [overFrame] This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name.
         * @param {string|number} [outFrame] This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name.
         * @param {string|number} [downFrame] This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name.
    +    * @param {string|number} [upFrame] This is the frame or frameName that will be set when this button is in an up state. Give either a number to use a frame ID or a string for a frame name.
    +    * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group.
         * @return {Phaser.Button} The newly created button object.
         */
    -    button: function (x, y, key, callback, callbackContext, overFrame, outFrame, downFrame) {
    +    button: function (x, y, key, callback, callbackContext, overFrame, outFrame, downFrame, upFrame, group) {
     
    -        return this.world.add(new Phaser.Button(this.game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame));
    +        if (typeof group === 'undefined') { group = this.world; }
    +
    +        return group.add(new Phaser.Button(this.game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame, upFrame));
     
         },
     
         /**
    -    * Creates a new <code>Graphics</code> object.
    +    * Creates a new Graphics object.
         *
         * @method Phaser.GameObjectFactory#graphics
         * @param {number} x - X position of the new graphics object.
         * @param {number} y - Y position of the new graphics object.
    +    * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group.
         * @return {Phaser.Graphics} The newly created graphics object.
         */
    -    graphics: function (x, y) {
    +    graphics: function (x, y, group) {
     
    -        return this.world.add(new Phaser.Graphics(this.game, x, y));
    +        if (typeof group === 'undefined') { group = this.world; }
    +
    +        return group.add(new Phaser.Graphics(this.game, x, y));
     
         },
     
    @@ -624,16 +650,19 @@ Phaser.GameObjectFactory.prototype = {
         },
     
         /**
    -    * * Create a new <code>BitmapText</code>.
    +    * * Create a new BitmapText object.
         *
         * @method Phaser.GameObjectFactory#bitmapText
         * @param {number} x - X position of the new bitmapText object.
         * @param {number} y - Y position of the new bitmapText object.
         * @param {string} text - The actual text that will be written.
         * @param {object} style - The style object containing style attributes like font, font size , etc.
    +    * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group.
         * @return {Phaser.BitmapText} The newly created bitmapText object.
         */
    -    bitmapText: function (x, y, text, style) {
    +    bitmapText: function (x, y, text, style, group) {
    +
    +        if (typeof group === 'undefined') { group = this.world; }
     
             return this.world.add(new Phaser.BitmapText(this.game, x, y, text, style));
     
    @@ -643,41 +672,13 @@ Phaser.GameObjectFactory.prototype = {
         * Creates a new Tilemap object.
         *
         * @method Phaser.GameObjectFactory#tilemap
    -    * @param {string} key - Asset key for the JSON file.
    +    * @param {string} key - Asset key for the JSON or CSV map data in the cache.
    +    * @param {object|string} tilesets - An object mapping Cache.tileset keys with the tileset names in the JSON file. If a string is provided that will be used.
         * @return {Phaser.Tilemap} The newly created tilemap object.
         */
    -    tilemap: function (key) {
    +    tilemap: function (key, tilesets) {
     
    -        return new Phaser.Tilemap(this.game, key);
    -
    -    },
    -
    -    /**
    -    * Creates a new Tileset object.
    -    *
    -    * @method Phaser.GameObjectFactory#tileset
    -    * @param {string} key - The image key as defined in the Game.Cache to use as the tileset.
    -    * @return {Phaser.Tileset} The newly created tileset object.
    -    */
    -    tileset: function (key) {
    -
    -        return this.game.cache.getTileset(key);
    -
    -    },
    -
    -    /**
    -    * Creates a new Tilemap Layer object.
    -    *
    -    * @method Phaser.GameObjectFactory#tilemapLayer
    -    * @param {number} x - X position of the new tilemapLayer.
    -    * @param {number} y - Y position of the new tilemapLayer.
    -    * @param {number} width - the width of the tilemapLayer.
    -    * @param {number} height - the height of the tilemapLayer.
    -    * @return {Phaser.TilemapLayer} The newly created tilemaplayer object.
    -    */
    -    tilemapLayer: function (x, y, width, height, tileset, tilemap, layer) {
    -
    -        return this.world.add(new Phaser.TilemapLayer(this.game, x, y, width, height, tileset, tilemap, layer));
    +        return new Phaser.Tilemap(this.game, key, tilesets);
     
         },
     
    @@ -701,7 +702,7 @@ Phaser.GameObjectFactory.prototype = {
         },
     
         /**
    -    * A BitmapData object which can be manipulated and drawn to like a traditional Canvas object and used to texture Sprites.
    +    * Experimental: A BitmapData object which can be manipulated and drawn to like a traditional Canvas object and used to texture Sprites.
         *
         * @method Phaser.GameObjectFactory#bitmapData
         * @param {number} [width=256] - The width of the BitmapData in pixels.
    @@ -734,7 +735,10 @@ Phaser.GameObjectFactory.prototype = {
     
         }
     
    -};
    +}; + +Phaser.GameObjectFactory.prototype.constructor = Phaser.GameObjectFactory; +
    @@ -749,13 +753,13 @@ Phaser.GameObjectFactory.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Gamepad.js.html b/docs/Gamepad.js.html new file mode 100644 index 00000000..54da0f92 --- /dev/null +++ b/docs/Gamepad.js.html @@ -0,0 +1,1057 @@ + + + + + + Phaser Source: input/Gamepad.js + + + + + + + + + + +
    + + +
    + + +
    + +
    + + + +

    Source: input/Gamepad.js

    + +
    +
    +
    /**
    +* @author       @karlmacklin <tacklemcclean@gmail.com>
    +* @copyright    2014 Photon Storm Ltd.
    +* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
    +*/
    +
    +/**
    +* The Gamepad class handles looking after gamepad input for your game.
    +* Remember to call gamepad.start(); expecting input!
    +*
    +* HTML5 GAMEPAD API SUPPORT IS AT AN EXPERIMENTAL STAGE!
    +* At moment of writing this (end of 2013) only Chrome supports parts of it out of the box. Firefox supports it
    +* via prefs flags (about:config, search gamepad). The browsers map the same controllers differently.
    +* This class has constans for Windows 7 Chrome mapping of
    +* XBOX 360 controller.
    +*
    +* @class Phaser.Gamepad
    +* @constructor
    +* @param {Phaser.Game} game - A reference to the currently running game.
    +*/
    +Phaser.Gamepad = function (game) {
    +
    +    /**
    +    * @property {Phaser.Game} game - Local reference to game.
    +    */
    +    this.game = game;
    +
    +    /**
    +    * @property {Array<Phaser.SinglePad>} _gamepads - The four Phaser Gamepads.
    +    * @private
    +    */
    +    this._gamepads = [
    +        new Phaser.SinglePad(game, this),
    +        new Phaser.SinglePad(game, this),
    +        new Phaser.SinglePad(game, this),
    +        new Phaser.SinglePad(game, this)
    +    ];
    +
    +    /**
    +    * @property {Object} _gamepadIndexMap - Maps the browsers gamepad indices to our Phaser Gamepads
    +    * @private
    +    */
    +    this._gamepadIndexMap = {};
    +
    +    /**
    +    * @property {Array} _rawPads - The raw state of the gamepads from the browser
    +    * @private
    +    */
    +    this._rawPads = [];
    +
    +    /**
    +    * @property {boolean} _active - Private flag for whether or not the API is polled
    +    * @private
    +    * @default
    +    */
    +    this._active = false;
    +
    +    /**
    +    * You can disable all Gamepad Input by setting disabled to true. While true all new input related events will be ignored.
    +    * @property {boolean} disabled - The disabled state of the Gamepad.
    +    * @default
    +    */
    +    this.disabled = false;
    +
    +    /**
    +    * Whether or not gamepads are supported in the current browser. Note that as of Dec. 2013 this check is actually not accurate at all due to poor implementation.
    +    * @property {boolean} _gamepadSupportAvailable - Are gamepads supported in this browser or not?
    +    * @private
    +    */
    +    this._gamepadSupportAvailable = !!navigator.webkitGetGamepads || !!navigator.webkitGamepads || (navigator.userAgent.indexOf('Firefox/') != -1);
    +
    +    /**
    +    * Used to check for differences between earlier polls and current state of gamepads.
    +    * @property {Array} _prevRawGamepadTypes
    +    * @private
    +    * @default
    +    */
    +    this._prevRawGamepadTypes = [];
    +
    +    /**
    +    * Used to check for differences between earlier polls and current state of gamepads.
    +    * @property {Array} _prevTimestamps
    +    * @private
    +    * @default
    +    */
    +    this._prevTimestamps = [];
    +
    +    /**
    +    * @property {Object} callbackContext - The context under which the callbacks are run.
    +    */
    +    this.callbackContext = this;
    +
    +    /**
    +    * @property {function} onConnectCallback - This callback is invoked every time any gamepad is connected
    +    */
    +    this.onConnectCallback = null;
    +
    +    /**
    +    * @property {function} onDisconnectCallback - This callback is invoked every time any gamepad is disconnected
    +    */
    +    this.onDisconnectCallback = null;
    +
    +    /**
    +    * @property {function} onDownCallback - This callback is invoked every time any gamepad button is pressed down.
    +    */
    +    this.onDownCallback = null;
    +
    +    /**
    +    * @property {function} onUpCallback - This callback is invoked every time any gamepad button is released.
    +    */
    +    this.onUpCallback = null;
    +
    +    /**
    +    * @property {function} onAxisCallback - This callback is invoked every time any gamepad axis is changed.
    +    */
    +    this.onAxisCallback = null;
    +
    +    /**
    +    * @property {function} onFloatCallback - This callback is invoked every time any gamepad button is changed to a value where value > 0 and value < 1.
    +    */
    +    this.onFloatCallback = null;
    +
    +    /**
    +    * @property {function} _ongamepadconnected - Private callback for Firefox gamepad connection handling
    +    * @private
    +    */
    +    this._ongamepadconnected = null;
    +
    +    /**
    +    * @property {function} _gamepaddisconnected - Private callback for Firefox gamepad connection handling
    +    * @private
    +    */
    +    this._gamepaddisconnected = null;
    +};
    +
    +Phaser.Gamepad.prototype = {
    +
    +    /**
    +    * Add callbacks to the main Gamepad handler to handle connect/disconnect/button down/button up/axis change/float value buttons
    +    * @method Phaser.Gamepad#addCallbacks
    +    * @param {Object} context - The context under which the callbacks are run.
    +    * @param {Object} callbacks - Object that takes six different callback methods:
    +    * onConnectCallback, onDisconnectCallback, onDownCallback, onUpCallback, onAxisCallback, onFloatCallback
    +    */
    +    addCallbacks: function (context, callbacks) {
    +
    +        if (typeof callbacks !== 'undefined')
    +        {
    +            this.onConnectCallback = (typeof callbacks.onConnect === 'function') ? callbacks.onConnect : this.onConnectCallback;
    +            this.onDisconnectCallback = (typeof callbacks.onDisconnect === 'function') ? callbacks.onDisconnect : this.onDisconnectCallback;
    +            this.onDownCallback = (typeof callbacks.onDown === 'function') ? callbacks.onDown : this.onDownCallback;
    +            this.onUpCallback = (typeof callbacks.onUp === 'function') ? callbacks.onUp : this.onUpCallback;
    +            this.onAxisCallback = (typeof callbacks.onAxis === 'function') ? callbacks.onAxis : this.onAxisCallback;
    +            this.onFloatCallback = (typeof callbacks.onFloat === 'function') ? callbacks.onFloat : this.onFloatCallback;
    +        }
    +
    +    },
    +
    +    /**
    +    * Starts the Gamepad event handling.
    +    * This MUST be called manually before Phaser will start polling the Gamepad API.
    +    *
    +    * @method Phaser.Gamepad#start
    +    */
    +    start: function () {
    +
    +        this._active = true;
    +        var _this = this;
    +
    +        this._ongamepadconnected = function(event) {
    +            var newPad = event.gamepad;
    +            _this._rawPads.push(newPad);
    +            _this._gamepads[newPad.index].connect(newPad);
    +        };
    +
    +        window.addEventListener('gamepadconnected', this._ongamepadconnected, false);
    +
    +        this._ongamepaddisconnected = function(event) {
    +
    +            var removedPad = event.gamepad;
    +
    +            for (var i in _this._rawPads)
    +            {
    +                if (_this._rawPads[i].index === removedPad.index)
    +                {
    +                    _this._rawPads.splice(i,1);
    +                }
    +            }
    +            _this._gamepads[removedPad.index].disconnect();
    +        };
    +
    +        window.addEventListener('gamepaddisconnected', this._ongamepaddisconnected, false);
    +
    +    },
    +
    +    /**
    +    * Main gamepad update loop. Should not be called manually.
    +    * @method Phaser.Gamepad#update
    +    * @private
    +    */
    +    update: function () {
    +
    +        this._pollGamepads();
    +
    +        for (var i = 0; i < this._gamepads.length; i++)
    +        {
    +            if (this._gamepads[i]._connected)
    +            {
    +                this._gamepads[i].pollStatus();
    +            }
    +        }
    +
    +    },
    +
    +    /**
    +    * Updating connected gamepads (for Google Chrome).
    +    * Should not be called manually.
    +    * @method Phaser.Gamepad#_pollGamepads
    +    * @private
    +    */
    +    _pollGamepads: function () {
    +
    +        var rawGamepads = (navigator.webkitGetGamepads && navigator.webkitGetGamepads()) || navigator.webkitGamepads;
    +
    +        if (rawGamepads)
    +        {
    +            this._rawPads = [];
    +
    +            var gamepadsChanged = false;
    +
    +            for (var i = 0; i < rawGamepads.length; i++)
    +            {
    +                if (typeof rawGamepads[i] !== this._prevRawGamepadTypes[i])
    +                {
    +                    gamepadsChanged = true;
    +                    this._prevRawGamepadTypes[i] = typeof rawGamepads[i];
    +                }
    +
    +                if (rawGamepads[i])
    +                {
    +                    this._rawPads.push(rawGamepads[i]);
    +                }
    +
    +                // Support max 4 pads at the moment
    +                if (i === 3)
    +                {
    +                    break;
    +                }
    +            }
    +
    +            if (gamepadsChanged)
    +            {
    +                var validConnections = { rawIndices: {}, padIndices: {} };
    +                var singlePad;
    +
    +                for (var j = 0; j < this._gamepads.length; j++)
    +                {
    +                    singlePad = this._gamepads[j];
    +
    +                    if (singlePad.connected)
    +                    {
    +                        for (var k = 0; k < this._rawPads.length; k++)
    +                        {
    +                            if (this._rawPads[k].index === singlePad.index)
    +                            {
    +                                validConnections.rawIndices[singlePad.index] = true;
    +                                validConnections.padIndices[j] = true;
    +                            }
    +                        }
    +                    }
    +                }
    +
    +                for (var l = 0; l < this._gamepads.length; l++)
    +                {
    +                    singlePad = this._gamepads[l];
    +
    +                    if (validConnections.padIndices[l])
    +                    {
    +                        continue;
    +                    }
    +
    +                    if (this._rawPads.length < 1)
    +                    {
    +                        singlePad.disconnect();
    +                    }
    +
    +                    for (var m = 0; m < this._rawPads.length; m++)
    +                    {
    +                        if (validConnections.padIndices[l])
    +                        {
    +                            break;
    +                        }
    +
    +                        var rawPad = this._rawPads[m];
    +                        
    +                        if (rawPad)
    +                        {
    +                            if (validConnections.rawIndices[rawPad.index])
    +                            {
    +                                singlePad.disconnect();
    +                                continue;
    +                            }
    +                            else
    +                            {
    +                                singlePad.connect(rawPad);
    +                                validConnections.rawIndices[rawPad.index] = true;
    +                                validConnections.padIndices[l] = true;
    +                            }
    +                        }
    +                        else
    +                        {
    +                            singlePad.disconnect();
    +                        }
    +                    }
    +                }
    +            }
    +        }
    +    },
    +
    +    /**
    +    * Sets the deadZone variable for all four gamepads
    +    * @method Phaser.Gamepad#setDeadZones
    +    */
    +    setDeadZones: function (value) {
    +
    +        for (var i = 0; i < this._gamepads.length; i++)
    +        {
    +            this._gamepads[i].deadZone = value;
    +        }
    +
    +    },
    +
    +    /**
    +    * Stops the Gamepad event handling.
    +    *
    +    * @method Phaser.Gamepad#stop
    +    */
    +    stop: function () {
    +
    +        this._active = false;
    +
    +        window.removeEventListener('gamepadconnected', this._ongamepadconnected);
    +        window.removeEventListener('gamepaddisconnected', this._ongamepaddisconnected);
    +
    +    },
    +
    +    /**
    +    * Reset all buttons/axes of all gamepads
    +    * @method Phaser.Gamepad#reset
    +    */
    +    reset: function () {
    +
    +        this.update();
    +
    +        for (var i = 0; i < this._gamepads.length; i++)
    +        {
    +            this._gamepads[i].reset();
    +        }
    +
    +    },
    +
    +    /**
    +    * Returns the "just pressed" state of a button from ANY gamepad connected. Just pressed is considered true if the button was pressed down within the duration given (default 250ms).
    +    * @method Phaser.Gamepad#justPressed
    +    * @param {number} buttonCode - The buttonCode of the button to check for.
    +    * @param {number} [duration=250] - The duration below which the button is considered as being just pressed.
    +    * @return {boolean} True if the button is just pressed otherwise false.
    +    */
    +    justPressed: function (buttonCode, duration) {
    +
    +        for (var i = 0; i < this._gamepads.length; i++)
    +        {
    +            if (this._gamepads[i].justPressed(buttonCode, duration) === true)
    +            {
    +                return true;
    +            }
    +        }
    +
    +        return false;
    +
    +    },
    +
    +    /**
    +    * Returns the "just released" state of a button from ANY gamepad connected. Just released is considered as being true if the button was released within the duration given (default 250ms).
    +    * @method Phaser.Gamepad#justPressed
    +    * @param {number} buttonCode - The buttonCode of the button to check for.
    +    * @param {number} [duration=250] - The duration below which the button is considered as being just released.
    +    * @return {boolean} True if the button is just released otherwise false.
    +    */
    +    justReleased: function (buttonCode, duration) {
    +
    +        for (var i = 0; i < this._gamepads.length; i++)
    +        {
    +            if (this._gamepads[i].justReleased(buttonCode, duration) === true)
    +            {
    +                return true;
    +            }
    +        }
    +
    +        return false;
    +
    +    },
    +
    +    /**
    +    * Returns true if the button is currently pressed down, on ANY gamepad.
    +    * @method Phaser.Gamepad#isDown
    +    * @param {number} buttonCode - The buttonCode of the button to check for.
    +    * @return {boolean} True if a button is currently down.
    +    */
    +    isDown: function (buttonCode) {
    +
    +        for (var i = 0; i < this._gamepads.length; i++)
    +        {
    +            if (this._gamepads[i].isDown(buttonCode) === true)
    +            {
    +                return true;
    +            }
    +        }
    +
    +        return false;
    +    }
    +
    +};
    +
    +Phaser.Gamepad.prototype.constructor = Phaser.Gamepad;
    +
    +/**
    +* If the gamepad input is active or not - if not active it should not be updated from Input.js
    +* @name Phaser.Gamepad#active
    +* @property {boolean} active - If the gamepad input is active or not.
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Gamepad.prototype, "active", {
    +
    +    get: function () {
    +        return this._active;
    +    }
    +
    +});
    +
    +/**
    +* Whether or not gamepads are supported in current browser.
    +* @name Phaser.Gamepad#supported
    +* @property {boolean} supported - Whether or not gamepads are supported in current browser.
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Gamepad.prototype, "supported", {
    +
    +    get: function () {
    +        return this._gamepadSupportAvailable;
    +    }
    +
    +});
    +
    +/**
    +* How many live gamepads are currently connected.
    +* @name Phaser.Gamepad#padsConnected
    +* @property {boolean} padsConnected - How many live gamepads are currently connected.
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Gamepad.prototype, "padsConnected", {
    +
    +    get: function () {
    +        return this._rawPads.length;
    +    }
    +
    +});
    +
    +/**
    +* Gamepad #1
    +* @name Phaser.Gamepad#pad1
    +* @property {boolean} pad1 - Gamepad #1;
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Gamepad.prototype, "pad1", {
    +
    +    get: function () {
    +        return this._gamepads[0];
    +    }
    +
    +});
    +
    +/**
    +* Gamepad #2
    +* @name Phaser.Gamepad#pad2
    +* @property {boolean} pad2 - Gamepad #2
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Gamepad.prototype, "pad2", {
    +
    +    get: function () {
    +        return this._gamepads[1];
    +    }
    +
    +});
    +
    +/**
    +* Gamepad #3
    +* @name Phaser.Gamepad#pad3
    +* @property {boolean} pad3 - Gamepad #3
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Gamepad.prototype, "pad3", {
    +
    +    get: function () {
    +        return this._gamepads[2];
    +    }
    +
    +});
    +
    +/**
    +* Gamepad #4
    +* @name Phaser.Gamepad#pad4
    +* @property {boolean} pad4 - Gamepad #4
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Gamepad.prototype, "pad4", {
    +
    +    get: function () {
    +        return this._gamepads[3];
    +    }
    +
    +});
    +
    +Phaser.Gamepad.BUTTON_0 = 0;
    +Phaser.Gamepad.BUTTON_1 = 1;
    +Phaser.Gamepad.BUTTON_2 = 2;
    +Phaser.Gamepad.BUTTON_3 = 3;
    +Phaser.Gamepad.BUTTON_4 = 4;
    +Phaser.Gamepad.BUTTON_5 = 5;
    +Phaser.Gamepad.BUTTON_6 = 6;
    +Phaser.Gamepad.BUTTON_7 = 7;
    +Phaser.Gamepad.BUTTON_8 = 8;
    +Phaser.Gamepad.BUTTON_9 = 9;
    +Phaser.Gamepad.BUTTON_10 = 10;
    +Phaser.Gamepad.BUTTON_11 = 11;
    +Phaser.Gamepad.BUTTON_12 = 12;
    +Phaser.Gamepad.BUTTON_13 = 13;
    +Phaser.Gamepad.BUTTON_14 = 14;
    +Phaser.Gamepad.BUTTON_15 = 15;
    +
    +Phaser.Gamepad.AXIS_0 = 0;
    +Phaser.Gamepad.AXIS_1 = 1;
    +Phaser.Gamepad.AXIS_2 = 2;
    +Phaser.Gamepad.AXIS_3 = 3;
    +Phaser.Gamepad.AXIS_4 = 4;
    +Phaser.Gamepad.AXIS_5 = 5;
    +Phaser.Gamepad.AXIS_6 = 6;
    +Phaser.Gamepad.AXIS_7 = 7;
    +Phaser.Gamepad.AXIS_8 = 8;
    +Phaser.Gamepad.AXIS_9 = 9;
    +
    +// Below mapping applies to XBOX 360 Wired and Wireless controller on Google Chrome (tested on Windows 7).
    +// - Firefox uses different map! Separate amount of buttons and axes. DPAD = axis and not a button.
    +// In other words - discrepancies when using gamepads.
    +
    +Phaser.Gamepad.XBOX360_A = 0;
    +Phaser.Gamepad.XBOX360_B = 1;
    +Phaser.Gamepad.XBOX360_X = 2;
    +Phaser.Gamepad.XBOX360_Y = 3;
    +Phaser.Gamepad.XBOX360_LEFT_BUMPER = 4;
    +Phaser.Gamepad.XBOX360_RIGHT_BUMPER = 5;
    +Phaser.Gamepad.XBOX360_LEFT_TRIGGER = 6;
    +Phaser.Gamepad.XBOX360_RIGHT_TRIGGER = 7;
    +Phaser.Gamepad.XBOX360_BACK = 8;
    +Phaser.Gamepad.XBOX360_START = 9;
    +Phaser.Gamepad.XBOX360_STICK_LEFT_BUTTON = 10;
    +Phaser.Gamepad.XBOX360_STICK_RIGHT_BUTTON = 11;
    +
    +Phaser.Gamepad.XBOX360_DPAD_LEFT = 14;
    +Phaser.Gamepad.XBOX360_DPAD_RIGHT = 15;
    +Phaser.Gamepad.XBOX360_DPAD_UP = 12;
    +Phaser.Gamepad.XBOX360_DPAD_DOWN = 13;
    +
    +Phaser.Gamepad.XBOX360_STICK_LEFT_X = 0;
    +Phaser.Gamepad.XBOX360_STICK_LEFT_Y = 1;
    +Phaser.Gamepad.XBOX360_STICK_RIGHT_X = 2;
    +Phaser.Gamepad.XBOX360_STICK_RIGHT_Y = 3;
    +
    +
    +
    + + + + + +
    + +
    +
    + + + + Phaser Copyright © 2012-2014 Photon Storm Ltd. + +
    + + + Documentation generated by JSDoc 3.3.0-dev + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + diff --git a/docs/GamepadButton.js.html b/docs/GamepadButton.js.html new file mode 100644 index 00000000..e4982105 --- /dev/null +++ b/docs/GamepadButton.js.html @@ -0,0 +1,654 @@ + + + + + + Phaser Source: input/GamepadButton.js + + + + + + + + + + +
    + + +
    + + +
    + +
    + + + +

    Source: input/GamepadButton.js

    + +
    +
    +
    /**
    +* @author       @karlmacklin <tacklemcclean@gmail.com>
    +* @copyright    2014 Photon Storm Ltd.
    +* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
    +*/
    +
    +/**
    +* @class Phaser.GamepadButton
    +* @classdesc If you need more fine-grained control over the handling of specific buttons you can create and use Phaser.GamepadButton objects.
    +* @constructor
    +* @param {Phaser.Game} game - Current game instance.
    +* @param {number} buttoncode - The button code this GamepadButton is responsible for.
    +*/
    +Phaser.GamepadButton = function (game, buttoncode) {
    +
    +    /**
    +    * @property {Phaser.Game} game - A reference to the currently running game.
    +    */
    +    this.game = game;
    +
    +    /**
    +    * @property {boolean} isDown - The "down" state of the button.
    +    * @default
    +    */
    +    this.isDown = false;
    +
    +    /**
    +    * @property {boolean} isUp - The "up" state of the button.
    +    * @default
    +    */
    +    this.isUp = false;
    +
    +    /**
    +    * @property {number} timeDown - The timestamp when the button was last pressed down.
    +    * @default
    +    */
    +    this.timeDown = 0;
    +
    +    /**
    +    * If the button is down this value holds the duration of that button press and is constantly updated.
    +    * If the button is up it holds the duration of the previous down session.
    +    * @property {number} duration - The number of milliseconds this button has been held down for.
    +    * @default
    +    */
    +    this.duration = 0;
    +
    +    /**
    +    * @property {number} timeUp - The timestamp when the button was last released.
    +    * @default
    +    */
    +    this.timeUp = 0;
    +
    +    /**
    +    * @property {number} repeats - If a button is held down this holds down the number of times the button has 'repeated'.
    +    * @default
    +    */
    +    this.repeats = 0;
    +
    +    /**
    +    * @property {number} value - Button value. Mainly useful for checking analog buttons (like shoulder triggers)
    +    * @default
    +    */
    +    this.value = 0;
    +
    +    /**
    +    * @property {number} buttonCode - The buttoncode of this button.
    +    */
    +    this.buttonCode = buttoncode;
    +
    +    /**
    +    * @property {Phaser.Signal} onDown - This Signal is dispatched every time this GamepadButton is pressed down. It is only dispatched once (until the button is released again).
    +    */
    +    this.onDown = new Phaser.Signal();
    +
    +    /**
    +    * @property {Phaser.Signal} onUp - This Signal is dispatched every time this GamepadButton is pressed down. It is only dispatched once (until the button is released again).
    +    */
    +    this.onUp = new Phaser.Signal();
    +
    +    /**
    +    * @property {Phaser.Signal} onFloat - This Signal is dispatched every time this GamepadButton changes floating value (between (but not exactly) 0 and 1)
    +    */
    +    this.onFloat = new Phaser.Signal();
    +
    +};
    +
    +Phaser.GamepadButton.prototype = {
    +
    +    /**
    +    * Called automatically by Phaser.SinglePad.
    +    * @method Phaser.GamepadButton#processButtonDown
    +    * @param {Object} value - Button value
    +    * @protected
    +    */
    +    processButtonDown: function (value) {
    +
    +        if (this.isDown)
    +        {
    +            this.duration = this.game.time.now - this.timeDown;
    +            this.repeats++;
    +        }
    +        else
    +        {
    +            this.isDown = true;
    +            this.isUp = false;
    +            this.timeDown = this.game.time.now;
    +            this.duration = 0;
    +            this.repeats = 0;
    +            this.value = value;
    +
    +            this.onDown.dispatch(this, value);
    +        }
    +
    +    },
    +
    +    /**
    +    * Called automatically by Phaser.SinglePad.
    +    * @method Phaser.GamepadButton#processButtonUp
    +    * @param {Object} value - Button value
    +    * @protected
    +    */
    +    processButtonUp: function (value) {
    +
    +        this.isDown = false;
    +        this.isUp = true;
    +        this.timeUp = this.game.time.now;
    +        this.value = value;
    +
    +        this.onUp.dispatch(this, value);
    +
    +    },
    +
    +    /**
    +    * Called automatically by Phaser.Gamepad.
    +    * @method Phaser.GamepadButton#processButtonFloat
    +    * @param {Object} value - Button value
    +    * @protected
    +    */
    +    processButtonFloat: function (value) {
    +
    +        this.value = value;
    +        this.onFloat.dispatch(this, value);
    +
    +    },
    +
    +    /**
    +    * Returns the "just pressed" state of this button. Just pressed is considered true if the button was pressed down within the duration given (default 250ms).
    +    * @method Phaser.GamepadButton#justPressed
    +    * @param {number} [duration=250] - The duration below which the button is considered as being just pressed.
    +    * @return {boolean} True if the button is just pressed otherwise false.
    +    */
    +    justPressed: function (duration) {
    +
    +        if (typeof duration === "undefined") { duration = 250; }
    +
    +        return (this.isDown && this.duration < duration);
    +
    +    },
    +
    +    /**
    +    * Returns the "just released" state of this button. Just released is considered as being true if the button was released within the duration given (default 250ms).
    +    * @method Phaser.GamepadButton#justPressed
    +    * @param {number} [duration=250] - The duration below which the button is considered as being just released.
    +    * @return {boolean} True if the button is just pressed otherwise false.
    +    */
    +    justReleased: function (duration) {
    +
    +        if (typeof duration === "undefined") { duration = 250; }
    +
    +        return (this.isDown === false && (this.game.time.now - this.timeUp < duration));
    +    }
    +
    +};
    +
    +Phaser.GamepadButton.prototype.constructor = Phaser.GamepadButton;
    +
    +
    +
    + + + + + +
    + +
    +
    + + + + Phaser Copyright © 2012-2014 Photon Storm Ltd. + +
    + + + Documentation generated by JSDoc 3.3.0-dev + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + diff --git a/docs/Graphics.js.html b/docs/Graphics.js.html index abb78deb..4c11d8b7 100644 --- a/docs/Graphics.js.html +++ b/docs/Graphics.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -540,13 +534,13 @@ Object.defineProperty(Phaser.Graphics.prototype, 'y', {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Group.js.html b/docs/Group.js.html index cfb22006..55d13f2c 100644 --- a/docs/Group.js.html +++ b/docs/Group.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -433,32 +427,32 @@
     * @classdesc A Group is a container for display objects that allows for fast pooling, recycling and collision checks.
     * @constructor
     * @param {Phaser.Game} game - A reference to the currently running game.
    -* @param {*} parent - The parent Group or DisplayObjectContainer that will hold this group, if any.
    +* @param {*} parent - The parent Group or DisplayObjectContainer that will hold this group, if any. If undefined it will use game.world.
     * @param {string} [name=group] - A name for this Group. Not used internally but useful for debugging.
     * @param {boolean} [useStage=false] - Should the DisplayObjectContainer this Group creates be added to the World (default, false) or direct to the Stage (true).
     */
     Phaser.Group = function (game, parent, name, useStage) {
     
    -    if (typeof parent === 'undefined' || typeof parent === null)
    +    /**
    +    * @property {Phaser.Game} game - A reference to the currently running Game.
    +    */
    +    this.game = game;
    +
    +    if (typeof parent === 'undefined')
         {
             parent = game.world;
         }
     
    +    /**
    +    * @property {string} name - A name for this Group. Not used internally but useful for debugging.
    +    */
    +    this.name = name || 'group';
    +
         if (typeof useStage === 'undefined')
         {
             useStage = false;
         }
     
    -    /**
    -    * @property {Phaser.Game} game - A reference to the currently running Game.
    -    */
    -    this.game = game;
    -    
    -    /**
    -    * @property {string} name - A name for this Group. Not used internally but useful for debugging.
    -    */
    -    this.name = name || 'group';
    -
         if (useStage)
         {
             this._container = this.game.stage._stage;
    @@ -473,7 +467,6 @@ Phaser.Group = function (game, parent, name, useStage) {
                 if (parent instanceof Phaser.Group)
                 {
                     parent._container.addChild(this._container);
    -                parent._container.updateTransform();
                 }
                 else
                 {
    @@ -494,6 +487,12 @@ Phaser.Group = function (game, parent, name, useStage) {
         */
         this.type = Phaser.GROUP;
     
    +    /**
    +    * @property {boolean} alive - The alive property is useful for Groups that are children of other Groups and need to be included/excluded in checks like forEachAlive.
    +    * @default
    +    */
    +    this.alive = true;
    +
         /**
         * @property {boolean} exists - If exists is true the the Group is updated, otherwise it is skipped.
         * @default
    @@ -501,9 +500,22 @@ Phaser.Group = function (game, parent, name, useStage) {
         this.exists = true;
     
         /**
    -    * @property {Phaser.Point} scale - Replaces the PIXI.Point with a slightly more flexible one.
    +    * @property {Phaser.Group} group - The parent Group of this Group, if a child of another.
         */
    -    this.scale = new Phaser.Point(1, 1);
    +    this.group = null;
    +
    +    //  Replaces the PIXI.Point with a slightly more flexible one.
    +    this._container.scale = new Phaser.Point(1, 1);
    +
    +    /**
    +    * @property {Phaser.Point} scale - The scane of the Group container.
    +    */
    +    this.scale = this._container.scale;
    +
    +    /**
    +    * @property {Phaser.Point} pivot - The pivot point of the Group container.
    +    */
    +    this.pivot = this._container.pivot;
     
         /**
         * The cursor is a simple way to iterate through the objects in a Group using the Group.next and Group.previous functions.
    @@ -561,16 +573,27 @@ Phaser.Group.prototype = {
     
             if (child.group !== this)
             {
    -            child.group = this;
    -
    -            if (child.events)
    +            if (child.type && child.type === Phaser.GROUP)
                 {
    -                child.events.onAddedToGroup.dispatch(child, this);
    +                child.group = this;
    +
    +                this._container.addChild(child._container);
    +
    +                child._container.updateTransform();
                 }
    +            else
    +            {
    +                child.group = this;
     
    -            this._container.addChild(child);
    +                this._container.addChild(child);
     
    -            child.updateTransform();
    +                child.updateTransform();
    +
    +                if (child.events)
    +                {
    +                    child.events.onAddedToGroup.dispatch(child, this);
    +                }
    +            }
     
                 if (this.cursor === null)
                 {
    @@ -595,16 +618,27 @@ Phaser.Group.prototype = {
     
             if (child.group !== this)
             {
    -            child.group = this;
    -
    -            if (child.events)
    +            if (child.type && child.type === Phaser.GROUP)
                 {
    -                child.events.onAddedToGroup.dispatch(child, this);
    +                child.group = this;
    +
    +                this._container.addChildAt(child._container, index);
    +
    +                child._container.updateTransform();
                 }
    +            else
    +            {
    +                child.group = this;
     
    -            this._container.addChildAt(child, index);
    +                this._container.addChildAt(child, index);
     
    -            child.updateTransform();
    +                child.updateTransform();
    +
    +                if (child.events)
    +                {
    +                    child.events.onAddedToGroup.dispatch(child, this);
    +                }
    +            }
     
                 if (this.cursor === null)
                 {
    @@ -643,7 +677,7 @@ Phaser.Group.prototype = {
         */
         create: function (x, y, key, frame, exists) {
     
    -        if (typeof exists == 'undefined') { exists = true; }
    +        if (typeof exists === 'undefined') { exists = true; }
     
             var child = new Phaser.Sprite(this.game, x, y, key, frame);
     
    @@ -652,15 +686,15 @@ Phaser.Group.prototype = {
             child.visible = exists;
             child.alive = exists;
     
    +        this._container.addChild(child);
    +            
    +        child.updateTransform();
    +
             if (child.events)
             {
                 child.events.onAddedToGroup.dispatch(child, this);
             }
     
    -        this._container.addChild(child);
    -            
    -        child.updateTransform();
    -
             if (this.cursor === null)
             {
                 this.cursor = child;
    @@ -683,7 +717,7 @@ Phaser.Group.prototype = {
         */
         createMultiple: function (quantity, key, frame, exists) {
     
    -        if (typeof exists == 'undefined') { exists = false; }
    +        if (typeof exists === 'undefined') { exists = false; }
     
             for (var i = 0; i < quantity; i++)
             {
    @@ -694,14 +728,15 @@ Phaser.Group.prototype = {
                 child.visible = exists;
                 child.alive = exists;
     
    +            this._container.addChild(child);
    +
    +            child.updateTransform();
    +
                 if (child.events)
                 {
                     child.events.onAddedToGroup.dispatch(child, this);
                 }
     
    -            this._container.addChild(child);
    -            child.updateTransform();
    -
                 if (this.cursor === null)
                 {
                     this.cursor = child;
    @@ -755,6 +790,11 @@ Phaser.Group.prototype = {
     
         },
     
    +    /**
    +    * Internal test.
    +    *
    +    * @method Phaser.Group#childTest
    +    */
         childTest: function (prefix, child) {
     
             var s = prefix + ' next: ';
    @@ -783,13 +823,16 @@ Phaser.Group.prototype = {
     
         },
     
    +    /**
    +    * Internal test.
    +    *
    +    * @method Phaser.Group#swapIndex
    +    */
         swapIndex: function (index1, index2) {
     
             var child1 = this.getAt(index1);
             var child2 = this.getAt(index2);
     
    -        console.log('swapIndex ', index1, ' with ', index2);
    -
             this.swap(child1, child2);
     
         },
    @@ -1054,6 +1097,32 @@ Phaser.Group.prototype = {
     
         },
     
    +    /**
    +    * This function allows you to quickly set a property on a single child of this Group to a new value.
    +    * The operation parameter controls how the new value is assigned to the property, from simple replacement to addition and multiplication.
    +    *
    +    * @method Phaser.Group#set
    +    * @param {Phaser.Sprite} child - The child to set the property on.
    +    * @param {string} key - The property, as a string, to be set. For example: 'body.velocity.x'
    +    * @param {*} value - The value that will be set.
    +    * @param {boolean} [checkAlive=false] - If set then the child will only be updated if alive=true.
    +    * @param {boolean} [checkVisible=false] - If set then the child will only be updated if visible=true.
    +    * @param {number} [operation=0] - Controls how the value is assigned. A value of 0 replaces the value with the new one. A value of 1 adds it, 2 subtracts it, 3 multiplies it and 4 divides it.
    +    */
    +    set: function (child, key, value, checkAlive, checkVisible, operation) {
    +
    +        key = key.split('.');
    +
    +        if (typeof checkAlive === 'undefined') { checkAlive = false; }
    +        if (typeof checkVisible === 'undefined') { checkVisible = false; }
    +
    +        if ((checkAlive === false || (checkAlive && child.alive)) && (checkVisible === false || (checkVisible && child.visible)))
    +        {
    +            this.setProperty(child, key, value, operation);
    +        }
    +
    +    },
    +
         /**
         * This function allows you to quickly set the same property across all children of this Group to a new value.
         * The operation parameter controls how the new value is assigned to the property, from simple replacement to addition and multiplication.
    @@ -1189,7 +1258,7 @@ Phaser.Group.prototype = {
         },
     
         /**
    -    * Calls a function on all of the children that have exists=true in this Group.
    +    * Returns a reference to a function that exists on a child of the Group based on the given callback array.
         * 
         * @method Phaser.Group#callbackFromArray
         * @param {object} child - The object to inspect.
    @@ -1247,7 +1316,7 @@ Phaser.Group.prototype = {
         * 
         * @method Phaser.Group#callAll
         * @param {string} method - A string containing the name of the function that will be called. The function must exist on the child.
    -    * @param {string} [context=''] - A string containing the context under which the method will be executed. Leave to '' to default to the child.
    +    * @param {string} [context=null] - A string containing the context under which the method will be executed. Set to null to default to the child.
         * @param {...*} parameter - Additional parameters that will be passed to the method.
         */
         callAll: function (method, context) {
    @@ -1314,6 +1383,7 @@ Phaser.Group.prototype = {
         * Allows you to call your own function on each member of this Group. You must pass the callback and context in which it will run.
         * After the checkExists parameter you can add as many parameters as you like, which will all be passed to the callback along with the child.
         * For example: Group.forEach(awardBonusGold, this, true, 100, 500)
    +    * Note: Currently this will skip any children which are Groups themselves.
         * 
         * @method Phaser.Group#forEach
         * @param {function} callback - The function that will be called. Each child of the Group will be passed to it as its first parameter.
    @@ -1464,12 +1534,13 @@ Phaser.Group.prototype = {
         * @param {number} returnType - How to return the data from this method. Either Phaser.Group.RETURN_NONE, Phaser.Group.RETURN_TOTAL or Phaser.Group.RETURN_CHILD.
         * @param {function} [callback=null] - Optional function that will be called on each matching child. Each child of the Group will be passed to it as its first parameter.
         * @param {Object} [callbackContext] - The context in which the function should be called (usually 'this').
    +    * @return {any} Returns either a numeric total (if RETURN_TOTAL was specified) or the child object.
         */
         iterate: function (key, value, returnType, callback, callbackContext, args) {
     
    -        if (returnType == Phaser.Group.RETURN_TOTAL && this._container.children.length === 0)
    +        if (returnType === Phaser.Group.RETURN_TOTAL && this._container.children.length === 0)
             {
    -            return -1;
    +            return 0;
             }
     
             if (typeof callback === 'undefined')
    @@ -1495,7 +1566,7 @@ Phaser.Group.prototype = {
                             callback.apply(callbackContext, args);
                         }
     
    -                    if (returnType == Phaser.Group.RETURN_CHILD)
    +                    if (returnType === Phaser.Group.RETURN_CHILD)
                         {
                             return currentNode;
                         }
    @@ -1506,11 +1577,11 @@ Phaser.Group.prototype = {
                 while (currentNode != this._container.last._iNext);
             }
     
    -        if (returnType == Phaser.Group.RETURN_TOTAL)
    +        if (returnType === Phaser.Group.RETURN_TOTAL)
             {
                 return total;
             }
    -        else if (returnType == Phaser.Group.RETURN_CHILD)
    +        else if (returnType === Phaser.Group.RETURN_CHILD)
             {
                 return null;
             }
    @@ -1565,7 +1636,7 @@ Phaser.Group.prototype = {
         * Call this function to find out how many members of the group are alive.
         *
         * @method Phaser.Group#countLiving
    -    * @return {number} The number of children flagged as alive. Returns -1 if Group is empty.
    +    * @return {number} The number of children flagged as alive.
         */
         countLiving: function () {
     
    @@ -1577,7 +1648,7 @@ Phaser.Group.prototype = {
         * Call this function to find out how many members of the group are dead.
         *
         * @method Phaser.Group#countDead
    -    * @return {number} The number of children flagged as dead. Returns -1 if Group is empty.
    +    * @return {number} The number of children flagged as dead.
         */
         countDead: function () {
     
    @@ -1721,11 +1792,31 @@ Phaser.Group.prototype = {
         * Destroys this Group. Removes all children, then removes the container from the display list and nulls references.
         *
         * @method Phaser.Group#destroy
    +    * @param {boolean} [destroyChildren=false] - Should every child of this Group have its destroy method called?
         */
    -    destroy: function () {
    +    destroy: function (destroyChildren) {
     
    -        this.removeAll();
    +        if (typeof destroyChildren === 'undefined') { destroyChildren = false; }
     
    +        if (destroyChildren)
    +        {
    +            if (this._container.children.length > 0)
    +            {
    +                do
    +                {
    +                    if (this._container.children[0].group)
    +                    {
    +                        this._container.children[0].destroy();
    +                    }
    +                }
    +                while (this._container.children.length > 0);
    +            }
    +        }
    +        else
    +        {
    +            this.removeAll();
    +        }
    +    
             this._container.parent.removeChild(this._container);
     
             this._container = null;
    @@ -1778,130 +1869,52 @@ Phaser.Group.prototype = {
     
             return true;
     
    -    },
    -
    -    /**
    -    * Dumps out a list of Group children and their index positions to the browser console. Useful for group debugging.
    -    *
    -    * @method Phaser.Group#dump
    -    * @param {boolean} [full=false] - If full the dump will include the entire display list, start from the Stage. Otherwise it will only include this container.
    -    */
    -    dump: function (full) {
    -
    -        if (typeof full == 'undefined')
    -        {
    -            full = false;
    -        }
    -
    -        var spacing = 20;
    -        var output = "\n" + Phaser.Utils.pad('Node', spacing) + "|" + Phaser.Utils.pad('Next', spacing) + "|" + Phaser.Utils.pad('Previous', spacing) + "|" + Phaser.Utils.pad('First', spacing) + "|" + Phaser.Utils.pad('Last', spacing);
    -
    -        console.log(output);
    -
    -        var output = Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing);
    -        console.log(output);
    -
    -        if (full)
    -        {
    -            var testObject = this.game.stage._stage.last._iNext;
    -            var displayObject = this.game.stage._stage;
    -        }
    -        else
    -        {
    -            var testObject = this._container.last._iNext;
    -            var displayObject = this._container;
    -        }
    -        
    -        do
    -        {
    -            var name = displayObject.name || '*';
    -
    -            if (this.cursor == displayObject)
    -            {
    -                var name = '> ' + name;
    -            }
    -
    -            var nameNext = '-';
    -            var namePrev = '-';
    -            var nameFirst = '-';
    -            var nameLast = '-';
    -
    -            if (displayObject._iNext)
    -            {
    -                nameNext = displayObject._iNext.name;
    -            }
    -
    -            if (displayObject._iPrev)
    -            {
    -                namePrev = displayObject._iPrev.name;
    -            }
    -
    -            if (displayObject.first)
    -            {
    -                nameFirst = displayObject.first.name;
    -            }
    -
    -            if (displayObject.last)
    -            {
    -                nameLast = displayObject.last.name;
    -            }
    -
    -            if (typeof nameNext === 'undefined')
    -            {
    -                nameNext = '-';
    -            }
    -
    -            if (typeof namePrev === 'undefined')
    -            {
    -                namePrev = '-';
    -            }
    -
    -            if (typeof nameFirst === 'undefined')
    -            {
    -                nameFirst = '-';
    -            }
    -
    -            if (typeof nameLast === 'undefined')
    -            {
    -                nameLast = '-';
    -            }
    -
    -            var output = Phaser.Utils.pad(name, spacing) + "|" + Phaser.Utils.pad(nameNext, spacing) + "|" + Phaser.Utils.pad(namePrev, spacing) + "|" + Phaser.Utils.pad(nameFirst, spacing) + "|" + Phaser.Utils.pad(nameLast, spacing);
    -            console.log(output);
    -
    -            displayObject = displayObject._iNext;
    -
    -        }
    -        while(displayObject != testObject)
    -
         }
     
     };
     
    +Phaser.Group.prototype.constructor = Phaser.Group;
    +
     /**
     * @name Phaser.Group#total
    -* @property {number} total - The total number of children in this Group, regardless of their alive state.
    +* @property {number} total - The total number of children in this Group who have a state of exists = true.
     * @readonly
     */
     Object.defineProperty(Phaser.Group.prototype, "total", {
     
         get: function () {
    -        return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
    -        // return this._container.children.length;
    +
    +        if (this._container)
    +        {
    +            return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
    +        }
    +        else
    +        {
    +            return 0;
    +        }
    +
         }
     
     });
     
     /**
     * @name Phaser.Group#length
    -* @property {number} length - The number of children in this Group.
    +* @property {number} length - The total number of children in this Group, regardless of their exists/alive status.
     * @readonly
     */
     Object.defineProperty(Phaser.Group.prototype, "length", {
     
         get: function () {
    -        return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
    -        // return this._container.children.length;
    +
    +        if (this._container)
    +        {
    +            return this._container.children.length;
    +        }
    +        else
    +        {
    +            return 0;
    +        }
    +
         }
     
     });
    @@ -2024,13 +2037,13 @@ Object.defineProperty(Phaser.Group.prototype, "alpha", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Input.js.html b/docs/Input.js.html index 8b01fbbb..962827b9 100644 --- a/docs/Input.js.html +++ b/docs/Input.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -453,6 +447,16 @@ Phaser.Input = function (game) {
         * @default
         */
         this.hitContext = null;
    +
    +    /**
    +    * @property {function} moveCallback - An optional callback that will be fired every time the activePointer receives a move event from the DOM. Set to null to disable.
    +    */
    +    this.moveCallback = null;
    +
    +    /**
    +    * @property {object} moveCallbackContext - The context in which the moveCallback will be sent. Defaults to Phaser.Input but can be set to any valid JS object.
    +    */
    +    this.moveCallbackContext = this;
         
     };
     
    @@ -729,6 +733,13 @@ Phaser.Input.prototype = {
         */
         mspointer: null,
     
    +    /**
    +     * The Gamepad Input manager.
    +     * @property {Phaser.Gamepad} gamepad - The Gamepad Input manager.
    +     * @default
    +     */
    +    gamepad: null,
    +
         /**
         * A Signal that is dispatched each time a pointer is pressed down.
         * @property {Phaser.Signal} onDown
    @@ -778,6 +789,7 @@ Phaser.Input.prototype = {
             this.keyboard = new Phaser.Keyboard(this.game);
             this.touch = new Phaser.Touch(this.game);
             this.mspointer = new Phaser.MSPointer(this.game);
    +        this.gamepad = new Phaser.Gamepad(this.game);
     
             this.onDown = new Phaser.Signal();
             this.onUp = new Phaser.Signal();
    @@ -817,6 +829,24 @@ Phaser.Input.prototype = {
             this.keyboard.stop();
             this.touch.stop();
             this.mspointer.stop();
    +        this.gamepad.stop();
    +
    +        this.moveCallback = null;
    +
    +    },
    +
    +    /**
    +    * Sets a callback that is fired every time the activePointer receives a DOM move event such as a mousemove or touchmove.
    +    * It will be called every time the activePointer moves, which in a multi-touch game can be a lot of times, so this is best
    +    * to only use if you've limited input to a single pointer (i.e. mouse or touch)
    +    * @method Phaser.Input#setMoveCallback
    +    * @param {function} callback - The callback that will be called each time the activePointer receives a DOM move event.
    +    * @param {object} callbackContext - The context in which the callback will be called.
    +    */
    +    setMoveCallback: function (callback, callbackContext) {
    +
    +        this.moveCallback = callback;
    +        this.moveCallbackContext = callbackContext;
     
         },
     
    @@ -870,6 +900,8 @@ Phaser.Input.prototype = {
             this._oldPosition.copyFrom(this.position);
             this.mousePointer.update();
     
    +        if (this.gamepad.active) { this.gamepad.update(); }
    +
             this.pointer1.update();
             this.pointer2.update();
     
    @@ -901,6 +933,7 @@ Phaser.Input.prototype = {
     
             this.keyboard.reset();
             this.mousePointer.reset();
    +        this.gamepad.reset();
     
             for (var i = 1; i <= 10; i++)
             {
    @@ -911,7 +944,11 @@ Phaser.Input.prototype = {
             }
     
             this.currentPointers = 0;
    -        this.game.stage.canvas.style.cursor = "default";
    +
    +        if (this.game.canvas.style.cursor !== 'none')
    +        {
    +            this.game.canvas.style.cursor = 'default';
    +        }
     
             if (hard === true)
             {
    @@ -1108,6 +1145,8 @@ Phaser.Input.prototype = {
     
     };
     
    +Phaser.Input.prototype.constructor = Phaser.Input;
    +
     /**
     * The X coordinate of the most recently active pointer. This value takes game scaling into account automatically. See Pointer.screenX/clientX for source values.
     * @name Phaser.Input#x
    @@ -1235,13 +1274,13 @@ Object.defineProperty(Phaser.Input.prototype, "worldY", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/InputHandler.js.html b/docs/InputHandler.js.html index 519c7515..592d86d6 100644 --- a/docs/InputHandler.js.html +++ b/docs/InputHandler.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -451,36 +445,6 @@ Phaser.InputHandler = function (sprite) {
         */
         this.enabled = false;
     
    -    /**
    -    * @property {Description} parent - Description. 
    -    * @default
    -    */
    -    // this.parent = null;
    -    
    -    /**
    -    * @property {Description} next - Linked List
    -    * @default
    -    */
    -    // this.next = null;
    -    
    -    /**
    -    * @property {Description} prev - Description. 
    -    * @default
    -    */
    -    // this.prev = null;
    -    
    -    /**
    -    * @property {Description} last - Description. 
    -    * @default
    -    */
    -    // this.last = this;
    -    
    -    /**
    -    * @property {Description} first - Description. 
    -    * @default
    -    */
    -    // this.first = this;
    -
         /**
         * @property {number} priorityID - The PriorityID controls which Sprite receives an Input event first if they should overlap.
         * @default
    @@ -547,6 +511,18 @@ Phaser.InputHandler = function (sprite) {
         */
         this.snapY = 0;
     
    +    /**
    +    * @property {number} snapOffsetX - This defines the top-left X coordinate of the snap grid.
    +    * @default
    +    */
    +    this.snapOffsetX = 0;
    +    
    +    /**
    +    * @property {number} snapOffsetY - This defines the top-left Y coordinate of the snap grid..
    +    * @default
    +    */
    +    this.snapOffsetY = 0;
    +
         /**
         * @property {number} pixelPerfect - Should we use pixel perfect hit detection? Warning: expensive. Only enable if you really need it!
         * @default
    @@ -622,8 +598,6 @@ Phaser.InputHandler.prototype = {
         */
         start: function (priority, useHandCursor) {
     
    -        console.log('InputHandler start');
    -
             priority = priority || 0;
             if (typeof useHandCursor == 'undefined') { useHandCursor = false; }
     
    @@ -1039,7 +1013,7 @@ Phaser.InputHandler.prototype = {
     
                 if (this.useHandCursor && this._pointerData[pointer.id].isDragged === false)
                 {
    -                this.game.stage.canvas.style.cursor = "pointer";
    +                this.game.canvas.style.cursor = "pointer";
                 }
     
                 this.sprite.events.onInputOver.dispatch(this.sprite, pointer);
    @@ -1060,7 +1034,7 @@ Phaser.InputHandler.prototype = {
     
             if (this.useHandCursor && this._pointerData[pointer.id].isDragged === false)
             {
    -            this.game.stage.canvas.style.cursor = "default";
    +            this.game.canvas.style.cursor = "default";
             }
     
             if (this.sprite && this.sprite.events)
    @@ -1121,15 +1095,18 @@ Phaser.InputHandler.prototype = {
                 //  Only release the InputUp signal if the pointer is still over this sprite
                 if (this.checkPointerOver(pointer))
                 {
    -                //console.log('releasedHandler: ' + Date.now());
    -                this.sprite.events.onInputUp.dispatch(this.sprite, pointer);
    +                //  Release the inputUp signal and provide optional parameter if pointer is still over the sprite or not
    +                this.sprite.events.onInputUp.dispatch(this.sprite, pointer, true);
                 }
                 else
                 {
    +                //  Release the inputUp signal and provide optional parameter if pointer is still over the sprite or not
    +                this.sprite.events.onInputUp.dispatch(this.sprite, pointer, false);
    +
                     //  Pointer outside the sprite? Reset the cursor
                     if (this.useHandCursor)
                     {
    -                    this.game.stage.canvas.style.cursor = "default";
    +                    this.game.canvas.style.cursor = "default";
                     }
                 }
     
    @@ -1156,30 +1133,61 @@ Phaser.InputHandler.prototype = {
                 return false;
             }
     
    -        if (this.allowHorizontalDrag)
    +        if (this.sprite.fixedToCamera)
             {
    -            this.sprite.x = pointer.x + this._dragPoint.x + this.dragOffset.x;
    -        }
    +            if (this.allowHorizontalDrag)
    +            {
    +                this.sprite.cameraOffset.x = pointer.x + this._dragPoint.x + this.dragOffset.x;
    +            }
     
    -        if (this.allowVerticalDrag)
    -        {
    -            this.sprite.y = pointer.y + this._dragPoint.y + this.dragOffset.y;
    -        }
    +            if (this.allowVerticalDrag)
    +            {
    +                this.sprite.cameraOffset.y = pointer.y + this._dragPoint.y + this.dragOffset.y;
    +            }
     
    -        if (this.boundsRect)
    -        {
    -            this.checkBoundsRect();
    -        }
    +            if (this.boundsRect)
    +            {
    +                this.checkBoundsRect();
    +            }
     
    -        if (this.boundsSprite)
    -        {
    -            this.checkBoundsSprite();
    -        }
    +            if (this.boundsSprite)
    +            {
    +                this.checkBoundsSprite();
    +            }
     
    -        if (this.snapOnDrag)
    +            if (this.snapOnDrag)
    +            {
    +                this.sprite.cameraOffset.x = Math.round((this.sprite.cameraOffset.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX);
    +                this.sprite.cameraOffset.y = Math.round((this.sprite.cameraOffset.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY);
    +            }
    +        }
    +        else
             {
    -            this.sprite.x = Math.round(this.sprite.x / this.snapX) * this.snapX;
    -            this.sprite.y = Math.round(this.sprite.y / this.snapY) * this.snapY;
    +            if (this.allowHorizontalDrag)
    +            {
    +                this.sprite.x = pointer.x + this._dragPoint.x + this.dragOffset.x;
    +            }
    +
    +            if (this.allowVerticalDrag)
    +            {
    +                this.sprite.y = pointer.y + this._dragPoint.y + this.dragOffset.y;
    +            }
    +
    +            if (this.boundsRect)
    +            {
    +                this.checkBoundsRect();
    +            }
    +
    +            if (this.boundsSprite)
    +            {
    +                this.checkBoundsSprite();
    +            }
    +
    +            if (this.snapOnDrag)
    +            {
    +                this.sprite.x = Math.round((this.sprite.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX);
    +                this.sprite.y = Math.round((this.sprite.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY);
    +            }
             }
     
             return true;
    @@ -1359,14 +1367,29 @@ Phaser.InputHandler.prototype = {
             this._draggedPointerID = pointer.id;
             this._pointerData[pointer.id].isDragged = true;
     
    -        if (this.dragFromCenter)
    +        if (this.sprite.fixedToCamera)
             {
    -            this.sprite.centerOn(pointer.x, pointer.y);
    -            this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y);
    +            if (this.dragFromCenter)
    +            {
    +                this.sprite.centerOn(pointer.x, pointer.y);
    +                this._dragPoint.setTo(this.sprite.cameraOffset.x - pointer.x, this.sprite.cameraOffset.y - pointer.y);
    +            }
    +            else
    +            {
    +                this._dragPoint.setTo(this.sprite.cameraOffset.x - pointer.x, this.sprite.cameraOffset.y - pointer.y);
    +            }
             }
             else
             {
    -            this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y);
    +            if (this.dragFromCenter)
    +            {
    +                this.sprite.centerOn(pointer.x, pointer.y);
    +                this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y);
    +            }
    +            else
    +            {
    +                this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y);
    +            }
             }
     
             this.updateDrag(pointer);
    @@ -1393,8 +1416,16 @@ Phaser.InputHandler.prototype = {
             
             if (this.snapOnRelease)
             {
    -            this.sprite.x = Math.round(this.sprite.x / this.snapX) * this.snapX;
    -            this.sprite.y = Math.round(this.sprite.y / this.snapY) * this.snapY;
    +            if (this.sprite.fixedToCamera)
    +            {
    +                this.sprite.cameraOffset.x = Math.round((this.sprite.cameraOffset.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX);
    +                this.sprite.cameraOffset.y = Math.round((this.sprite.cameraOffset.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY);
    +            }
    +            else
    +            {
    +                this.sprite.x = Math.round((this.sprite.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX);
    +                this.sprite.y = Math.round((this.sprite.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY);
    +            }
             }
     
             this.sprite.events.onDragStop.dispatch(this.sprite, pointer);
    @@ -1431,14 +1462,20 @@ Phaser.InputHandler.prototype = {
         * @param {number} snapY - The height of the grid cell to snap to.
         * @param {boolean} [onDrag=true] - If true the sprite will snap to the grid while being dragged.
         * @param {boolean} [onRelease=false] - If true the sprite will snap to the grid when released.
    +    * @param {number} [snapOffsetX=0] - Used to offset the top-left starting point of the snap grid.
    +    * @param {number} [snapOffsetX=0] - Used to offset the top-left starting point of the snap grid.
         */
    -    enableSnap: function (snapX, snapY, onDrag, onRelease) {
    +    enableSnap: function (snapX, snapY, onDrag, onRelease, snappOffsetX, snappOffsetY) {
     
             if (typeof onDrag == 'undefined') { onDrag = true; }
             if (typeof onRelease == 'undefined') { onRelease = false; }
    +        if (typeof snapOffsetX == 'undefined') { snapOffsetX = 0; }
    +        if (typeof snapOffsetY == 'undefined') { snapOffsetY = 0; }
     
             this.snapX = snapX;
             this.snapY = snapY;
    +        this.snapOffsetX = snapOffsetX;
    +        this.snapOffsetY = snapOffsetY;
             this.snapOnDrag = onDrag;
             this.snapOnRelease = onRelease;
     
    @@ -1461,22 +1498,45 @@ Phaser.InputHandler.prototype = {
         */
         checkBoundsRect: function () {
     
    -        if (this.sprite.x < this.boundsRect.left)
    +        if (this.sprite.fixedToCamera)
             {
    -            this.sprite.x = this.boundsRect.x;
    -        }
    -        else if ((this.sprite.x + this.sprite.width) > this.boundsRect.right)
    -        {
    -            this.sprite.x = this.boundsRect.right - this.sprite.width;
    -        }
    +            if (this.sprite.cameraOffset.x < this.boundsRect.left)
    +            {
    +                this.sprite.cameraOffset.x = this.boundsRect.cameraOffset.x;
    +            }
    +            else if ((this.sprite.cameraOffset.x + this.sprite.width) > this.boundsRect.right)
    +            {
    +                this.sprite.cameraOffset.x = this.boundsRect.right - this.sprite.width;
    +            }
     
    -        if (this.sprite.y < this.boundsRect.top)
    -        {
    -            this.sprite.y = this.boundsRect.top;
    +            if (this.sprite.cameraOffset.y < this.boundsRect.top)
    +            {
    +                this.sprite.cameraOffset.y = this.boundsRect.top;
    +            }
    +            else if ((this.sprite.cameraOffset.y + this.sprite.height) > this.boundsRect.bottom)
    +            {
    +                this.sprite.cameraOffset.y = this.boundsRect.bottom - this.sprite.height;
    +            }
             }
    -        else if ((this.sprite.y + this.sprite.height) > this.boundsRect.bottom)
    +        else
             {
    -            this.sprite.y = this.boundsRect.bottom - this.sprite.height;
    +            if (this.sprite.x < this.boundsRect.left)
    +            {
    +                this.sprite.x = this.boundsRect.x;
    +            }
    +            else if ((this.sprite.x + this.sprite.width) > this.boundsRect.right)
    +            {
    +                this.sprite.x = this.boundsRect.right - this.sprite.width;
    +            }
    +
    +            if (this.sprite.y < this.boundsRect.top)
    +            {
    +                this.sprite.y = this.boundsRect.top;
    +            }
    +            else if ((this.sprite.y + this.sprite.height) > this.boundsRect.bottom)
    +            {
    +                this.sprite.y = this.boundsRect.bottom - this.sprite.height;
    +            }
             }
     
         },
    @@ -1487,27 +1547,53 @@ Phaser.InputHandler.prototype = {
         */
         checkBoundsSprite: function () {
     
    -        if (this.sprite.x < this.boundsSprite.x)
    +        if (this.sprite.fixedToCamera && this.boundsSprite.fixedToCamera)
             {
    -            this.sprite.x = this.boundsSprite.x;
    -        }
    -        else if ((this.sprite.x + this.sprite.width) > (this.boundsSprite.x + this.boundsSprite.width))
    -        {
    -            this.sprite.x = (this.boundsSprite.x + this.boundsSprite.width) - this.sprite.width;
    -        }
    +            if (this.sprite.cameraOffset.x < this.boundsSprite.camerOffset.x)
    +            {
    +                this.sprite.cameraOffset.x = this.boundsSprite.camerOffset.x;
    +            }
    +            else if ((this.sprite.cameraOffset.x + this.sprite.width) > (this.boundsSprite.camerOffset.x + this.boundsSprite.width))
    +            {
    +                this.sprite.cameraOffset.x = (this.boundsSprite.camerOffset.x + this.boundsSprite.width) - this.sprite.width;
    +            }
     
    -        if (this.sprite.y < this.boundsSprite.y)
    -        {
    -            this.sprite.y = this.boundsSprite.y;
    +            if (this.sprite.cameraOffset.y < this.boundsSprite.camerOffset.y)
    +            {
    +                this.sprite.cameraOffset.y = this.boundsSprite.camerOffset.y;
    +            }
    +            else if ((this.sprite.cameraOffset.y + this.sprite.height) > (this.boundsSprite.camerOffset.y + this.boundsSprite.height))
    +            {
    +                this.sprite.cameraOffset.y = (this.boundsSprite.camerOffset.y + this.boundsSprite.height) - this.sprite.height;
    +            }
             }
    -        else if ((this.sprite.y + this.sprite.height) > (this.boundsSprite.y + this.boundsSprite.height))
    +        else
             {
    -            this.sprite.y = (this.boundsSprite.y + this.boundsSprite.height) - this.sprite.height;
    +            if (this.sprite.x < this.boundsSprite.x)
    +            {
    +                this.sprite.x = this.boundsSprite.x;
    +            }
    +            else if ((this.sprite.x + this.sprite.width) > (this.boundsSprite.x + this.boundsSprite.width))
    +            {
    +                this.sprite.x = (this.boundsSprite.x + this.boundsSprite.width) - this.sprite.width;
    +            }
    +
    +            if (this.sprite.y < this.boundsSprite.y)
    +            {
    +                this.sprite.y = this.boundsSprite.y;
    +            }
    +            else if ((this.sprite.y + this.sprite.height) > (this.boundsSprite.y + this.boundsSprite.height))
    +            {
    +                this.sprite.y = (this.boundsSprite.y + this.boundsSprite.height) - this.sprite.height;
    +            }
             }
     
         }
     
    -};
    +}; + +Phaser.InputHandler.prototype.constructor = Phaser.InputHandler; +
    @@ -1522,13 +1608,13 @@ Phaser.InputHandler.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/IntroDocs.js.html b/docs/IntroDocs.js.html index 9efbd205..664fba12 100644 --- a/docs/IntroDocs.js.html +++ b/docs/IntroDocs.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -381,7 +405,7 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -592,6 +586,8 @@ Phaser.Key.prototype = {
         }
     
     };
    +
    +Phaser.Key.prototype.constructor = Phaser.Key;
     
    @@ -607,13 +603,13 @@ Phaser.Key.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Keyboard.js.html b/docs/Keyboard.js.html index d7d6010a..4b428a4c 100644 --- a/docs/Keyboard.js.html +++ b/docs/Keyboard.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -523,7 +517,7 @@ Phaser.Keyboard.prototype = {
         * The Key object can then be polled, have events attached to it, etc.
         *
         * @method Phaser.Keyboard#addKey
    -    * @param {number} keycode - The keycode of the key, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR
    +    * @param {number} keycode - The keycode of the key, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR
         * @return {Phaser.Key} The Key object which you can store locally and reference directly.
         */
         addKey: function (keycode) {
    @@ -540,7 +534,7 @@ Phaser.Keyboard.prototype = {
         * Removes a Key object from the Keyboard manager.
         *
         * @method Phaser.Keyboard#removeKey
    -    * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR
    +    * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR
         */
         removeKey: function (keycode) {
     
    @@ -762,7 +756,7 @@ Phaser.Keyboard.prototype = {
         /**
         * Returns the "just pressed" state of the key. Just pressed is considered true if the key was pressed down within the duration given (default 250ms)
         * @method Phaser.Keyboard#justPressed
    -    * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR
    +    * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR
         * @param {number} [duration=250] - The duration below which the key is considered as being just pressed.
         * @return {boolean} True if the key is just pressed otherwise false.
         */
    @@ -781,8 +775,8 @@ Phaser.Keyboard.prototype = {
     
         /**
         * Returns the "just released" state of the Key. Just released is considered as being true if the key was released within the duration given (default 250ms)
    -    * @method Phaser.Keyboard#justPressed
    -    * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR
    +    * @method Phaser.Keyboard#justReleased
    +    * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR
         * @param {number} [duration=250] - The duration below which the key is considered as being just released.
         * @return {boolean} True if the key is just released otherwise false.
         */
    @@ -802,7 +796,7 @@ Phaser.Keyboard.prototype = {
         /**
         * Returns true of the key is currently pressed down. Note that it can only detect key presses on the web browser.
         * @method Phaser.Keyboard#isDown
    -    * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR
    +    * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR
         * @return {boolean} True if the key is currently down.
         */
         isDown: function (keycode) {
    @@ -818,6 +812,8 @@ Phaser.Keyboard.prototype = {
     
     };
     
    +Phaser.Keyboard.prototype.constructor = Phaser.Keyboard;
    +
     Phaser.Keyboard.A = "A".charCodeAt(0);
     Phaser.Keyboard.B = "B".charCodeAt(0);
     Phaser.Keyboard.C = "C".charCodeAt(0);
    @@ -931,13 +927,13 @@ Phaser.Keyboard.NUM_LOCK = 144;
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Line.js.html b/docs/Line.js.html new file mode 100644 index 00000000..aa41210f --- /dev/null +++ b/docs/Line.js.html @@ -0,0 +1,743 @@ + + + + + + Phaser Source: geom/Line.js + + + + + + + + + + +
    + + +
    + + +
    + +
    + + + +

    Source: geom/Line.js

    + +
    +
    +
    /**
    +* @author       Richard Davey <rich@photonstorm.com>
    +* @copyright    2014 Photon Storm Ltd.
    +* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
    +*/
    +
    +/**
    +* Creates a new Line object with a start and an end point.
    +* @class Line
    +* @classdesc Phaser - Line
    +* @constructor
    +* @param {number} [x1=0] - The x coordinate of the start of the line.
    +* @param {number} [y1=0] - The y coordinate of the start of the line.
    +* @param {number} [x2=0] - The x coordinate of the end of the line.
    +* @param {number} [y2=0] - The y coordinate of the end of the line.
    +* @return {Phaser.Line} This line object
    +*/
    +Phaser.Line = function (x1, y1, x2, y2) {
    +
    +    x1 = x1 || 0;
    +    y1 = y1 || 0;
    +    x2 = x2 || 0;
    +    y2 = y2 || 0;
    +
    +    /**
    +    * @property {Phaser.Point} start - The start point of the line.
    +    */
    +    this.start = new Phaser.Point(x1, y1);
    +
    +    /**
    +    * @property {Phaser.Point} end - The end point of the line.
    +    */
    +    this.end = new Phaser.Point(x2, y2);
    +
    +};
    +
    +Phaser.Line.prototype = {
    +
    +    /**
    +    * Sets the components of the Line to the specified values.
    +    * @method Phaser.Line#setTo
    +    * @param {number} [x1=0] - The x coordinate of the start of the line.
    +    * @param {number} [y1=0] - The y coordinate of the start of the line.
    +    * @param {number} [x2=0] - The x coordinate of the end of the line.
    +    * @param {number} [y2=0] - The y coordinate of the end of the line.
    +    * @return {Phaser.Line} This line object
    +    */
    +    setTo: function (x1, y1, x2, y2) {
    +
    +        this.start.setTo(x1, y1);
    +        this.end.setTo(x2, y2);
    +
    +        return this;
    +
    +    },
    +
    +    /**
    +    * Sets the line to match the x/y coordinates of the two given sprites.
    +    * Can optionally be calculated from their center coordinates.
    +    * @method Phaser.Line#fromSprite
    +    * @param {Phaser.Sprite} startSprite - The coordinates of this Sprite will be set to the Line.start point.
    +    * @param {Phaser.Sprite} endSprite - The coordinates of this Sprite will be set to the Line.start point.
    +    * @param {boolean} [useCenter=true] - If true it will use startSprite.center.x, if false startSprite.x.
    +    * @return {Phaser.Line} This line object
    +    */
    +    fromSprite: function (startSprite, endSprite, useCenter) {
    +
    +        if (typeof useCenter === 'undefined') { useCenter = true; }
    +
    +        if (useCenter)
    +        {
    +            return this.setTo(startSprite.center.x, startSprite.center.y, endSprite.center.x, endSprite.center.y);
    +        }
    +        else
    +        {
    +            return this.setTo(startSprite.x, startSprite.y, endSprite.x, endSprite.y);
    +        }
    +
    +    },
    +
    +    /**
    +    * Checks for intersection between this line and another Line.
    +    * If asSegment is true it will check for segment intersection. If asSegment is false it will check for line intersection.
    +    * Returns the intersection segment of AB and EF as a Point, or null if there is no intersection.
    +    *
    +    * @method Phaser.Line#intersects
    +    * @param {Phaser.Line} line - The line to check against this one.
    +    * @param {boolean} [asSegment=true] - If true it will check for segment intersection, otherwise full line intersection.
    +    * @param {Phaser.Point} [result] - A Point object to store the result in, if not given a new one will be created.
    +    * @return {Phaser.Point} The intersection segment of the two lines as a Point, or null if there is no intersection.
    +    */
    +    intersects: function (line, asSegment, result) {
    +
    +        return Phaser.Line.intersectsPoints(this.start, this.end, line.start, line.end, asSegment, result);
    +
    +    },
    +
    +    /**
    +    * Tests if the given coordinates fall on this line. See pointOnSegment to test against just the line segment.
    +    * @method Phaser.Line#pointOnLine
    +    * @param {number} x - The line to check against this one.
    +    * @param {number} y - The line to check against this one.
    +    * @return {boolean} True if the point is on the line, false if not.
    +    */
    +    pointOnLine: function (x, y) {
    +
    +        return ((x - this.start.x) * (this.end.y - this.end.y) === (this.end.x - this.start.x) * (y - this.end.y));
    +
    +    },
    +
    +    /**
    +    * Tests if the given coordinates fall on this line and within the segment. See pointOnLine to test against just the line.
    +    * @method Phaser.Line#pointOnSegment
    +    * @param {number} x - The line to check against this one.
    +    * @param {number} y - The line to check against this one.
    +    * @return {boolean} True if the point is on the line and segment, false if not.
    +    */
    +    pointOnSegment: function (x, y) {
    +
    +        var xMin = Math.min(this.start.x, this.end.x);
    +        var xMax = Math.max(this.start.x, this.end.x);
    +        var yMin = Math.min(this.start.y, this.end.y);
    +        var yMax = Math.max(this.start.y, this.end.y);
    +
    +        return (this.pointOnLine(x, y) && (x >= xMin && x <= xMax) && (y >= yMin && y <= yMax));
    +
    +    }
    +
    +};
    +
    +/**
    +* @name Phaser.Line#length
    +* @property {number} length - Gets the length of the line segment.
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Line.prototype, "length", {
    +
    +    get: function () {
    +        return Math.sqrt((this.end.x - this.start.x) * (this.end.x - this.start.x) + (this.end.y - this.start.y) * (this.end.y - this.start.y));
    +    }
    +
    +});
    +
    +/**
    +* @name Phaser.Line#angle
    +* @property {number} angle - Gets the angle of the line.
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Line.prototype, "angle", {
    +
    +    get: function () {
    +        return Math.atan2(this.end.x - this.start.x, this.end.y - this.start.y);
    +    }
    +
    +});
    +
    +/**
    +* @name Phaser.Line#slope
    +* @property {number} slope - Gets the slope of the line (y/x).
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Line.prototype, "slope", {
    +
    +    get: function () {
    +        return (this.end.y - this.start.y) / (this.end.x - this.start.x);
    +    }
    +
    +});
    +
    +/**
    +* @name Phaser.Line#perpSlope
    +* @property {number} perpSlope - Gets the perpendicular slope of the line (x/y).
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Line.prototype, "perpSlope", {
    +
    +    get: function () {
    +        return -((this.end.x - this.start.x) / (this.end.y - this.start.y));
    +    }
    +
    +});
    +
    +/**
    +* Checks for intersection between two lines as defined by the given start and end points.
    +* If asSegment is true it will check for line segment intersection. If asSegment is false it will check for line intersection.
    +* Returns the intersection segment of AB and EF as a Point, or null if there is no intersection.
    +* Adapted from code by Keith Hair
    +*
    +* @method Phaser.Line.intersects
    +* @param {Phaser.Point} a - The start of the first Line to be checked.
    +* @param {Phaser.Point} b - The end of the first line to be checked.
    +* @param {Phaser.Point} e - The start of the second Line to be checked.
    +* @param {Phaser.Point} f - The end of the second line to be checked.
    +* @param {boolean} [asSegment=true] - If true it will check for segment intersection, otherwise full line intersection.
    +* @param {Phaser.Point} [result] - A Point object to store the result in, if not given a new one will be created.
    +* @return {Phaser.Point} The intersection segment of the two lines as a Point, or null if there is no intersection.
    +*/
    +Phaser.Line.intersectsPoints = function (a, b, e, f, asSegment, result) {
    +
    +    if (typeof asSegment === 'undefined') { asSegment = true; }
    +    if (typeof result === 'undefined') { result = new Phaser.Point(); }
    +
    +    var a1 = b.y - a.y;
    +    var a2 = f.y - e.y;
    +    var b1 = a.x - b.x;
    +    var b2 = e.x - f.x;
    +    var c1 = (b.x * a.y) - (a.x * b.y);
    +    var c2 = (f.x * e.y) - (e.x * f.y);
    +    var denom = (a1 * b2) - (a2 * b1);
    +
    +    if (denom === 0)
    +    {
    +        return null;
    +    }
    +
    +    result.x = ((b1 * c2) - (b2 * c1)) / denom;
    +    result.y = ((a2 * c1) - (a1 * c2)) / denom;
    + 
    +    if (asSegment)
    +    {
    +        if (Math.pow((result.x - b.x) + (result.y - b.y), 2) > Math.pow((a.x - b.x) + (a.y - b.y), 2))
    +        {
    +            return null;
    +        }
    +
    +        if (Math.pow((result.x - a.x) + (result.y - a.y), 2) > Math.pow((a.x - b.x) + (a.y - b.y), 2))
    +        {
    +            return null;
    +        }
    +
    +        if (Math.pow((result.x - f.x) + (result.y - f.y), 2) > Math.pow((e.x - f.x) + (e.y - f.y), 2))
    +        {
    +            return null;
    +        }
    +
    +        if (Math.pow((result.x - e.x) + (result.y - e.y), 2) > Math.pow((e.x - f.x) + (e.y - f.y), 2))
    +        {
    +            return null;
    +        }
    +    }
    +
    +    return result;
    +
    +};
    +
    +/**
    +* Checks for intersection between two lines.
    +* If asSegment is true it will check for segment intersection.
    +* If asSegment is false it will check for line intersection.
    +* Returns the intersection segment of AB and EF as a Point, or null if there is no intersection.
    +* Adapted from code by Keith Hair
    +*
    +* @method Phaser.Line.intersects
    +* @param {Phaser.Line} a - The first Line to be checked.
    +* @param {Phaser.Line} b - The second Line to be checked.
    +* @param {boolean} [asSegment=true] - If true it will check for segment intersection, otherwise full line intersection.
    +* @param {Phaser.Point} [result] - A Point object to store the result in, if not given a new one will be created.
    +* @return {Phaser.Point} The intersection segment of the two lines as a Point, or null if there is no intersection.
    +*/
    +Phaser.Line.intersects = function (a, b, asSegment, result) {
    +
    +    return Phaser.Line.intersectsPoints(a.start, a.end, b.start, b.end, asSegment, result);
    +
    +};
    +
    +
    +
    + + + + + +
    + +
    +
    + + + + Phaser Copyright © 2012-2014 Photon Storm Ltd. + +
    + + + Documentation generated by JSDoc 3.3.0-dev + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + diff --git a/docs/LinkedList.js.html b/docs/LinkedList.js.html index 82354172..dce1bbe0 100644 --- a/docs/LinkedList.js.html +++ b/docs/LinkedList.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -574,7 +568,10 @@ Phaser.LinkedList.prototype = {
     
         }
     
    -};
    +}; + +Phaser.LinkedList.prototype.constructor = Phaser.LinkedList; +
    @@ -589,13 +586,13 @@ Phaser.LinkedList.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Loader.js.html b/docs/Loader.js.html index bd0e0d33..6dde3054 100644 --- a/docs/Loader.js.html +++ b/docs/Loader.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -457,7 +451,7 @@ Phaser.Loader = function (game) {
         this._fileIndex = 0;
     
         /**
    -    * @property {number} _progressChunk - Indicates assets loading progress. (from 0 to 100)
    +    * @property {number} _progressChunk - Indicates the size of 1 file in terms of a percentage out of 100.
         * @private
         * @default
         */
    @@ -482,15 +476,21 @@ Phaser.Loader = function (game) {
         this.hasLoaded = false;
     
         /**
    -    * @property {number} progress - The Load progress percentage value (from 0 to 100)
    +    * @property {number} progress - The rounded load progress percentage value (from 0 to 100)
         * @default
         */
         this.progress = 0;
     
    +    /**
    +    * @property {number} progressFloat - The non-rounded load progress value (from 0.0 to 100.0)
    +    * @default
    +    */
    +    this.progressFloat = 0;
    +
         /**
         * You can optionally link a sprite to the preloader.
         * If you do so the Sprite's width or height will be cropped based on the percentage loaded.
    -    * @property {Description} preloadSprite
    +    * @property {Phaser.Sprite} preloadSprite
         * @default
         */
         this.preloadSprite = null;
    @@ -786,6 +786,29 @@ Phaser.Loader.prototype = {
     
         },
     
    +    /**
    +    * Add a binary file to the Loader. It will be loaded via xhr with a responseType of "arraybuffer". You can specify an optional callback to process the file after load.
    +    * When the callback is called it will be passed 2 parameters: the key of the file and the file data.
    +    * WARNING: If you specify a callback, the file data will be set to whatever your callback returns. So always return the data object, even if you didn't modify it.
    +    *
    +    * @method Phaser.Loader#binary
    +    * @param {string} key - Unique asset key of the binary file.
    +    * @param {string} url - URL of the binary file.
    +    * @param {function} [callback] - Optional callback that will be passed the file after loading, so you can perform additional processing on it.
    +    * @param {function} [callbackContext] - The context under which the callback will be applied. If not specified it will use the callback itself as the context.
    +    * @return {Phaser.Loader} This Loader instance.
    +    */
    +    binary: function (key, url, callback, callbackContext) {
    +
    +        if (typeof callback === 'undefined') { callback = false; }
    +        if (callback !== false && typeof callbackContext === 'undefined') { callbackContext = callback; }
    +
    +        this.addToFileList('binary', key, url, { callback: callback, callbackContext: callbackContext });
    +
    +        return this;
    +
    +    },
    +
         /**
         * Add a new sprite sheet to the loader.
         *
    @@ -795,38 +818,17 @@ Phaser.Loader.prototype = {
         * @param {number} frameWidth - Width of each single frame.
         * @param {number} frameHeight - Height of each single frame.
         * @param {number} [frameMax=-1] - How many frames in this sprite sheet. If not specified it will divide the whole image into frames.
    +    * @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here.
    +    * @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here.
         * @return {Phaser.Loader} This Loader instance.
         */
    -    spritesheet: function (key, url, frameWidth, frameHeight, frameMax) {
    +    spritesheet: function (key, url, frameWidth, frameHeight, frameMax, margin, spacing) {
     
             if (typeof frameMax === "undefined") { frameMax = -1; }
    +        if (typeof margin === "undefined") { margin = 0; }
    +        if (typeof spacing === "undefined") { spacing = 0; }
     
    -        this.addToFileList('spritesheet', key, url, { frameWidth: frameWidth, frameHeight: frameHeight, frameMax: frameMax });
    -
    -        return this;
    -
    -    },
    -
    -    /**
    -    * Add a new tile set to the loader. These are used in the rendering of tile maps.
    -    *
    -    * @method Phaser.Loader#tileset
    -    * @param {string} key - Unique asset key of the tileset file.
    -    * @param {string} url - URL of the tileset.
    -    * @param {number} tileWidth - Width of each single tile in pixels.
    -    * @param {number} tileHeight - Height of each single tile in pixels.
    -    * @param {number} [tileMax=-1] - How many tiles in this tileset. If not specified it will divide the whole image into tiles.
    -    * @param {number} [tileMargin=0] - If the tiles have been drawn with a margin, specify the amount here.
    -    * @param {number} [tileSpacing=0] - If the tiles have been drawn with spacing between them, specify the amount here.
    -    * @return {Phaser.Loader} This Loader instance.
    -    */
    -    tileset: function (key, url, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) {
    -
    -        if (typeof tileMax === "undefined") { tileMax = -1; }
    -        if (typeof tileMargin === "undefined") { tileMargin = 0; }
    -        if (typeof tileSpacing === "undefined") { tileSpacing = 0; }
    -
    -        this.addToFileList('tileset', key, url, { tileWidth: tileWidth, tileHeight: tileHeight, tileMax: tileMax, tileMargin: tileMargin, tileSpacing: tileSpacing });
    +        this.addToFileList('spritesheet', key, url, { frameWidth: frameWidth, frameHeight: frameHeight, frameMax: frameMax, margin: margin, spacing: spacing });
     
             return this;
     
    @@ -1134,6 +1136,7 @@ Phaser.Loader.prototype = {
             }
     
             this.progress = 0;
    +        this.progressFloat = 0;
             this.hasLoaded = false;
             this.isLoading = true;
     
    @@ -1148,6 +1151,7 @@ Phaser.Loader.prototype = {
             else
             {
                 this.progress = 100;
    +            this.progressFloat = 100;
                 this.hasLoaded = true;
                 this.onLoadComplete.dispatch();
             }
    @@ -1178,7 +1182,6 @@ Phaser.Loader.prototype = {
                 case 'spritesheet':
                 case 'textureatlas':
                 case 'bitmapfont':
    -            case 'tileset':
                     file.data = new Image();
                     file.data.name = file.key;
                     file.data.onload = function () {
    @@ -1269,6 +1272,7 @@ Phaser.Loader.prototype = {
                     break;
     
                 case 'text':
    +            case 'script':
                     this._xhr.open("GET", this.baseURL + file.url, true);
                     this._xhr.responseType = "text";
                     this._xhr.onload = function () {
    @@ -1280,10 +1284,9 @@ Phaser.Loader.prototype = {
                     this._xhr.send();
                     break;
     
    -            case 'script':
    -
    +            case 'binary':
                     this._xhr.open("GET", this.baseURL + file.url, true);
    -                this._xhr.responseType = "text";
    +                this._xhr.responseType = "arraybuffer";
                     this._xhr.onload = function () {
                         return _this.fileComplete(_this._fileIndex);
                     };
    @@ -1356,7 +1359,6 @@ Phaser.Loader.prototype = {
                 console.warn('Phaser.Loader fileComplete invalid index ' + index);
                 return;
             }
    -        
     
             var file = this._fileList[index];
             file.loaded = true;
    @@ -1373,12 +1375,7 @@ Phaser.Loader.prototype = {
     
                 case 'spritesheet':
     
    -                this.game.cache.addSpriteSheet(file.key, file.url, file.data, file.frameWidth, file.frameHeight, file.frameMax);
    -                break;
    -
    -            case 'tileset':
    -
    -                this.game.cache.addTileset(file.key, file.url, file.data, file.tileWidth, file.tileHeight, file.tileMax, file.tileMargin, file.tileSpacing);
    +                this.game.cache.addSpriteSheet(file.key, file.url, file.data, file.frameWidth, file.frameHeight, file.frameMax, file.margin, file.spacing);
                     break;
     
                 case 'textureatlas':
    @@ -1461,6 +1458,7 @@ Phaser.Loader.prototype = {
                                 if (buffer)
                                 {
                                     that.game.cache.decodedSound(key, buffer);
    +                                that.game.sound.onSoundDecode.dispatch(key, that.game.cache.getSound(key));
                                 }
                             });
                         }
    @@ -1481,10 +1479,24 @@ Phaser.Loader.prototype = {
                     file.data = document.createElement('script');
                     file.data.language = 'javascript';
                     file.data.type = 'text/javascript';
    -                file.data.defer = true;
    +                file.data.defer = false;
                     file.data.text = this._xhr.responseText;
                     document.head.appendChild(file.data);
                     break;
    +
    +            case 'binary':
    +                if (file.callback)
    +                {
    +                    file.data = file.callback.call(file.callbackContext, file.key, this._xhr.response);
    +                }
    +                else
    +                {
    +                    file.data = this._xhr.response;
    +                }
    +
    +                this.game.cache.addBinary(file.key, file.data);
    +
    +                break;
             }
     
             if (loadNext)
    @@ -1630,7 +1642,8 @@ Phaser.Loader.prototype = {
         */
         nextFile: function (previousIndex, success) {
     
    -        this.progress = Math.round(this.progress + this._progressChunk);
    +        this.progressFloat += this._progressChunk;
    +        this.progress = Math.round(this.progressFloat);
     
             if (this.progress > 100)
             {
    @@ -1713,6 +1726,8 @@ Phaser.Loader.prototype = {
         }
     
     };
    +
    +Phaser.Loader.prototype.constructor = Phaser.Loader;
     
    @@ -1728,13 +1743,13 @@ Phaser.Loader.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/LoaderParser.js.html b/docs/LoaderParser.js.html index eefdaba6..bd280b4c 100644 --- a/docs/LoaderParser.js.html +++ b/docs/LoaderParser.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -518,13 +512,13 @@ Phaser.LoaderParser = {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/MSPointer.js.html b/docs/MSPointer.js.html index 88f18043..014729ff 100644 --- a/docs/MSPointer.js.html +++ b/docs/MSPointer.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -588,7 +582,10 @@ Phaser.MSPointer.prototype = {
     
         }
     
    -};
    +}; + +Phaser.MSPointer.prototype.constructor = Phaser.MSPointer; +
    @@ -603,13 +600,13 @@ Phaser.MSPointer.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Math.js.html b/docs/Math.js.html index 087509fe..166ea58e 100644 --- a/docs/Math.js.html +++ b/docs/Math.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -750,7 +744,7 @@ Phaser.Math = {
         },
     
         /**
    -    * Find the angle of a segment from (x1, y1) -> (x2, y2 ).
    +    * Find the angle of a segment from (x1, y1) -> (x2, y2).
         * @method Phaser.Math#angleBetween
         * @param {number} x1
         * @param {number} y1
    @@ -763,24 +757,58 @@ Phaser.Math = {
         },
     
         /**
    -    * Set an angle  within the bounds of -π toπ.
    -    * @method Phaser.Math#normalizeAngle
    -    * @param {number} angle
    -    * @param {boolean} radians - True if angle size is expressed in radians.
    -    * @return {number}
    +    * Reverses an angle.
    +    * @method Phaser.Math#reverseAngle
    +    * @param {number} angleRad - The angle to reverse, in radians.
    +    * @return {number} Returns the reverse angle, in radians.
         */
    -    normalizeAngle: function (angle, radians) {
    +    reverseAngle: function (angleRad) {
    +        return this.normalizeAngle(angleRad + Math.PI, true);
    +    },
     
    -        if (typeof radians === "undefined") { radians = true; }
    +    /**
    +    * Normalizes an angle to the [0,2pi) range.
    +    * @method Phaser.Math#normalizeAngle
    +    * @param {number} angleRad - The angle to normalize, in radians.
    +    * @return {number} Returns the angle, fit within the [0,2pi] range, in radians.
    +    */
    +    normalizeAngle: function (angleRad) {
     
    -        var rd = (radians) ? Math.PI : 180;
    -        return this.wrap(angle, -rd, rd);
    +        angleRad = angleRad % (2 * Math.PI);
    +        return angleRad >= 0 ? angleRad : angleRad + 2 * Math.PI;
             
         },
     
         /**
    -    * Closest angle between two angles from a1 to a2
    -    * absolute value the return for exact angle
    +    * Normalizes a latitude to the [-90,90] range. Latitudes above 90 or below -90 are capped, not wrapped.
    +    * @method Phaser.Math#normalizeLatitude
    +    * @param {number} lat - The latitude to normalize, in degrees.
    +    * @return {number} Returns the latitude, fit within the [-90,90] range.
    +    */
    +    normalizeLatitude: function (lat) {
    +        return Math.max(-90, Math.min(90, lat));
    +    },
    +
    +    /**
    +    * Normalizes a longitude to the [-180,180] range. Longitudes above 180 or below -180 are wrapped.
    +    * @method Phaser.Math#normalizeLongitude
    +    * @param {number} lng - The longitude to normalize, in degrees.
    +    * @return {number} Returns the longitude, fit within the [-180,180] range.
    +    */
    +    normalizeLongitude: function (lng) {
    +
    +        if (lng % 360 == 180)
    +        {
    +            return 180;
    +        }
    +
    +        lng = lng % 360;
    +        return lng < -180 ? lng + 360 : lng > 180 ? lng - 360 : lng;
    +
    +    },
    +
    +    /**
    +    * Closest angle between two angles from a1 to a2 absolute value the return for exact angle
         * @method Phaser.Math#nearestAngleBetween
         * @param {number} a1
         * @param {number} a2
    @@ -934,13 +962,13 @@ Phaser.Math = {
     
         /**
         * Ensures that the value always stays between min and max, by wrapping the value around.
    -    * <p>max should be larger than min, or the function will return 0</p>
    +    * max should be larger than min, or the function will return 0.
         *
         * @method Phaser.Math#wrap
    -    * @param value The value to wrap
    -    * @param min The minimum the value is allowed to be
    -    * @param max The maximum the value is allowed to be
    -    * @return {number} The wrapped value
    +    * @param {number} value - The value to wrap.
    +    * @param {number} min - The minimum the value is allowed to be.
    +    * @param {number} max - The maximum the value is allowed to be.
    +    * @return {number} The wrapped value.
         */
         wrap: function (value, min, max) {
     
    @@ -1049,7 +1077,7 @@ Phaser.Math = {
         },
     
         /**
    -    * Significantly faster version of Math.min
    +    * Updated version of Math.min that can be passed either an array of numbers or the numbers as parameters.
         * See http://jsperf.com/math-s-min-max-vs-homemade/5
         *
         * @method Phaser.Math#min
    @@ -1057,15 +1085,113 @@ Phaser.Math = {
         */
         min: function () {
     
    -        for (var i =1 , min = 0, len = arguments.length; i < len; i++)
    +        if (arguments.length === 1 && typeof arguments[0] === 'object')
             {
    -            if (arguments[i] < arguments[min])
    +            var data = arguments[0];
    +        }
    +        else
    +        {
    +            var data = arguments;
    +        }
    +
    +        for (var i = 1, min = 0, len = data.length; i < len; i++)
    +        {
    +            if (data[i] < data[min])
                 {
                     min = i;
                 }
             }
     
    -        return arguments[min];
    +        return data[min];
    +
    +    },
    +
    +    /**
    +    * Updated version of Math.max that can be passed either an array of numbers or the numbers as parameters.
    +    *
    +    * @method Phaser.Math#max
    +    * @return {number} The largest value from those given.
    +    */
    +    max: function () {
    +
    +        if (arguments.length === 1 && typeof arguments[0] === 'object')
    +        {
    +            var data = arguments[0];
    +        }
    +        else
    +        {
    +            var data = arguments;
    +        }
    +
    +        for (var i = 1, max = 0, len = data.length; i < len; i++)
    +        {
    +            if (data[i] > data[max])
    +            {
    +                max = i;
    +            }
    +        }
    +
    +        return data[max];
    +
    +    },
    +
    +    /**
    +    * Updated version of Math.min that can be passed a property and either an array of objects or the objects as parameters.
    +    * It will find the lowest matching property value from the given objects.
    +    *
    +    * @method Phaser.Math#minProperty
    +    * @return {number} The lowest value from those given.
    +    */
    +    minProperty: function (property) {
    +
    +        if (arguments.length === 2 && typeof arguments[1] === 'object')
    +        {
    +            var data = arguments[1];
    +        }
    +        else
    +        {
    +            var data = arguments.slice(1);
    +        }
    +
    +        for (var i = 1, min = 0, len = data.length; i < len; i++)
    +        {
    +            if (data[i][property] < data[min][property])
    +            {
    +                min = i;
    +            }
    +        }
    +
    +        return data[min][property];
    +
    +    },
    +
    +    /**
    +    * Updated version of Math.max that can be passed a property and either an array of objects or the objects as parameters.
    +    * It will find the largest matching property value from the given objects.
    +    *
    +    * @method Phaser.Math#maxProperty
    +    * @return {number} The largest value from those given.
    +    */
    +    maxProperty: function (property) {
    +
    +        if (arguments.length === 2 && typeof arguments[1] === 'object')
    +        {
    +            var data = arguments[1];
    +        }
    +        else
    +        {
    +            var data = arguments.slice(1);
    +        }
    +
    +        for (var i = 1, max = 0, len = data.length; i < len; i++)
    +        {
    +            if (data[i][property] > data[max][property])
    +            {
    +                max = i;
    +            }
    +        }
    +
    +        return data[max][property];
     
         },
     
    @@ -1111,7 +1237,7 @@ Phaser.Math = {
         },
     
         /**
    -    * Description.
    +    * A Linear Interpolation Method, mostly used by Phaser.Tween.
         * @method Phaser.Math#linearInterpolation
         * @param {number} v
         * @param {number} k
    @@ -1138,7 +1264,7 @@ Phaser.Math = {
         },
     
         /**
    -    * Description.
    +    * A Bezier Interpolation Method, mostly used by Phaser.Tween.
         * @method Phaser.Math#bezierInterpolation
         * @param {number} v
         * @param {number} k
    @@ -1159,7 +1285,7 @@ Phaser.Math = {
         },
     
         /**
    -    * Description.
    +    * A Catmull Rom Interpolation Method, mostly used by Phaser.Tween.
         * @method Phaser.Math#catmullRomInterpolation
         * @param {number} v
         * @param {number} k
    @@ -1394,7 +1520,7 @@ Phaser.Math = {
         * @param {number} y1
         * @param {number} x2
         * @param {number} y2
    -    * @return {number} The distance between this Point object and the destination Point object.
    +    * @return {number} The distance between the two sets of coordinates.
         */
         distance: function (x1, y1, x2, y2) {
     
    @@ -1405,6 +1531,25 @@ Phaser.Math = {
     
         },
     
    +    /**
    +    * Returns the distance between the two given set of coordinates at the power given.
    +    * 
    +    * @method Phaser.Math#distancePow
    +    * @param {number} x1
    +    * @param {number} y1
    +    * @param {number} x2
    +    * @param {number} y2
    +    * @param {number} [pow=2]
    +    * @return {number} The distance between the two sets of coordinates.
    +    */
    +    distancePow: function (x1, y1, x2, y2, pow) {
    +
    +        if (typeof pow === 'undefined') { pow = 2; }
    +
    +        return Math.sqrt(Math.pow(x2 - x1, pow) + Math.pow(y2 - y1, pow));
    +
    +    },
    +
         /**
         * Returns the rounded distance between the two given set of coordinates.
         * 
    @@ -1604,13 +1749,13 @@ Phaser.Math = {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Mouse.js.html b/docs/Mouse.js.html index 4dbbdc0f..c1518e11 100644 --- a/docs/Mouse.js.html +++ b/docs/Mouse.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -491,7 +485,8 @@ Phaser.Mouse = function (game) {
         this.pointerLock = new Phaser.Signal();
     
         /**
    -    * @property {MouseEvent} event - The browser mouse event.
    +    * @property {MouseEvent} event - The browser mouse DOM event. Will be set to null if no mouse event has ever been received.
    +    * @default
         */
         this.event = null;
     
    @@ -749,6 +744,8 @@ Phaser.Mouse.prototype = {
         }
     
     };
    +
    +Phaser.Mouse.prototype.constructor = Phaser.Mouse;
     
    @@ -764,13 +761,13 @@ Phaser.Mouse.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Net.js.html b/docs/Net.js.html index 8494000a..b9b79823 100644 --- a/docs/Net.js.html +++ b/docs/Net.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -551,8 +545,8 @@ Phaser.Net.prototype = {
             var output = {};
             var keyValues = location.search.substring(1).split('&');
     
    -        for (var i in keyValues) {
    -
    +        for (var i in keyValues)
    +        {
                 var key = keyValues[i].split('=');
     
                 if (key.length > 1)
    @@ -585,6 +579,8 @@ Phaser.Net.prototype = {
         }
     
     };
    +
    +Phaser.Net.prototype.constructor = Phaser.Net;
     
    @@ -600,13 +596,13 @@ Phaser.Net.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Particles.js.html b/docs/Particles.js.html index 501ff851..89d16184 100644 --- a/docs/Particles.js.html +++ b/docs/Particles.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -499,7 +493,10 @@ Phaser.Particles.prototype = {
     
         }
     
    -};
    +}; + +Phaser.Particles.prototype.constructor = Phaser.Particles; +
    @@ -514,13 +511,13 @@ Phaser.Particles.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Animation.html b/docs/Phaser.Animation.html index c2b32417..3ea9c67e 100644 --- a/docs/Phaser.Animation.html +++ b/docs/Phaser.Animation.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -579,10 +573,10 @@ It is created by the AnimationManager, consists of Animation.Frame objects and b -Array.<number> +Array.<number> | -Array.<string> +Array.<string> @@ -798,7 +792,7 @@ It is created by the AnimationManager, consists of Animation.Frame objects and b
    Source:
    @@ -1002,7 +996,7 @@ It is created by the AnimationManager, consists of Animation.Frame objects and b
    Source:
    @@ -1104,7 +1098,7 @@ It is created by the AnimationManager, consists of Animation.Frame objects and b
    Source:
    @@ -1311,7 +1305,7 @@ It is created by the AnimationManager, consists of Animation.Frame objects and b
    Source:
    @@ -1416,7 +1410,7 @@ It is created by the AnimationManager, consists of Animation.Frame objects and b
    Source:
    @@ -1521,7 +1515,7 @@ It is created by the AnimationManager, consists of Animation.Frame objects and b
    Source:
    @@ -1578,7 +1572,7 @@ It is created by the AnimationManager, consists of Animation.Frame objects and b - looped + killOnComplete @@ -1594,7 +1588,7 @@ It is created by the AnimationManager, consists of Animation.Frame objects and b -

    The loop state of the Animation.

    +

    Should the parent of this Animation be killed when the animation completes?

    @@ -1619,11 +1613,14 @@ It is created by the AnimationManager, consists of Animation.Frame objects and b +
    Default Value:
    +
    • false
    +
    Source:
    @@ -1929,7 +1926,7 @@ It is created by the AnimationManager, consists of Animation.Frame objects and b
    Source:
    @@ -2209,7 +2206,7 @@ You could use this function to generate those by doing: Phaser.Animation.generat
    Source:
    @@ -2278,7 +2275,7 @@ You could use this function to generate those by doing: Phaser.Animation.generat
    Source:
    @@ -2347,7 +2344,7 @@ You could use this function to generate those by doing: Phaser.Animation.generat
    Source:
    @@ -2563,7 +2560,7 @@ You could use this function to generate those by doing: Phaser.Animation.generat
    Source:
    @@ -2657,7 +2654,7 @@ You could use this function to generate those by doing: Phaser.Animation.generat
    Source:
    @@ -2795,7 +2792,7 @@ You could use this function to generate those by doing: Phaser.Animation.generat
    Source:
    @@ -2864,7 +2861,7 @@ You could use this function to generate those by doing: Phaser.Animation.generat
    Source:
    @@ -2909,13 +2906,13 @@ You could use this function to generate those by doing: Phaser.Animation.generat - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:26 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:25 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.AnimationManager.html b/docs/Phaser.AnimationManager.html index 344ada58..4609bb4a 100644 --- a/docs/Phaser.AnimationManager.html +++ b/docs/Phaser.AnimationManager.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -762,7 +756,7 @@ Any Game Object such as Phaser.Sprite that supports animation contains a single
    Source:
    @@ -864,7 +858,7 @@ Any Game Object such as Phaser.Sprite that supports animation contains a single
    Source:
    @@ -966,7 +960,7 @@ Any Game Object such as Phaser.Sprite that supports animation contains a single
    Source:
    @@ -1068,7 +1062,7 @@ Any Game Object such as Phaser.Sprite that supports animation contains a single
    Source:
    @@ -1377,7 +1371,7 @@ Any Game Object such as Phaser.Sprite that supports animation contains a single
    Source:
    @@ -1696,7 +1690,7 @@ Animations added in this way are played back with the play function.

    -Array +Array @@ -2801,7 +2795,7 @@ The currentAnim property of the AnimationManager is automatically set to the ani -Array +Array @@ -2962,13 +2956,13 @@ The currentAnim property of the AnimationManager is automatically set to the ani - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:26 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:25 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.AnimationParser.html b/docs/Phaser.AnimationParser.html index 97906828..ca5b0c11 100644 --- a/docs/Phaser.AnimationParser.html +++ b/docs/Phaser.AnimationParser.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -659,7 +653,7 @@
    Source:
    @@ -846,7 +840,7 @@
    Source:
    @@ -897,7 +891,7 @@
    -

    <static> spriteSheet(game, key, frameWidth, frameHeight, frameMax) → {Phaser.FrameData}

    +

    <static> spriteSheet(game, key, frameWidth, frameHeight, frameMax, margin, spacing) → {Phaser.FrameData}

    @@ -1119,6 +1113,84 @@ + + + + margin + + + + + +number + + + + + + + + + <optional>
    + + + + + + + + + + + + 0 + + + + +

    If the frames have been drawn with a margin, specify the amount here.

    + + + + + + + spacing + + + + + +number + + + + + + + + + <optional>
    + + + + + + + + + + + + 0 + + + + +

    If the frames have been drawn with spacing between them, specify the amount here.

    + + + @@ -1334,7 +1406,7 @@
    Source:
    @@ -1402,13 +1474,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:26 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:25 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.BitmapData.html b/docs/Phaser.BitmapData.html index e561604f..b1f396be 100644 --- a/docs/Phaser.BitmapData.html +++ b/docs/Phaser.BitmapData.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1940,7 +1934,7 @@ for multiple Sprites. So if you need to dynamically create a Sprite texture then
    Source:
    @@ -2815,7 +2809,7 @@ going in the given direction by anticlockwise (defaulting to clockwise).

    Source:
    @@ -3034,7 +3028,7 @@ example, the following code defines a black to white vertical gradient ranging f -Array +Array @@ -3057,7 +3051,7 @@ example, the following code defines a black to white vertical gradient ranging f -Array +Array @@ -3293,7 +3287,7 @@ square to display it:

    -Array +Array @@ -3316,7 +3310,7 @@ square to display it:

    -Array +Array @@ -3645,7 +3639,7 @@ blue radial gradient centered at (100, 100), with a radius of 50, and draws a re -Array +Array @@ -3668,7 +3662,7 @@ blue radial gradient centered at (100, 100), with a radius of 50, and draws a re -Array +Array @@ -4337,7 +4331,7 @@ blue radial gradient centered at (100, 100), with a radius of 50, and draws a re
    Source:
    @@ -4406,7 +4400,7 @@ blue radial gradient centered at (100, 100), with a radius of 50, and draws a re
    Source:
    @@ -4475,7 +4469,7 @@ blue radial gradient centered at (100, 100), with a radius of 50, and draws a re
    Source:
    @@ -4544,7 +4538,7 @@ blue radial gradient centered at (100, 100), with a radius of 50, and draws a re
    Source:
    @@ -5263,7 +5257,7 @@ blue radial gradient centered at (100, 100), with a radius of 50, and draws a re
    Source:
    @@ -5799,7 +5793,7 @@ Once the gradient is created colors can be inserted using the addColorStop metho
    Source:
    @@ -5868,7 +5862,7 @@ Once the gradient is created colors can be inserted using the addColorStop metho
    Source:
    @@ -5937,7 +5931,7 @@ Once the gradient is created colors can be inserted using the addColorStop metho
    Source:
    @@ -6006,7 +6000,7 @@ Once the gradient is created colors can be inserted using the addColorStop metho
    Source:
    @@ -6075,7 +6069,7 @@ Once the gradient is created colors can be inserted using the addColorStop metho
    Source:
    @@ -6354,7 +6348,7 @@ Once the gradient is created colors can be inserted using the addColorStop metho
    Source:
    @@ -6423,7 +6417,7 @@ Once the gradient is created colors can be inserted using the addColorStop metho
    Source:
    @@ -7828,7 +7822,7 @@ source-over (default), destination-atop, destination-in, destination-out, destin
    Source:
    @@ -8625,7 +8619,7 @@ source-over (default), destination-atop, destination-in, destination-out, destin
    Source:
    @@ -8999,7 +8993,7 @@ source-over (default), destination-atop, destination-in, destination-out, destin
    Source:
    @@ -9068,7 +9062,7 @@ source-over (default), destination-atop, destination-in, destination-out, destin
    Source:
    @@ -9137,7 +9131,7 @@ source-over (default), destination-atop, destination-in, destination-out, destin
    Source:
    @@ -9416,7 +9410,7 @@ source-over (default), destination-atop, destination-in, destination-out, destin
    Source:
    @@ -9485,7 +9479,7 @@ source-over (default), destination-atop, destination-in, destination-out, destin
    Source:
    @@ -9926,7 +9920,7 @@ This is called automatically if the BitmapData is being used by a Sprite, otherw
    Source:
    @@ -10136,7 +10130,7 @@ This is called automatically if the BitmapData is being used by a Sprite, otherw
    Source:
    @@ -10205,7 +10199,7 @@ This is called automatically if the BitmapData is being used by a Sprite, otherw
    Source:
    @@ -10274,7 +10268,7 @@ This is called automatically if the BitmapData is being used by a Sprite, otherw
    Source:
    @@ -11451,7 +11445,7 @@ the stroke style and color in a single line of code like so:

    Source:
    @@ -11939,13 +11933,13 @@ the stroke style and color in a single line of code like so:

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:26 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:25 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.BitmapText.html b/docs/Phaser.BitmapText.html index 069b9624..46ef4655 100644 --- a/docs/Phaser.BitmapText.html +++ b/docs/Phaser.BitmapText.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -970,7 +964,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -1390,108 +1384,6 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati - - - - - - - - -
    -

    renderable

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    renderable - - -boolean - - - -

    A renderable object will be rendered to the context each frame.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - -
    @@ -1793,7 +1685,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -1899,7 +1791,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -1964,7 +1856,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -2009,13 +1901,13 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:27 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:25 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Button.html b/docs/Phaser.Button.html index 6b04cc28..ac34735f 100644 --- a/docs/Phaser.Button.html +++ b/docs/Phaser.Button.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -445,7 +439,7 @@
    -

    new Button(game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame)

    +

    new Button(game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame, upFrame)

    @@ -475,6 +469,8 @@ + Default + Description @@ -508,6 +504,10 @@ + + + +

    Current game instance.

    @@ -541,6 +541,12 @@ + + + 0 + + +

    X position of the Button.

    @@ -574,6 +580,12 @@ + + + 0 + + +

    Y position of the Button.

    @@ -607,6 +619,10 @@ + + + +

    The image key as defined in the Game.Cache to use as the texture for this Button.

    @@ -640,6 +656,10 @@ + + + +

    The function to call when this Button is pressed.

    @@ -673,6 +693,10 @@ + + + +

    The context in which the callback will be called (usually 'this').

    @@ -709,6 +733,10 @@ + + + +

    This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name.

    @@ -745,6 +773,10 @@ + + + +

    This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name.

    @@ -781,11 +813,55 @@ + + + +

    This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name.

    + + + + upFrame + + + + + +string +| + +number + + + + + + + + + <optional>
    + + + + + + + + + + + + + + +

    This is the frame or frameName that will be set when this button is in an up state. Give either a number to use a frame ID or a string for a frame name.

    + + + @@ -814,7 +890,7 @@
    Source:
    @@ -865,7 +941,7 @@
    -

    When the Button is clicked you can optionally force the state to "out".

    +

    When the Button is touched / clicked and then released you can force it to enter a state of "out" instead of "up".

    @@ -943,13 +1019,13 @@
    Default Value:
    -
    • true
    +
    • false
    Source:
    @@ -1051,7 +1127,7 @@
    Source:
    @@ -1156,7 +1232,7 @@
    Source:
    @@ -1258,7 +1334,7 @@
    Source:
    @@ -1360,7 +1436,7 @@
    Source:
    @@ -1462,7 +1538,7 @@
    Source:
    @@ -1564,7 +1640,7 @@
    Source:
    @@ -1666,7 +1742,7 @@
    Source:
    @@ -1771,7 +1847,7 @@
    Source:
    @@ -1873,7 +1949,7 @@
    Source:
    @@ -1978,7 +2054,7 @@
    Source:
    @@ -2080,7 +2156,7 @@
    Source:
    @@ -2185,7 +2261,7 @@
    Source:
    @@ -2287,7 +2363,7 @@
    Source:
    @@ -2389,7 +2465,7 @@
    Source:
    @@ -2413,7 +2489,76 @@
    -

    <protected> onInputOverHandler(pointer)

    +

    clearFrames()

    + + +
    +
    + + +
    +

    Clears all of the frames set on this Button.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> onInputOverHandler(sprite, pointer)

    @@ -2453,6 +2598,29 @@ + + + sprite + + + + + +Phaser.Button + + + + + + + + + +

    The Button that the event occured on.

    + + + + pointer @@ -2503,7 +2671,7 @@
    Source:
    @@ -2531,7 +2699,7 @@
    -

    <protected> onInputOverHandler(pointer)

    +

    <protected> onInputOverHandler(sprite, pointer)

    @@ -2571,6 +2739,29 @@ + + + sprite + + + + + +Phaser.Button + + + + + + + + + +

    The Button that the event occured on.

    + + + + pointer @@ -2621,7 +2812,7 @@
    Source:
    @@ -2649,7 +2840,7 @@
    -

    <protected> onInputOverHandler(pointer)

    +

    <protected> onInputOverHandler(sprite, pointer)

    @@ -2691,13 +2882,13 @@ - pointer + sprite -Phaser.Pointer +Phaser.Button @@ -2707,105 +2898,10 @@ -

    The Pointer that activated the Button.

    +

    The Button that the event occured on.

    - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - - - - - -
    -

    <protected> onInputOverHandler(pointer)

    - - -
    -
    - - -
    -

    Internal function that handles input events.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - @@ -2880,6 +2976,147 @@ + + + + +
    +

    <protected> onInputOverHandler(sprite, pointer)

    + + +
    +
    + + +
    +

    Internal function that handles input events.

    +
    + + + + + + + +
    Parameters:
    + + +
    NameTypeDescription
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    sprite + + +Phaser.Button + + + +

    The Button that the event occured on.

    pointer + + +Phaser.Pointer + + + +

    The Pointer that activated the Button.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + +
    @@ -2893,7 +3130,7 @@
    -

    The Sound to be played when a Pointer clicks on this Button.

    +

    The Sound to be played when a Pointer presses down on this Button.

    @@ -3018,7 +3255,7 @@
    Source:
    @@ -3046,7 +3283,7 @@
    -

    setFrames(overFrame, outFrame, downFrame)

    +

    setFrames(overFrame, outFrame, downFrame, upFrame)

    @@ -3054,8 +3291,7 @@
    -

    Used to manually set the frames that will be used for the different states of the button -exactly like setting them in the constructor.

    +

    Used to manually set the frames that will be used for the different states of the Button.

    @@ -3196,6 +3432,42 @@ exactly like setting them in the constructor.

    + + + + upFrame + + + + + +string +| + +number + + + + + + + + + <optional>
    + + + + + + + + + + +

    This is the frame or frameName that will be set when this button is in an up state. Give either a number to use a frame ID or a string for a frame name.

    + + + @@ -3224,7 +3496,7 @@ exactly like setting them in the constructor.

    Source:
    @@ -3385,7 +3657,7 @@ exactly like setting them in the constructor.

    Source:
    @@ -3546,7 +3818,7 @@ exactly like setting them in the constructor.

    Source:
    @@ -3909,7 +4181,125 @@ Call this function with no parameters at all to reset all sounds on this Button.
    Source:
    + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    +

    <protected> setState(newState)

    + + +
    +
    + + +
    +

    Internal function that handles Button state changes.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    newState + + +number + + + +

    The new State of the Button.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -3945,7 +4335,7 @@ Call this function with no parameters at all to reset all sounds on this Button.
    -

    The Sound to be played when a Pointer clicks on this Button.

    +

    The Sound to be played when a Pointer has pressed down and is released from this Button.

    @@ -4070,7 +4460,7 @@ Call this function with no parameters at all to reset all sounds on this Button.
    Source:
    @@ -4115,13 +4505,13 @@ Call this function with no parameters at all to reset all sounds on this Button. - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:27 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:26 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Cache.html b/docs/Phaser.Cache.html index 48d2c327..ac9a8804 100644 --- a/docs/Phaser.Cache.html +++ b/docs/Phaser.Cache.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -427,8 +421,7 @@ Cache -

    A game only has one instance of a Cache and it is used to store all externally loaded assets such -as images, sounds and data files as a result of Loader calls. Cache items use string based keys for look-up.

    +

    A game only has one instance of a Cache and it is used to store all externally loaded assets such as images, sounds and data files as a result of Loader calls. Cached items use string based keys for look-up.

    @@ -529,7 +522,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -657,7 +650,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -759,7 +752,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -782,6 +775,147 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    +
    +

    addBinary(key, binaryData)

    + + +
    +
    + + +
    +

    Add a binary object in to the cache.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    key + + +string + + + +

    Asset key for this binary data.

    binaryData + + +object + + + +

    The binary object to be addded to the cache.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + +

    addBitmapData(key, bitmapData) → {Phaser.BitmapData}

    @@ -896,7 +1030,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -1106,7 +1240,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -1270,7 +1404,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -1339,7 +1473,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -1503,7 +1637,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -1572,7 +1706,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -1713,7 +1847,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -1923,7 +2057,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -1951,7 +2085,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    -

    addSpriteSheet(key, url, data, frameWidth, frameHeight, frameMax)

    +

    addSpriteSheet(key, url, data, frameWidth, frameHeight, frameMax, margin, spacing)

    @@ -1981,8 +2115,12 @@ as images, sounds and data files as a result of Loader calls. Cache items use st Type + Argument + + Default + Description @@ -2006,7 +2144,19 @@ as images, sounds and data files as a result of Loader calls. Cache items use st + + + + + + + + + + + +

    The unique key by which you will reference this object.

    @@ -2029,7 +2179,19 @@ as images, sounds and data files as a result of Loader calls. Cache items use st + + + + + + + + + + + +

    URL of this sprite sheet file.

    @@ -2052,7 +2214,19 @@ as images, sounds and data files as a result of Loader calls. Cache items use st + + + + + + + + + + + +

    Extra sprite sheet data.

    @@ -2075,7 +2249,19 @@ as images, sounds and data files as a result of Loader calls. Cache items use st + + + + + + + + + + + +

    Width of the sprite sheet.

    @@ -2098,7 +2284,19 @@ as images, sounds and data files as a result of Loader calls. Cache items use st + + + + + + + + + + + +

    Height of the sprite sheet.

    @@ -2121,10 +2319,104 @@ as images, sounds and data files as a result of Loader calls. Cache items use st + + + <optional>
    + + + + + -

    How many frames stored in the sprite sheet.

    + + + + -1 + + + + +

    How many frames stored in the sprite sheet. If -1 then it divides the whole sheet evenly.

    + + + + + + + margin + + + + + +number + + + + + + + + + <optional>
    + + + + + + + + + + + + 0 + + + + +

    If the frames have been drawn with a margin, specify the amount here.

    + + + + + + + spacing + + + + + +number + + + + + + + + + <optional>
    + + + + + + + + + + + + 0 + + + + +

    If the frames have been drawn with spacing between them, specify the amount here.

    @@ -2156,7 +2448,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -2320,7 +2612,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -2530,7 +2822,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -2662,7 +2954,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st -

    The tilemap data object.

    +

    The tilemap data object (either a CSV or JSON file).

    @@ -2717,394 +3009,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    addTileset(key, url, data, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing)

    - - -
    -
    - - -
    -

    Add a new tile set in to the cache.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeArgumentDefaultDescription
    key - - -string - - - - - - - - - - - -

    The unique key by which you will reference this object.

    url - - -string - - - - - - - - - - - -

    URL of this tile set file.

    data - - -object - - - - - - - - - - - -

    Extra tile set data.

    tileWidth - - -number - - - - - - - - - - - -

    Width of the sprite sheet.

    tileHeight - - -number - - - - - - - - - - - -

    Height of the sprite sheet.

    tileMax - - -number - - - - - - - - - - - -

    How many tiles stored in the sprite sheet.

    tileMargin - - -number - - - - - - <optional>
    - - - - - -
    - - 0 - -

    If the tiles have been drawn with a margin, specify the amount here.

    tileSpacing - - -number - - - - - - <optional>
    - - - - - -
    - - 0 - -

    If the tiles have been drawn with spacing between them, specify the amount here.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -3190,7 +3095,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st -

    Asset key of the image you want.

    +

    Asset key of the image to check is in the Cache.

    @@ -3222,7 +3127,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -3386,7 +3291,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -3455,7 +3360,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -3478,6 +3383,147 @@ as images, sounds and data files as a result of Loader calls. Cache items use st +
    + + + +
    +

    getBinary(key) → {object}

    + + +
    +
    + + +
    +

    Get binary data by key.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    key + + +string + + + +

    Asset key of the binary data object to retrieve from the Cache.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The binary data object.

    +
    + + + +
    +
    + Type +
    +
    + +object + + +
    +
    + + + + +
    @@ -3541,7 +3587,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st -

    Asset key of the BitmapData object you want.

    +

    Asset key of the BitmapData object to retrieve from the Cache.

    @@ -3573,7 +3619,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -3682,7 +3728,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st -

    Asset key of the canvas you want.

    +

    Asset key of the canvas to retrieve from the Cache.

    @@ -3714,7 +3760,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -3739,7 +3785,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    -

    The canvas you want.

    +

    The canvas object.

    @@ -3823,7 +3869,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st -

    Asset key of the frame data you want.

    +

    Asset key of the frame data to retrieve from the Cache.

    @@ -3855,7 +3901,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -3880,7 +3926,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    -

    The frame data you want.

    +

    The frame data.

    @@ -3964,7 +4010,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st -

    Asset key of the frame data you want.

    +

    Asset key of the frame data to retrieve from the Cache.

    @@ -3996,7 +4042,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -4021,7 +4067,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    -

    The frame data you want.

    +

    The frame object.

    @@ -4105,7 +4151,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st -

    Asset key of the frame data you want.

    +

    Asset key of the frame data to retrieve from the Cache.

    @@ -4137,7 +4183,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -4162,7 +4208,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    -

    The frame data you want.

    +

    The frame object.

    @@ -4246,7 +4292,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st -

    Asset key of the frame data you want.

    +

    Asset key of the frame data to retrieve from the Cache.

    @@ -4278,7 +4324,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -4303,7 +4349,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    -

    The frame data you want.

    +

    The frame data.

    @@ -4387,7 +4433,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st -

    Asset key of the image you want.

    +

    Asset key of the image to retrieve from the Cache.

    @@ -4419,7 +4465,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -4444,7 +4490,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    -

    The image data you want.

    +

    The image data.

    @@ -4470,7 +4516,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    -

    getImageKeys() → {Array}

    +

    getImageKeys() → {Array}

    @@ -4511,7 +4557,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    Source:
    @@ -4547,7 +4593,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    -Array +Array
    @@ -4562,7 +4608,7 @@ as images, sounds and data files as a result of Loader calls. Cache items use st
    -

    getKeys(array) → {Array}

    +

    getKeys(array) → {Array}

    @@ -4611,7 +4657,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys -Array +Array @@ -4653,7 +4699,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -4689,7 +4735,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -Array +Array
    @@ -4762,7 +4808,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys -

    Asset key of the sound you want.

    +

    Asset key of the sound to retrieve from the Cache.

    @@ -4794,7 +4840,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -4819,7 +4865,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -

    The sound you want.

    +

    The sound object.

    @@ -4903,7 +4949,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys -

    Asset key of the sound you want.

    +

    Asset key of the sound to retrieve from the Cache.

    @@ -4935,7 +4981,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -4960,7 +5006,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -

    The sound data you want.

    +

    The sound data.

    @@ -4986,7 +5032,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -

    getSoundKeys() → {Array}

    +

    getSoundKeys() → {Array}

    @@ -5027,7 +5073,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -5063,7 +5109,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -Array +Array
    @@ -5136,7 +5182,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys -

    Asset key of the text data you want.

    +

    Asset key of the text data to retrieve from the Cache.

    @@ -5168,7 +5214,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -5193,7 +5239,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -

    The text data you want.

    +

    The text data.

    @@ -5219,7 +5265,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -

    getTextKeys() → {Array}

    +

    getTextKeys() → {Array}

    @@ -5260,7 +5306,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -5296,7 +5342,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -Array +Array
    @@ -5369,7 +5415,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys -

    Asset key of the RenderTexture you want.

    +

    Asset key of the RenderTexture to retrieve from the Cache.

    @@ -5401,7 +5447,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -5426,7 +5472,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -

    The RenderTexture you want.

    +

    The RenderTexture object.

    @@ -5460,7 +5506,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -

    Get a single frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image.

    +

    Get a single texture frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image.

    @@ -5510,7 +5556,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys -

    Asset key of the frame data you want.

    +

    Asset key of the frame to retrieve from the Cache.

    @@ -5542,7 +5588,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -5567,7 +5613,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -

    The frame data you want.

    +

    The frame data.

    @@ -5651,7 +5697,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys -

    Asset key of the tilemap you want.

    +

    Asset key of the tilemap data to retrieve from the Cache.

    @@ -5683,7 +5729,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -5708,7 +5754,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -

    The tilemap data. The tileset image is in the data property, the map data in mapData.

    +

    The raw tilemap data in CSV or JSON format.

    @@ -5729,288 +5775,6 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys - - - - -
    -

    getTileset(key) → {Phaser.Tileset}

    - - -
    -
    - - -
    -

    Get tile set image data by key.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    key - - -string - - - -

    Asset key of the image you want.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    The tileset data. The tileset image is in the data property, the tile data in tileData.

    -
    - - - -
    -
    - Type -
    -
    - -Phaser.Tileset - - -
    -
    - - - - - -
    - - - -
    -

    getTileSetImage(key) → {object}

    - - -
    -
    - - -
    -

    Get tile set image data by key.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    key - - -string - - - -

    Asset key of the image you want.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    The image data you want.

    -
    - - - -
    -
    - Type -
    -
    - -object - - -
    -
    - - - - -
    @@ -6074,7 +5838,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys -

    Asset key of the sound you want.

    +

    Asset key of the sound in the Cache.

    @@ -6106,7 +5870,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -6215,7 +5979,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys -

    Asset key of the sound you want.

    +

    Asset key of the sound in the Cache.

    @@ -6247,7 +6011,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -6388,7 +6152,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -6529,7 +6293,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -6565,7 +6329,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -

    Description.

    +

    Fires the onSoundUnlock event when the sound has completed reloading.

    @@ -6647,7 +6411,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -6765,7 +6529,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -6883,7 +6647,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -7001,7 +6765,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -7119,7 +6883,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -7155,7 +6919,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    -

    Description.

    +

    Updates the sound object in the cache.

    @@ -7237,7 +7001,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
    Source:
    @@ -7282,13 +7046,13 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:27 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:26 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Camera.html b/docs/Phaser.Camera.html index c999006b..9c78271a 100644 --- a/docs/Phaser.Camera.html +++ b/docs/Phaser.Camera.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -730,7 +724,7 @@ The game automatically creates a single Stage sized camera on boot. Move the cam
    Source:
    @@ -790,7 +784,7 @@ The game automatically creates a single Stage sized camera on boot. Move the cam
    Source:
    @@ -850,7 +844,7 @@ The game automatically creates a single Stage sized camera on boot. Move the cam
    Source:
    @@ -910,7 +904,7 @@ The game automatically creates a single Stage sized camera on boot. Move the cam
    Source:
    @@ -1231,6 +1225,108 @@ at all then set this to null. The values can be anything and are in World coordi + + + + + + + + +
    +

    displayObject

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    displayObject + + +PIXI.DisplayObject + + + +

    The display object to which all game objects are added. Set by World.boot

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + +
    @@ -1430,7 +1526,7 @@ at all then set this to null. The values can be anything and are in World coordi
    Source:
    @@ -1770,7 +1866,7 @@ at all then set this to null. The values can be anything and are in World coordi

    Camera view. The view into the world we wish to render (by default the game dimensions). The x/y values are in world coordinates, not screen coordinates, the width/height is how many pixels to render. -Objects outside of this view are not rendered (unless set to ignore the Camera, i.e. UI?).

    +Objects outside of this view are not rendered if set to camera cull.

    @@ -2062,7 +2158,7 @@ Objects outside of this view are not rendered (unless set to ignore the Camera,
    Source:
    @@ -2270,7 +2366,7 @@ Objects outside of this view are not rendered (unless set to ignore the Camera,
    Source:
    @@ -2376,7 +2472,7 @@ Objects outside of this view are not rendered (unless set to ignore the Camera,
    Source:
    @@ -2441,7 +2537,7 @@ Objects outside of this view are not rendered (unless set to ignore the Camera,
    Source:
    @@ -2559,7 +2655,7 @@ Objects outside of this view are not rendered (unless set to ignore the Camera,
    Source:
    @@ -2700,7 +2796,7 @@ Objects outside of this view are not rendered (unless set to ignore the Camera,
    Source:
    @@ -2861,7 +2957,76 @@ Objects outside of this view are not rendered (unless set to ignore the Camera,
    Source:
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    setBoundsToWorld()

    + + +
    +
    + + +
    +

    Update the Camera bounds to match the game world.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -3003,7 +3168,7 @@ without having to use game.camera.x and game.camera.y.

    Source:
    @@ -3144,7 +3309,7 @@ without having to use game.camera.x and game.camera.y.

    Source:
    @@ -3213,7 +3378,7 @@ without having to use game.camera.x and game.camera.y.

    Source:
    @@ -3258,13 +3423,13 @@ without having to use game.camera.x and game.camera.y.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:27 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:26 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Canvas.html b/docs/Phaser.Canvas.html index 71bd9952..06f8a7ad 100644 --- a/docs/Phaser.Canvas.html +++ b/docs/Phaser.Canvas.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -444,7 +438,7 @@
    -

    The Canvas class handles everything related to the <canvas> tag as a DOM Element, like styles, offset, aspect ratio

    +

    The Canvas class handles everything related to creating the canvas DOM tag that Phaser will use, including styles, offset and aspect ratio.

    @@ -523,7 +517,7 @@
    -

    <static> addToDOM(canvas, parent, overflowHidden) → {HTMLCanvasElement}

    +

    <static> addToDOM(canvas, parent, overflowHidden) → {HTMLCanvasElement}

    @@ -554,8 +548,12 @@ If no parent is given it will be added as a child of the document.body.

    Type + Argument + + Default + Description @@ -579,7 +577,19 @@ If no parent is given it will be added as a child of the document.body.

    + + + + + + + + + + + +

    The canvas to set the touch action on.

    @@ -605,10 +615,22 @@ If no parent is given it will be added as a child of the document.body.

    + + + + + + -

    The DOM element to add the canvas to. Defaults to ''.

    + + + + + + +

    The DOM element to add the canvas to.

    @@ -628,7 +650,23 @@ If no parent is given it will be added as a child of the document.body.

    + + + <optional>
    + + + + + + + + + + + true + +

    If set to true it will add the overflow='hidden' style to the parent DOM element.

    @@ -663,7 +701,7 @@ If no parent is given it will be added as a child of the document.body.

    Source:
    @@ -714,7 +752,7 @@ If no parent is given it will be added as a child of the document.body.

    -

    <static> create(width, height) → {HTMLCanvasElement}

    +

    <static> create(width, height, id) → {HTMLCanvasElement}

    @@ -722,7 +760,7 @@ If no parent is given it will be added as a child of the document.body.

    -

    Creates the <canvas> tag

    +

    Creates a canvas DOM element. The element is not automatically added to the document.

    @@ -744,8 +782,12 @@ If no parent is given it will be added as a child of the document.body.

    Type + Argument + + Default + Description @@ -769,10 +811,26 @@ If no parent is given it will be added as a child of the document.body.

    + + + <optional>
    + + + + + -

    The desired width.

    + + + + 256 + + + + +

    The width of the canvas element.

    @@ -792,10 +850,65 @@ If no parent is given it will be added as a child of the document.body.

    + + + <optional>
    + + + + + -

    The desired height.

    + + + + 256 + + + + +

    The height of the canvas element..

    + + + + + + + id + + + + + +string + + + + + + + + + <optional>
    + + + + + + + + + + + + '' + + + + +

    If given this will be set as the ID of the canvas element, otherwise no ID will be set.

    @@ -852,7 +965,7 @@ If no parent is given it will be added as a child of the document.body.

    -

    The newly created <canvas> tag.

    +

    The newly created canvas element.

    @@ -968,7 +1081,7 @@ If no parent is given it will be added as a child of the document.body.

    Source:
    @@ -1152,7 +1265,7 @@ If no parent is given it will be added as a child of the document.body.

    Source:
    @@ -1338,7 +1451,7 @@ If no parent is given it will be added as a child of the document.body.

    Source:
    @@ -1480,7 +1593,7 @@ Note that if this doesn't given the desired result then see the CanvasUtils.setS
    Source:
    @@ -1622,7 +1735,7 @@ Note that if this doesn't given the desired result then see the setSmoothingEnab
    Source:
    @@ -1790,7 +1903,7 @@ patchy on earlier browsers, especially on mobile.

    Source:
    @@ -1974,7 +2087,7 @@ patchy on earlier browsers, especially on mobile.

    Source:
    @@ -2253,7 +2366,7 @@ patchy on earlier browsers, especially on mobile.

    Source:
    @@ -2437,7 +2550,7 @@ patchy on earlier browsers, especially on mobile.

    Source:
    @@ -2505,13 +2618,13 @@ patchy on earlier browsers, especially on mobile.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:27 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:26 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Circle.html b/docs/Phaser.Circle.html index 36d2d5a0..9f4ff06b 100644 --- a/docs/Phaser.Circle.html +++ b/docs/Phaser.Circle.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -472,6 +466,8 @@ + Default + Description @@ -507,6 +503,12 @@ + + + 0 + + +

    The x coordinate of the center of the circle.

    @@ -540,6 +542,12 @@ + + + 0 + + +

    The y coordinate of the center of the circle.

    @@ -573,6 +581,12 @@ + + + 0 + + +

    The diameter of the circle.

    @@ -761,7 +775,7 @@
    Source:
    @@ -867,7 +881,7 @@
    Source:
    @@ -973,7 +987,7 @@
    Source:
    @@ -1080,7 +1094,7 @@ If set to true it will reset all of the Circle objects properties to 0. A Circle
    Source:
    @@ -1134,7 +1148,7 @@ If set to true it will reset all of the Circle objects properties to 0. A Circle
    Source:
    @@ -1240,7 +1254,7 @@ If set to true it will reset all of the Circle objects properties to 0. A Circle
    Source:
    @@ -1346,7 +1360,7 @@ If set to true it will reset all of the Circle objects properties to 0. A Circle
    Source:
    @@ -1452,7 +1466,7 @@ If set to true it will reset all of the Circle objects properties to 0. A Circle
    Source:
    @@ -1875,7 +1889,7 @@ If set to true it will reset all of the Circle objects properties to 0. A Circle
    Source:
    @@ -2062,7 +2076,7 @@ If set to true it will reset all of the Circle objects properties to 0. A Circle
    Source:
    @@ -2226,7 +2240,7 @@ If set to true it will reset all of the Circle objects properties to 0. A Circle
    Source:
    @@ -2391,7 +2405,7 @@ This method checks the radius distances between the two Circle objects to see if
    Source:
    @@ -2555,7 +2569,7 @@ This method checks the radius distances between the two Circle objects to see if
    Source:
    @@ -4282,13 +4296,13 @@ This method checks the radius distances between the two Circle objects to see if - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:27 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:26 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Color.html b/docs/Phaser.Color.html index 51379fd7..8db79737 100644 --- a/docs/Phaser.Color.html +++ b/docs/Phaser.Color.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -3611,13 +3605,13 @@ Set the max value to restrict the maximum color used per channel.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:27 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:26 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.DOMSprite.html b/docs/Phaser.DOMSprite.html new file mode 100644 index 00000000..c7f3269d --- /dev/null +++ b/docs/Phaser.DOMSprite.html @@ -0,0 +1,1476 @@ + + + + + + Phaser Class: DOMSprite + + + + + + + + + + +
    + + +
    + + +
    + +
    + + + +

    Class: DOMSprite

    +
    + +
    +

    + Phaser. + + DOMSprite +

    + +

    Phaser.DOMSprite

    + +
    + +
    +
    + + + + +
    +

    new DOMSprite(game, id, x, y, text, style)

    + + +
    +
    + + +
    +

    Create a new DOMSprite.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    game + + +Phaser.Game + + + +

    Current game instance.

    id + + +string + + + +

    DOM ID.

    x + + +number + + + +

    X position of the new text object.

    y + + +number + + + +

    Y position of the new text object.

    text + + +string + + + +

    The actual text that will be written.

    style + + +object + + + +

    The style object containing style attributes like font, font size ,

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + +
    + + + + + + + + + + + + +

    Members

    + +
    + +
    +

    alive

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    alive + + +boolean + + + +

    This is a handy little var your game can use to determine if an object is alive or not, it doesn't effect rendering.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • true
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    exists

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    exists + + +boolean + + + +

    If exists = false then the Text isn't updated by the core game loop.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • true
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    game

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    game + + +Phaser.Game + + + +

    A reference to the currently running Game.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    group

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    group + + +Phaser.Group + + + +

    The parent Group of this Text object.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    name

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    name + + +string + + + +

    The user defined name given to this object.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    type

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    type + + +number + + + +

    The const type of this object.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    visible

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    visible + + +boolean + + + +

    Sets the visible state of this DOMSprite.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • true
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + +
    + + + + + + + +
    + +
    + + + + +
    + +
    +
    + + + + Phaser Copyright © 2012-2014 Photon Storm Ltd. + +
    + + + Documentation generated by JSDoc 3.3.0-dev + on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template. + +
    +
    + + +
    +
    +
    + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/Phaser.Device.html b/docs/Phaser.Device.html index 033bb1ac..7d231d36 100644 --- a/docs/Phaser.Device.html +++ b/docs/Phaser.Device.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -610,7 +604,7 @@
    Source:
    @@ -715,7 +709,7 @@
    Source:
    @@ -820,7 +814,7 @@
    Source:
    @@ -925,7 +919,7 @@
    Source:
    @@ -1030,7 +1024,7 @@
    Source:
    @@ -1135,7 +1129,7 @@
    Source:
    @@ -1345,7 +1339,7 @@
    Source:
    @@ -1459,6 +1453,111 @@ +
    + + + +
    + + + +
    +

    ejecta

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ejecta + + +boolean + + + +

    Is the game running under Ejecta?

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + +
    @@ -1555,7 +1654,7 @@
    Source:
    @@ -1660,7 +1759,7 @@
    Source:
    @@ -1765,7 +1864,7 @@
    Source:
    @@ -1870,7 +1969,7 @@
    Source:
    @@ -1975,7 +2074,7 @@
    Source:
    @@ -2080,7 +2179,7 @@
    Source:
    @@ -2290,7 +2389,7 @@
    Source:
    @@ -2395,7 +2494,7 @@
    Source:
    @@ -2500,7 +2599,7 @@
    Source:
    @@ -2605,7 +2704,7 @@
    Source:
    @@ -2710,7 +2809,7 @@
    Source:
    @@ -2815,7 +2914,7 @@
    Source:
    @@ -2924,7 +3023,7 @@
    Source:
    @@ -3029,7 +3128,7 @@
    Source:
    @@ -3134,7 +3233,7 @@
    Source:
    @@ -3239,7 +3338,7 @@
    Source:
    @@ -3344,7 +3443,7 @@
    Source:
    @@ -3449,7 +3548,7 @@
    Source:
    @@ -3554,7 +3653,7 @@
    Source:
    @@ -3659,7 +3758,7 @@
    Source:
    @@ -3764,7 +3863,7 @@
    Source:
    @@ -3978,7 +4077,7 @@
    Source:
    @@ -4083,7 +4182,112 @@
    Source:
    + + + + + + + + + + + + + + + +
    +

    quirksMode

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    quirksMode + + +boolean + + + +

    Is the browser running in strict mode (false) or quirks mode? (true)

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    @@ -4188,7 +4392,112 @@
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    silk

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    silk + + +boolean + + + +

    Set to true if running in the Silk browser (as used on the Amazon Kindle)

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    @@ -4293,7 +4602,217 @@
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    trident

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    trident + + +boolean + + + +

    Set to true if running a Trident version of Internet Explorer (IE11+)

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    tridentVersion

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    tridentVersion + + +number + + + +

    If running in Internet Explorer 11 this will contain the major version number. See http://msdn.microsoft.com/en-us/library/ie/ms537503(v=vs.85).aspx

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • 0
    + + + +
    Source:
    +
    @@ -4398,7 +4917,112 @@
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    vibration

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    vibration + + +boolean + + + +

    Does the device support the Vibration API?

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    @@ -4503,7 +5127,7 @@
    Source:
    @@ -4608,7 +5232,7 @@
    Source:
    @@ -4713,7 +5337,7 @@
    Source:
    @@ -4818,7 +5442,7 @@
    Source:
    @@ -4923,7 +5547,7 @@
    Source:
    @@ -5028,7 +5652,7 @@
    Source:
    @@ -5133,7 +5757,7 @@
    Source:
    @@ -5247,7 +5871,7 @@
    Source:
    @@ -5339,7 +5963,7 @@
    Source:
    @@ -5407,13 +6031,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:27 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Easing.Back.html b/docs/Phaser.Easing.Back.html index 227caf6e..5cd5ceb8 100644 --- a/docs/Phaser.Easing.Back.html +++ b/docs/Phaser.Easing.Back.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -963,13 +957,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:28 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Easing.Bounce.html b/docs/Phaser.Easing.Bounce.html index eefc3a87..559da0c6 100644 --- a/docs/Phaser.Easing.Bounce.html +++ b/docs/Phaser.Easing.Bounce.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -963,13 +957,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:28 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Easing.Circular.html b/docs/Phaser.Easing.Circular.html index d8de3fde..423e8058 100644 --- a/docs/Phaser.Easing.Circular.html +++ b/docs/Phaser.Easing.Circular.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -963,13 +957,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:28 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Easing.Cubic.html b/docs/Phaser.Easing.Cubic.html index 029e55f0..56b6e2f3 100644 --- a/docs/Phaser.Easing.Cubic.html +++ b/docs/Phaser.Easing.Cubic.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -963,13 +957,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:28 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Easing.Elastic.html b/docs/Phaser.Easing.Elastic.html index a2032e2a..445528fa 100644 --- a/docs/Phaser.Easing.Elastic.html +++ b/docs/Phaser.Easing.Elastic.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -963,13 +957,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:28 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Easing.Exponential.html b/docs/Phaser.Easing.Exponential.html index d0f95ae5..2bec6a2d 100644 --- a/docs/Phaser.Easing.Exponential.html +++ b/docs/Phaser.Easing.Exponential.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -963,13 +957,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:28 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Easing.Linear.html b/docs/Phaser.Easing.Linear.html index 897f16f3..efd870b1 100644 --- a/docs/Phaser.Easing.Linear.html +++ b/docs/Phaser.Easing.Linear.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -681,13 +675,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:28 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Easing.Quadratic.html b/docs/Phaser.Easing.Quadratic.html index 9293bc3b..97dd1fb8 100644 --- a/docs/Phaser.Easing.Quadratic.html +++ b/docs/Phaser.Easing.Quadratic.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -963,13 +957,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:28 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Easing.Quartic.html b/docs/Phaser.Easing.Quartic.html index f0710356..d605c617 100644 --- a/docs/Phaser.Easing.Quartic.html +++ b/docs/Phaser.Easing.Quartic.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -963,13 +957,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:28 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Easing.Quintic.html b/docs/Phaser.Easing.Quintic.html index 38b69a8d..cae49a2f 100644 --- a/docs/Phaser.Easing.Quintic.html +++ b/docs/Phaser.Easing.Quintic.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -963,13 +957,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:29 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Easing.Sinusoidal.html b/docs/Phaser.Easing.Sinusoidal.html index 9f27d626..876ace73 100644 --- a/docs/Phaser.Easing.Sinusoidal.html +++ b/docs/Phaser.Easing.Sinusoidal.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -963,13 +957,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:29 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Easing.html b/docs/Phaser.Easing.html index 9b823c61..76cf08c7 100644 --- a/docs/Phaser.Easing.html +++ b/docs/Phaser.Easing.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -573,13 +567,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:28 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Events.html b/docs/Phaser.Events.html index 56989c5d..a3c813c2 100644 --- a/docs/Phaser.Events.html +++ b/docs/Phaser.Events.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -587,13 +581,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:29 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Filter.html b/docs/Phaser.Filter.html index f5ba4e84..20026212 100644 --- a/docs/Phaser.Filter.html +++ b/docs/Phaser.Filter.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -532,7 +526,7 @@ -Array +Array @@ -1011,7 +1005,7 @@
    Source:
    @@ -1422,7 +1416,7 @@
    Source:
    @@ -1487,7 +1481,7 @@
    Source:
    @@ -1872,13 +1866,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:29 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Frame.html b/docs/Phaser.Frame.html index 743e23ef..a7dd759c 100644 --- a/docs/Phaser.Frame.html +++ b/docs/Phaser.Frame.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -2948,13 +2942,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:29 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.FrameData.html b/docs/Phaser.FrameData.html index 6a39c33a..e8a64653 100644 --- a/docs/Phaser.FrameData.html +++ b/docs/Phaser.FrameData.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -607,7 +601,7 @@
    Source:
    @@ -1195,7 +1189,7 @@
    -

    getFrameIndexes(frames, useNumericIndex, output) → {Array}

    +

    getFrameIndexes(frames, useNumericIndex, output) → {Array}

    @@ -1248,7 +1242,7 @@ The frames indexes are returned in the output array, or if none is provided in a -Array +Array @@ -1322,7 +1316,7 @@ The frames indexes are returned in the output array, or if none is provided in a -Array +Array @@ -1414,7 +1408,7 @@ The frames indexes are returned in the output array, or if none is provided in a
    -Array +Array
    @@ -1429,7 +1423,7 @@ The frames indexes are returned in the output array, or if none is provided in a
    -

    getFrameRange(start, end, output) → {Array}

    +

    getFrameRange(start, end, output) → {Array}

    @@ -1541,7 +1535,7 @@ The frames indexes are returned in the output array, or if none is provided in a -Array +Array @@ -1629,7 +1623,7 @@ The frames indexes are returned in the output array, or if none is provided in a
    -Array +Array
    @@ -1644,7 +1638,7 @@ The frames indexes are returned in the output array, or if none is provided in a
    -

    getFrames(frames, useNumericIndex, output) → {Array}

    +

    getFrames(frames, useNumericIndex, output) → {Array}

    @@ -1697,7 +1691,7 @@ The frames are returned in the output array, or if none is provided in a new Arr -Array +Array @@ -1771,7 +1765,7 @@ The frames are returned in the output array, or if none is provided in a new Arr -Array +Array @@ -1863,7 +1857,7 @@ The frames are returned in the output array, or if none is provided in a new Arr
    -Array +Array
    @@ -1895,13 +1889,13 @@ The frames are returned in the output array, or if none is provided in a new Arr - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:29 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Game.html b/docs/Phaser.Game.html index 906478dd..5290e6ce 100644 --- a/docs/Phaser.Game.html +++ b/docs/Phaser.Game.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -611,6 +605,9 @@ providing quick access to common functions and handling the boot process. +string +| + HTMLElement @@ -637,7 +634,7 @@ providing quick access to common functions and handling the boot process. -

    The Games DOM parent.

    +

    The DOM element into which this games canvas will be injected. Either a DOM ID (string) or the element itself.

    @@ -650,7 +647,7 @@ providing quick access to common functions and handling the boot process. -any +object @@ -676,7 +673,7 @@ providing quick access to common functions and handling the boot process. -

    Description.

    +

    The default state object. A object consisting of Phaser.State functions (preload, create, update, render) or null.

    @@ -917,7 +914,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -1015,11 +1012,14 @@ providing quick access to common functions and handling the boot process. +
    Default Value:
    +
    • true
    +
    Source:
    @@ -1124,7 +1124,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -1229,7 +1229,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -1334,7 +1334,109 @@ providing quick access to common functions and handling the boot process.
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    config

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    config + + +object + + + +

    The Phaser.Game configuration object.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1439,7 +1541,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -1544,7 +1646,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -1649,7 +1751,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -1747,11 +1849,14 @@ providing quick access to common functions and handling the boot process. +
    Default Value:
    +
    • 600
    +
    Source:
    @@ -1853,7 +1958,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -1958,7 +2063,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -2063,7 +2168,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -2168,7 +2273,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -2273,7 +2378,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -2378,7 +2483,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -2483,7 +2588,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -2585,7 +2690,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -2690,7 +2795,7 @@ providing quick access to common functions and handling the boot process.
    Source:
    @@ -2797,7 +2902,112 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> pendingStep

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    stepping + + +boolean + + + +

    An internal property used by enableStep, but also useful to query from your own game objects.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    @@ -2902,7 +3112,7 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    @@ -3007,7 +3217,7 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    @@ -3105,14 +3315,11 @@ When a game is paused the onPause event is dispatched. When it is resumed the on -
    Default Value:
    -
    • null
    -
    Source:
    @@ -3214,7 +3421,7 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    @@ -3319,7 +3526,7 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    @@ -3424,7 +3631,7 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    @@ -3529,7 +3736,7 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    @@ -3631,7 +3838,217 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> stepCount

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    stepCount + + +number + + + +

    When stepping is enabled this contains the current step cycle.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • 0
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> stepping

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    stepping + + +boolean + + + +

    Enable core loop stepping with Game.enableStep().

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    @@ -3736,7 +4153,7 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    @@ -3834,11 +4251,14 @@ When a game is paused the onPause event is dispatched. When it is resumed the on +
    Default Value:
    +
    • false
    +
    Source:
    @@ -3943,7 +4363,7 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    @@ -4041,11 +4461,14 @@ When a game is paused the onPause event is dispatched. When it is resumed the on +
    Default Value:
    +
    • 800
    +
    Source:
    @@ -4150,7 +4573,7 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    @@ -4215,7 +4638,7 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    @@ -4284,7 +4707,146 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    disableStep()

    + + +
    +
    + + +
    +

    Disables core game loop stepping.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    enableStep()

    + + +
    +
    + + +
    +

    Enable core game loop stepping. When enabled you must call game.step() directly (perhaps via a DOM button?) +Calling step will advance the game loop by one frame. This is extremely useful to hard to track down errors!

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -4353,7 +4915,145 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> parseConfig()

    + + +
    +
    + + +
    +

    Parses a Game configuration object.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> parseDimension()

    + + +
    +
    + + +
    +

    Get dimension.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -4422,7 +5122,7 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    @@ -4491,7 +5191,77 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    step()

    + + +
    +
    + + +
    +

    When stepping is enabled you must call this function directly (perhaps via a DOM button?) to advance the game loop by one frame. +This is extremely useful to hard to track down errors! Use the internal stepCount property to monitor progress.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -4609,7 +5379,7 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
    Source:
    @@ -4654,13 +5424,13 @@ When a game is paused the onPause event is dispatched. When it is resumed the on - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:29 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:29 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.GameObjectFactory.html b/docs/Phaser.GameObjectFactory.html index f0dbb6f0..336b5ec6 100644 --- a/docs/Phaser.GameObjectFactory.html +++ b/docs/Phaser.GameObjectFactory.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -790,7 +784,7 @@
    -

    Creates a new instance of the Sound class.

    +

    Creates a new Sound object.

    @@ -1005,7 +999,7 @@
    Source:
    @@ -1064,7 +1058,7 @@
    -

    A BitmapData object which can be manipulated and drawn to like a traditional Canvas object and used to texture Sprites.

    +

    Experimental: A BitmapData object which can be manipulated and drawn to like a traditional Canvas object and used to texture Sprites.

    @@ -1205,7 +1199,7 @@
    Source:
    @@ -1256,7 +1250,7 @@
    -

    bitmapText(x, y, text, style) → {Phaser.BitmapText}

    +

    bitmapText(x, y, text, style, group) → {Phaser.BitmapText}

    @@ -1265,7 +1259,7 @@
      -
    • Create a new <code>BitmapText</code>.
    • +
    • Create a new BitmapText object.
    @@ -1288,6 +1282,8 @@ Type + Argument + @@ -1313,6 +1309,14 @@ + + + + + + + + @@ -1336,6 +1340,14 @@ + + + + + + + + @@ -1359,6 +1371,14 @@ + + + + + + + + @@ -1382,6 +1402,14 @@ + + + + + + + + @@ -1389,6 +1417,39 @@ + + + + group + + + + + +Phaser.Group + + + + + + + + + <optional>
    + + + + + + + + + + +

    Optional Group to add the object to. If not specified it will be added to the World group.

    + + + @@ -1417,7 +1478,7 @@
    Source:
    @@ -1468,7 +1529,7 @@
    -

    button(x, y, key, callback, callbackContext, overFrame, outFrame, downFrame) → {Phaser.Button}

    +

    button(x, y, key, callback, callbackContext, overFrame, outFrame, downFrame, upFrame, group) → {Phaser.Button}

    @@ -1476,7 +1537,7 @@
    -

    Creates a new <code>Button</code> object.

    +

    Creates a new Button object.

    @@ -1782,6 +1843,75 @@ + + + + upFrame + + + + + +string +| + +number + + + + + + + + + <optional>
    + + + + + + + + + + +

    This is the frame or frameName that will be set when this button is in an up state. Give either a number to use a frame ID or a string for a frame name.

    + + + + + + + group + + + + + +Phaser.Group + + + + + + + + + <optional>
    + + + + + + + + + + +

    Optional Group to add the object to. If not specified it will be added to the World group.

    + + + @@ -1810,7 +1940,7 @@
    Source:
    @@ -1869,7 +1999,8 @@
    -

    Create a new Sprite with specific position and sprite sheet key that will automatically be added as a child of the given parent.

    +

    DEPRECATED - will be removed in Phaser 1.2 +Create a new Sprite with specific position and sprite sheet key that will automatically be added as a child of the given parent.

    @@ -2095,7 +2226,7 @@
    Source:
    @@ -2336,7 +2467,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    Source:
    @@ -2641,7 +2772,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    Source:
    @@ -2692,7 +2823,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    -

    graphics(x, y) → {Phaser.Graphics}

    +

    graphics(x, y, group) → {Phaser.Graphics}

    @@ -2700,7 +2831,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    -

    Creates a new <code>Graphics</code> object.

    +

    Creates a new Graphics object.

    @@ -2722,6 +2853,8 @@ at set intervals, and fixes their positions and velocities accorindgly.

    Type + Argument + @@ -2747,6 +2880,14 @@ at set intervals, and fixes their positions and velocities accorindgly.

    + + + + + + + + @@ -2770,6 +2911,14 @@ at set intervals, and fixes their positions and velocities accorindgly.

    + + + + + + + + @@ -2777,6 +2926,39 @@ at set intervals, and fixes their positions and velocities accorindgly.

    + + + + group + + + + + +Phaser.Group + + + + + + + + + <optional>
    + + + + + + + + + + +

    Optional Group to add the object to. If not specified it will be added to the World group.

    + + + @@ -2805,7 +2987,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    Source:
    @@ -2908,7 +3090,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    -* +any @@ -2964,7 +3146,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    - group + 'group' @@ -3001,7 +3183,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    Source:
    @@ -3188,7 +3370,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    Source:
    @@ -3239,7 +3421,281 @@ at set intervals, and fixes their positions and velocities accorindgly.

    -

    sprite(x, y, key, frame) → {Phaser.Sprite}

    +

    sound(key, volume, loop, connect) → {Phaser.Sound}

    + + +
    +
    + + +
    +

    Creates a new Sound object.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    key + + +string + + + + + + + + + + + +

    The Game.cache key of the sound that this object will use.

    volume + + +number + + + + + + <optional>
    + + + + + +
    + + 1 + +

    The volume at which the sound will be played.

    loop + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    Whether or not the sound will loop.

    connect + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    Controls if the created Sound object will connect to the master gainNode of the SoundManager when running under WebAudio.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The newly created text object.

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.Sound + + +
    +
    + + + + + +
    + + + +
    +

    sprite(x, y, key, frame, group) → {Phaser.Sprite}

    @@ -3415,6 +3871,39 @@ at set intervals, and fixes their positions and velocities accorindgly.

    + + + + group + + + + + +Phaser.Group + + + + + + + + + <optional>
    + + + + + + + + + + +

    Optional Group to add the object to. If not specified it will be added to the World group.

    + + + @@ -3494,7 +3983,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    -

    text(x, y, text, style) → {Phaser.Text}

    +

    text(x, y, text, style, group) → {Phaser.Text}

    @@ -3502,7 +3991,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    -

    Creates a new <code>Text</code>.

    +

    Creates a new Text object.

    @@ -3524,6 +4013,8 @@ at set intervals, and fixes their positions and velocities accorindgly.

    Type + Argument + @@ -3549,6 +4040,14 @@ at set intervals, and fixes their positions and velocities accorindgly.

    + + + + + + + + @@ -3572,6 +4071,14 @@ at set intervals, and fixes their positions and velocities accorindgly.

    + + + + + + + + @@ -3595,6 +4102,14 @@ at set intervals, and fixes their positions and velocities accorindgly.

    + + + + + + + + @@ -3618,6 +4133,14 @@ at set intervals, and fixes their positions and velocities accorindgly.

    + + + + + + + + @@ -3625,6 +4148,39 @@ at set intervals, and fixes their positions and velocities accorindgly.

    + + + + group + + + + + +Phaser.Group + + + + + + + + + <optional>
    + + + + + + + + + + +

    Optional Group to add the object to. If not specified it will be added to the World group.

    + + + @@ -3653,7 +4209,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    Source:
    @@ -3704,7 +4260,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    -

    tilemap(key) → {Phaser.Tilemap}

    +

    tilemap(key, tilesets) → {Phaser.Tilemap}

    @@ -3762,7 +4318,33 @@ at set intervals, and fixes their positions and velocities accorindgly.

    -

    Asset key for the JSON file.

    +

    Asset key for the JSON or CSV map data in the cache.

    + + + + + + + tilesets + + + + + +object +| + +string + + + + + + + + + +

    An object mapping Cache.tileset keys with the tileset names in the JSON file. If a string is provided that will be used.

    @@ -3794,7 +4376,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    Source:
    @@ -3845,7 +4427,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    -

    tilemapLayer(x, y, width, height) → {Phaser.TilemapLayer}

    +

    tileSprite(x, y, width, height, key, group) → {Phaser.TileSprite}

    @@ -3853,7 +4435,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    -

    Creates a new Tilemap Layer object.

    +

    Creates a new TileSprite object.

    @@ -3875,6 +4457,8 @@ at set intervals, and fixes their positions and velocities accorindgly.

    Type + Argument + @@ -3900,356 +4484,13 @@ at set intervals, and fixes their positions and velocities accorindgly.

    - - - -

    X position of the new tilemapLayer.

    - - - - - - - y - - - - + -number - - - - - - - - -

    Y position of the new tilemapLayer.

    - - - - - - - width - - - - -number - - - - - - - - -

    the width of the tilemapLayer.

    - - - - - - - height - - - - -number - - - - - - - - - -

    the height of the tilemapLayer.

    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    The newly created tilemaplayer object.

    -
    - - - -
    -
    - Type -
    -
    - -Phaser.TilemapLayer - - -
    -
    - - - - - -
    - - - -
    -

    tileset(key) → {Phaser.Tileset}

    - - -
    -
    - - -
    -

    Creates a new Tileset object.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    key - - -string - - - -

    The image key as defined in the Game.Cache to use as the tileset.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    The newly created tileset object.

    -
    - - - -
    -
    - Type -
    -
    - -Phaser.Tileset - - -
    -
    - - - - - -
    - - - -
    -

    tileSprite(x, y, width, height, key, frame) → {Phaser.TileSprite}

    - - -
    -
    - - -
    -

    Creates a new <code>TileSprite</code>.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -4274,6 +4515,14 @@ at set intervals, and fixes their positions and velocities accorindgly.

    + + @@ -4297,6 +4546,14 @@ at set intervals, and fixes their positions and velocities accorindgly.

    + + @@ -4320,6 +4577,14 @@ at set intervals, and fixes their positions and velocities accorindgly.

    + + @@ -4349,6 +4614,14 @@ at set intervals, and fixes their positions and velocities accorindgly.

    + + @@ -4359,26 +4632,33 @@ at set intervals, and fixes their positions and velocities accorindgly.

    - + + + - + @@ -4410,7 +4690,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    Source:
    @@ -4551,7 +4831,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    Source:
    @@ -4619,13 +4899,13 @@ at set intervals, and fixes their positions and velocities accorindgly.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:29 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:29 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Gamepad.html b/docs/Phaser.Gamepad.html new file mode 100644 index 00000000..aeae4f64 --- /dev/null +++ b/docs/Phaser.Gamepad.html @@ -0,0 +1,3409 @@ + + + + + + Phaser Class: Gamepad + + + + + + + + + + +
    + + +
    + + +
    + +
    + + + +

    Class: Gamepad

    +
    + +
    +

    + Phaser. + + Gamepad +

    + +

    Phaser.Gamepad

    + +
    + +
    +
    + + + + +
    +

    new Gamepad(game)

    + + +
    +
    + + +
    +

    The Gamepad class handles looking after gamepad input for your game. +Remember to call gamepad.start(); expecting input!

    +

    HTML5 GAMEPAD API SUPPORT IS AT AN EXPERIMENTAL STAGE! +At moment of writing this (end of 2013) only Chrome supports parts of it out of the box. Firefox supports it +via prefs flags (about:config, search gamepad). The browsers map the same controllers differently. +This class has constans for Windows 7 Chrome mapping of +XBOX 360 controller.

    +
    + + + + + + + +
    Parameters:
    + + +
    NameTypeDescription
    x - - -number - - - - + + + + + + + + + + + + + + + + + + + + + + + +
    framegroup -string -| - -number +Phaser.Group + + <optional>
    + + + + + +

    If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.

    Optional Group to add the object to. If not specified it will be added to the World group.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    game + + +Phaser.Game + + + +

    A reference to the currently running game.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + + + + + + + + + + + + + +

    Members

    + +
    + +
    +

    <readonly> active

    + + +
    +
    + +
    +

    If the gamepad input is active or not - if not active it should not be updated from Input.js

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    active + + +boolean + + + +

    If the gamepad input is active or not.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    callbackContext

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    callbackContext + + +Object + + + +

    The context under which the callbacks are run.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    disabled

    + + +
    +
    + +
    +

    You can disable all Gamepad Input by setting disabled to true. While true all new input related events will be ignored.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    disabled + + +boolean + + + +

    The disabled state of the Gamepad.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    game

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    game + + +Phaser.Game + + + +

    Local reference to game.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onAxisCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onAxisCallback + + +function + + + +

    This callback is invoked every time any gamepad axis is changed.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onConnectCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onConnectCallback + + +function + + + +

    This callback is invoked every time any gamepad is connected

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onDisconnectCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onDisconnectCallback + + +function + + + +

    This callback is invoked every time any gamepad is disconnected

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onDownCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onDownCallback + + +function + + + +

    This callback is invoked every time any gamepad button is pressed down.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onFloatCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onFloatCallback + + +function + + + +

    This callback is invoked every time any gamepad button is changed to a value where value > 0 and value < 1.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onUpCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onUpCallback + + +function + + + +

    This callback is invoked every time any gamepad button is released.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> pad1

    + + +
    +
    + +
    +

    Gamepad #1

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    pad1 + + +boolean + + + +

    Gamepad #1;

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> pad2

    + + +
    +
    + +
    +

    Gamepad #2

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    pad2 + + +boolean + + + +

    Gamepad #2

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> pad3

    + + +
    +
    + +
    +

    Gamepad #3

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    pad3 + + +boolean + + + +

    Gamepad #3

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> pad4

    + + +
    +
    + +
    +

    Gamepad #4

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    pad4 + + +boolean + + + +

    Gamepad #4

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> padsConnected

    + + +
    +
    + +
    +

    How many live gamepads are currently connected.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    padsConnected + + +boolean + + + +

    How many live gamepads are currently connected.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> supported

    + + +
    +
    + +
    +

    Whether or not gamepads are supported in current browser.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    supported + + +boolean + + + +

    Whether or not gamepads are supported in current browser.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + +
    + + + +

    Methods

    + +
    + +
    +

    addCallbacks(context, callbacks)

    + + +
    +
    + + +
    +

    Add callbacks to the main Gamepad handler to handle connect/disconnect/button down/button up/axis change/float value buttons

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    context + + +Object + + + +

    The context under which the callbacks are run.

    callbacks + + +Object + + + +

    Object that takes six different callback methods: +onConnectCallback, onDisconnectCallback, onDownCallback, onUpCallback, onAxisCallback, onFloatCallback

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    addCallbacks(context, callbacks)

    + + +
    +
    + + +
    +

    Add callbacks to the this Gamepad to handle connect/disconnect/button down/button up/axis change/float value buttons

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    context + + +Object + + + +

    The context under which the callbacks are run.

    callbacks + + +Object + + + +

    Object that takes six different callbak methods: +onConnectCallback, onDisconnectCallback, onDownCallback, onUpCallback, onAxisCallback, onFloatCallback

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    isDown(buttonCode) → {boolean}

    + + +
    +
    + + +
    +

    Returns true if the button is currently pressed down, on ANY gamepad.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    buttonCode + + +number + + + +

    The buttonCode of the button to check for.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if a button is currently down.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    justPressed(buttonCode, duration) → {boolean}

    + + +
    +
    + + +
    +

    Returns the "just pressed" state of a button from ANY gamepad connected. Just pressed is considered true if the button was pressed down within the duration given (default 250ms).

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    buttonCode + + +number + + + + + + + + + + + +

    The buttonCode of the button to check for.

    duration + + +number + + + + + + <optional>
    + + + + + +
    + + 250 + +

    The duration below which the button is considered as being just pressed.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the button is just pressed otherwise false.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    justPressed(buttonCode, duration) → {boolean}

    + + +
    +
    + + +
    +

    Returns the "just released" state of a button from ANY gamepad connected. Just released is considered as being true if the button was released within the duration given (default 250ms).

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    buttonCode + + +number + + + + + + + + + + + +

    The buttonCode of the button to check for.

    duration + + +number + + + + + + <optional>
    + + + + + +
    + + 250 + +

    The duration below which the button is considered as being just released.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the button is just released otherwise false.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    reset()

    + + +
    +
    + + +
    +

    Reset all buttons/axes of all gamepads

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    setDeadZones()

    + + +
    +
    + + +
    +

    Sets the deadZone variable for all four gamepads

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    start()

    + + +
    +
    + + +
    +

    Starts the Gamepad event handling. +This MUST be called manually before Phaser will start polling the Gamepad API.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    stop()

    + + +
    +
    + + +
    +

    Stops the Gamepad event handling.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + +
    + + + + + +
    + + + + + + + + +
    +
    + + + + Phaser Copyright © 2012-2014 Photon Storm Ltd. + +
    + + + Documentation generated by JSDoc 3.3.0-dev + on Wed Feb 05 2014 06:28:29 GMT-0000 (GMT) using the DocStrap template. + +
    + + + +
    +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/Phaser.GamepadButton.html b/docs/Phaser.GamepadButton.html new file mode 100644 index 00000000..8a741cdf --- /dev/null +++ b/docs/Phaser.GamepadButton.html @@ -0,0 +1,2587 @@ + + + + + + Phaser Class: GamepadButton + + + + + + + + + + +
    + + +
    + + +
    + +
    + + + +

    Class: GamepadButton

    +
    + +
    +

    + Phaser. + + GamepadButton +

    + +

    If you need more fine-grained control over the handling of specific buttons you can create and use Phaser.GamepadButton objects.

    + +
    + +
    +
    + + + + +
    +

    new GamepadButton(game, buttoncode)

    + + +
    +
    + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    game + + +Phaser.Game + + + +

    Current game instance.

    buttoncode + + +number + + + +

    The button code this GamepadButton is responsible for.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + +
    + + + + + + + + + + + + +

    Members

    + +
    + +
    +

    buttonCode

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    buttonCode + + +number + + + +

    The buttoncode of this button.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    duration

    + + +
    +
    + +
    +

    If the button is down this value holds the duration of that button press and is constantly updated. +If the button is up it holds the duration of the previous down session.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    duration + + +number + + + +

    The number of milliseconds this button has been held down for.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • 0
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    game

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    game + + +Phaser.Game + + + +

    A reference to the currently running game.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    isDown

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    isDown + + +boolean + + + +

    The "down" state of the button.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    isUp

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    isUp + + +boolean + + + +

    The "up" state of the button.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onDown

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onDown + + +Phaser.Signal + + + +

    This Signal is dispatched every time this GamepadButton is pressed down. It is only dispatched once (until the button is released again).

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onFloat

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onFloat + + +Phaser.Signal + + + +

    This Signal is dispatched every time this GamepadButton changes floating value (between (but not exactly) 0 and 1)

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onUp

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onUp + + +Phaser.Signal + + + +

    This Signal is dispatched every time this GamepadButton is pressed down. It is only dispatched once (until the button is released again).

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    repeats

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    repeats + + +number + + + +

    If a button is held down this holds down the number of times the button has 'repeated'.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • 0
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    timeDown

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    timeDown + + +number + + + +

    The timestamp when the button was last pressed down.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • 0
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    timeUp

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    timeUp + + +number + + + +

    The timestamp when the button was last released.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • 0
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    value

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    value + + +number + + + +

    Button value. Mainly useful for checking analog buttons (like shoulder triggers)

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • 0
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + +
    + + + +

    Methods

    + +
    + +
    +

    justPressed(duration) → {boolean}

    + + +
    +
    + + +
    +

    Returns the "just pressed" state of this button. Just pressed is considered true if the button was pressed down within the duration given (default 250ms).

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    duration + + +number + + + + + + <optional>
    + + + + + +
    + + 250 + +

    The duration below which the button is considered as being just pressed.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the button is just pressed otherwise false.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    justPressed(duration) → {boolean}

    + + +
    +
    + + +
    +

    Returns the "just released" state of this button. Just released is considered as being true if the button was released within the duration given (default 250ms).

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    duration + + +number + + + + + + <optional>
    + + + + + +
    + + 250 + +

    The duration below which the button is considered as being just released.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the button is just pressed otherwise false.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    <protected> processButtonDown(value)

    + + +
    +
    + + +
    +

    Called automatically by Phaser.SinglePad.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    value + + +Object + + + +

    Button value

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> processButtonFloat(value)

    + + +
    +
    + + +
    +

    Called automatically by Phaser.Gamepad.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    value + + +Object + + + +

    Button value

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> processButtonUp(value)

    + + +
    +
    + + +
    +

    Called automatically by Phaser.SinglePad.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    value + + +Object + + + +

    Button value

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + +
    + + + + + +
    + +
    + + + + +
    + +
    +
    + + + + Phaser Copyright © 2012-2014 Photon Storm Ltd. + +
    + + + Documentation generated by JSDoc 3.3.0-dev + on Wed Feb 05 2014 06:28:29 GMT-0000 (GMT) using the DocStrap template. + +
    +
    + + +
    +
    +
    + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/Phaser.Graphics.html b/docs/Phaser.Graphics.html index 8d98e7fc..75ae9f33 100644 --- a/docs/Phaser.Graphics.html +++ b/docs/Phaser.Graphics.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -739,13 +733,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:29 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:29 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Group.html b/docs/Phaser.Group.html index 4d4e8b21..79bcc812 100644 --- a/docs/Phaser.Group.html +++ b/docs/Phaser.Group.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -547,7 +541,7 @@ -

    The parent Group or DisplayObjectContainer that will hold this group, if any.

    +

    The parent Group or DisplayObjectContainer that will hold this group, if any. If undefined it will use game.world.

    @@ -743,7 +737,7 @@
    Source:
    @@ -803,7 +797,7 @@
    Source:
    @@ -863,7 +857,7 @@
    Source:
    @@ -923,7 +917,7 @@
    Source:
    @@ -983,7 +977,112 @@
    Source:
    + + + + + + + + + + + + + + + +
    +

    alive

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    alive + + +boolean + + + +

    The alive property is useful for Groups that are children of other Groups and need to be included/excluded in checks like forEachAlive.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • true
    + + + +
    Source:
    +
    @@ -1085,7 +1184,7 @@
    Source:
    @@ -1192,7 +1291,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -1299,7 +1398,7 @@ The cursor is set to the first child added to the Group and doesn't change unles
    Source:
    @@ -1404,7 +1503,7 @@ The cursor is set to the first child added to the Group and doesn't change unles
    Source:
    @@ -1506,7 +1605,109 @@ The cursor is set to the first child added to the Group and doesn't change unles
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    group

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    group + + +Phaser.Group + + + +

    The parent Group of this Group, if a child of another.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1579,7 +1780,7 @@ The cursor is set to the first child added to the Group and doesn't change unles -

    The number of children in this Group.

    +

    The total number of children in this Group, regardless of their exists/alive status.

    @@ -1608,7 +1809,7 @@ The cursor is set to the first child added to the Group and doesn't change unles
    Source:
    @@ -1710,7 +1911,109 @@ The cursor is set to the first child added to the Group and doesn't change unles
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    pivot

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    pivot + + +Phaser.Point + + + +

    The pivot point of the Group container.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1817,7 +2120,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -1890,7 +2193,7 @@ This will have no impact on the rotation value of its children, but it will upda -

    Replaces the PIXI.Point with a slightly more flexible one.

    +

    The scane of the Group container.

    @@ -1919,7 +2222,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -1992,7 +2295,7 @@ This will have no impact on the rotation value of its children, but it will upda -

    The total number of children in this Group, regardless of their alive state.

    +

    The total number of children in this Group who have a state of exists = true.

    @@ -2021,7 +2324,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -2123,7 +2426,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -2225,7 +2528,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -2332,7 +2635,7 @@ This will have no impact on the x/y coordinates of its children, but it will upd
    Source:
    @@ -2439,7 +2742,7 @@ This will have no impact on the x/y coordinates of its children, but it will upd
    Source:
    @@ -2555,7 +2858,7 @@ that then see the addAt method.

    Source:
    @@ -2775,7 +3078,7 @@ Group.addAll('x', 10) will add 10 to the child.x value.

    Source:
    @@ -2917,7 +3220,7 @@ The child is added to the Group at the location specified by the index value, th
    Source:
    @@ -3058,7 +3361,7 @@ The child is added to the Group at the location specified by the index value, th
    Source:
    @@ -3218,12 +3521,12 @@ After the method parameter and context you can add as many extra parameters as y - '' + null -

    A string containing the context under which the method will be executed. Leave to '' to default to the child.

    +

    A string containing the context under which the method will be executed. Set to null to default to the child.

    @@ -3292,7 +3595,7 @@ After the method parameter and context you can add as many extra parameters as y
    Source:
    @@ -3485,7 +3788,7 @@ After the existsValue parameter you can add as many parameters as you like, whic
    Source:
    @@ -3521,7 +3824,7 @@ After the existsValue parameter you can add as many parameters as you like, whic
    -

    Calls a function on all of the children that have exists=true in this Group.

    +

    Returns a reference to a function that exists on a child of the Group based on the given callback array.

    @@ -3649,7 +3952,76 @@ After the existsValue parameter you can add as many parameters as you like, whic
    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    childTest()

    + + +
    +
    + + +
    +

    Internal test.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -3718,7 +4090,7 @@ After the existsValue parameter you can add as many parameters as you like, whic
    Source:
    @@ -3743,7 +4115,7 @@ After the existsValue parameter you can add as many parameters as you like, whic
    -

    The number of children flagged as dead. Returns -1 if Group is empty.

    +

    The number of children flagged as dead.

    @@ -3810,7 +4182,7 @@ After the existsValue parameter you can add as many parameters as you like, whic
    Source:
    @@ -3835,7 +4207,7 @@ After the existsValue parameter you can add as many parameters as you like, whic
    -

    The number of children flagged as alive. Returns -1 if Group is empty.

    +

    The number of children flagged as alive.

    @@ -4117,7 +4489,7 @@ Useful if you don't need to create the Sprite instances before-hand.

    Source:
    @@ -4390,7 +4762,7 @@ and will be positioned at 0, 0 (relative to the Group.x/y)

    Source:
    @@ -4418,7 +4790,7 @@ and will be positioned at 0, 0 (relative to the Group.x/y)

    -

    destroy()

    +

    destroy(destroyChildren)

    @@ -4435,6 +4807,75 @@ and will be positioned at 0, 0 (relative to the Group.x/y)

    +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    destroyChildren + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    Should every child of this Group have its destroy method called?

    + +
    @@ -4459,7 +4900,7 @@ and will be positioned at 0, 0 (relative to the Group.x/y)

    Source:
    @@ -4647,145 +5088,7 @@ Group.divideAll('x', 2) will half the child.x value.

    Source:
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    dump(full)

    - - -
    -
    - - -
    -

    Dumps out a list of Group children and their index positions to the browser console. Useful for group debugging.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeArgumentDefaultDescription
    full - - -boolean - - - - - - <optional>
    - - - - - -
    - - false - -

    If full the dump will include the entire display list, start from the Stage. Otherwise it will only include this container.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -4823,7 +5126,8 @@ Group.divideAll('x', 2) will half the child.x value.

    Allows you to call your own function on each member of this Group. You must pass the callback and context in which it will run. After the checkExists parameter you can add as many parameters as you like, which will all be passed to the callback along with the child. -For example: Group.forEach(awardBonusGold, this, true, 100, 500)

    +For example: Group.forEach(awardBonusGold, this, true, 100, 500) +Note: Currently this will skip any children which are Groups themselves.

    @@ -4951,7 +5255,7 @@ For example: Group.forEach(awardBonusGold, this, true, 100, 500)

    Source:
    @@ -5094,7 +5398,7 @@ For example: Group.forEachAlive(causeDamage, this, 500)

    Source:
    @@ -5237,7 +5541,7 @@ For example: Group.forEachAlive(causeDamage, this, 500)

    Source:
    @@ -5380,7 +5684,7 @@ For example: Group.forEachDead(bringToLife, this)

    Source:
    @@ -5498,7 +5802,7 @@ For example: Group.forEachDead(bringToLife, this)

    Source:
    @@ -5591,7 +5895,7 @@ This is handy for checking if everything has been wiped out, or choosing a squad
    Source:
    @@ -5684,7 +5988,7 @@ This is handy for checking if everything has been wiped out, or choosing a squad
    Source:
    @@ -5825,7 +6129,7 @@ This is handy for checking if everything has been wiped out, or choosing a squad
    Source:
    @@ -5966,7 +6270,7 @@ This is handy for checking if everything has been wiped out, or choosing a squad
    Source:
    @@ -6130,7 +6434,7 @@ This is handy for checking if everything has been wiped out, or choosing a squad
    Source:
    @@ -6181,7 +6485,7 @@ This is handy for checking if everything has been wiped out, or choosing a squad
    -

    iterate(key, value, returnType, callback, callbackContext)

    +

    iterate(key, value, returnType, callback, callbackContext) → {any}

    @@ -6435,7 +6739,7 @@ You can add as many callback parameters as you like, which will all be passed to
    Source:
    @@ -6456,6 +6760,29 @@ You can add as many callback parameters as you like, which will all be passed to +
    Returns:
    + + +
    +

    Returns either a numeric total (if RETURN_TOTAL was specified) or the child object.

    +
    + + + +
    +
    + Type +
    +
    + +any + + +
    +
    + + +
    @@ -6623,7 +6950,7 @@ Group.multiplyAll('x', 2) will x2 the child.x value.

    Source:
    @@ -6692,7 +7019,7 @@ Group.multiplyAll('x', 2) will x2 the child.x value.

    Source:
    @@ -6761,7 +7088,7 @@ Group.multiplyAll('x', 2) will x2 the child.x value.

    Source:
    @@ -6879,7 +7206,7 @@ Group.multiplyAll('x', 2) will x2 the child.x value.

    Source:
    @@ -6972,7 +7299,7 @@ The Group container remains on the display list.

    Source:
    @@ -7113,7 +7440,7 @@ The Group container remains on the display list.

    Source:
    @@ -7254,7 +7581,329 @@ The Group container remains on the display list.

    Source:
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    set(child, key, value, checkAlive, checkVisible, operation)

    + + +
    +
    + + +
    +

    This function allows you to quickly set a property on a single child of this Group to a new value. +The operation parameter controls how the new value is assigned to the property, from simple replacement to addition and multiplication.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    child + + +Phaser.Sprite + + + + + + + + + + + +

    The child to set the property on.

    key + + +string + + + + + + + + + + + +

    The property, as a string, to be set. For example: 'body.velocity.x'

    value + + +* + + + + + + + + + + + +

    The value that will be set.

    checkAlive + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    If set then the child will only be updated if alive=true.

    checkVisible + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    If set then the child will only be updated if visible=true.

    operation + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    Controls how the value is assigned. A value of 0 replaces the value with the new one. A value of 1 adds it, 2 subtracts it, 3 multiplies it and 4 divides it.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -7541,7 +8190,7 @@ The operation parameter controls how the new value is assigned to the property,
    Source:
    @@ -7784,7 +8433,7 @@ The operation parameter controls how the new value is assigned to the property,
    Source:
    @@ -7962,7 +8611,7 @@ For example to depth sort Sprites for Zelda-style game you might call grou
    Source:
    @@ -8150,7 +8799,7 @@ Group.subAll('x', 10) will minus 10 from the child.x value.

    Source:
    @@ -8292,7 +8941,7 @@ You cannot swap a child with itself, or swap un-parented children, doing so will
    Source:
    @@ -8338,6 +8987,75 @@ You cannot swap a child with itself, or swap un-parented children, doing so will +
    + + + +
    +

    swapIndex()

    + + +
    +
    + + +
    +

    Internal test.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + +
    @@ -8360,13 +9078,13 @@ You cannot swap a child with itself, or swap un-parented children, doing so will - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:30 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:29 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Input.html b/docs/Phaser.Input.html index 524d8463..66d143c8 100644 --- a/docs/Phaser.Input.html +++ b/docs/Phaser.Input.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -615,7 +609,7 @@ The Input manager is updated automatically by the core game loop.

    Source:
    @@ -675,7 +669,7 @@ The Input manager is updated automatically by the core game loop.

    Source:
    @@ -735,7 +729,7 @@ The Input manager is updated automatically by the core game loop.

    Source:
    @@ -845,7 +839,7 @@ When you've limited max pointers to 1 this will accurately be either the first f
    Source:
    @@ -952,7 +946,7 @@ Default size of 44px (Apples recommended "finger tip" size) but can be
    Source:
    @@ -1061,7 +1055,7 @@ Default size of 44px (Apples recommended "finger tip" size) but can be
    Source:
    @@ -1171,7 +1165,7 @@ If you need to disable just one type of input, for example mouse, use Input.mous
    Source:
    @@ -1280,7 +1274,7 @@ If you need to disable just one type of input, for example mouse, use Input.mous
    Source:
    @@ -1391,6 +1385,115 @@ If you need to disable just one type of input, for example mouse, use Input.mous + + + + + + + + +
    +

    gamepad

    + + +
    +
    + +
    +

    The Gamepad Input manager.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    gamepad + + +Phaser.Gamepad + + + +

    The Gamepad Input manager.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • null
    + + + +
    Source:
    +
    + + + + + + +
    @@ -1701,7 +1804,7 @@ If you need to disable just one type of input, for example mouse, use Input.mous
    Source:
    @@ -1807,7 +1910,7 @@ If you need to disable just one type of input, for example mouse, use Input.mous
    Source:
    @@ -1916,7 +2019,7 @@ If you need to disable just one type of input, for example mouse, use Input.mous
    Source:
    @@ -2025,7 +2128,7 @@ If you need to disable just one type of input, for example mouse, use Input.mous
    Source:
    @@ -2134,7 +2237,7 @@ If you need to disable just one type of input, for example mouse, use Input.mous
    Source:
    @@ -2244,7 +2347,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -2353,7 +2456,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -2462,7 +2565,211 @@ For lots of games it's useful to set this to 1.

    Source:
    + + + + + + + + + + + + + + + +
    +

    moveCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    moveCallback + + +function + + + +

    An optional callback that will be fired every time the activePointer receives a move event from the DOM. Set to null to disable.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    moveCallbackContext

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    moveCallbackContext + + +object + + + +

    The context in which the moveCallback will be sent. Defaults to Phaser.Input but can be set to any valid JS object.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -2571,7 +2878,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -2677,7 +2984,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -2786,7 +3093,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -2895,7 +3202,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -3004,7 +3311,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -3113,7 +3420,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -3219,7 +3526,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -3325,7 +3632,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -3431,7 +3738,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -3537,7 +3844,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -3643,7 +3950,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -3749,7 +4056,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -3855,7 +4162,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -3961,7 +4268,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -4067,7 +4374,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -4173,7 +4480,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -4275,7 +4582,7 @@ For lots of games it's useful to set this to 1.

    Source:
    @@ -4385,7 +4692,7 @@ A value of 0 means every single frame (60fps), a value of 1 means every other fr
    Source:
    @@ -4490,7 +4797,7 @@ A value of 0 means every single frame (60fps), a value of 1 means every other fr
    Source:
    @@ -4600,7 +4907,7 @@ If the Pointer is tracking one event every 100ms, then a trackLimit of 100 would
    Source:
    @@ -4711,7 +5018,7 @@ The history is updated at the rate specified in Input.pollRate

    Source:
    @@ -4820,7 +5127,7 @@ The history is updated at the rate specified in Input.pollRate

    Source:
    @@ -4927,7 +5234,7 @@ In an un-scaled game the values will be x: 1 and y: 1.

    Source:
    @@ -5033,7 +5340,7 @@ In an un-scaled game the values will be x: 1 and y: 1.

    Source:
    @@ -5142,7 +5449,7 @@ In an un-scaled game the values will be x: 1 and y: 1.

    Source:
    @@ -5248,7 +5555,7 @@ In an un-scaled game the values will be x: 1 and y: 1.

    Source:
    @@ -5354,7 +5661,7 @@ In an un-scaled game the values will be x: 1 and y: 1.

    Source:
    @@ -5463,7 +5770,7 @@ In an un-scaled game the values will be x: 1 and y: 1.

    Source:
    @@ -5569,7 +5876,7 @@ In an un-scaled game the values will be x: 1 and y: 1.

    Source:
    @@ -5675,7 +5982,7 @@ In an un-scaled game the values will be x: 1 and y: 1.

    Source:
    @@ -5781,7 +6088,7 @@ In an un-scaled game the values will be x: 1 and y: 1.

    Source:
    @@ -5887,7 +6194,7 @@ In an un-scaled game the values will be x: 1 and y: 1.

    Source:
    @@ -5953,7 +6260,7 @@ If you need more then use this to create a new one, up to a maximum of 10.

    Source:
    @@ -6045,7 +6352,7 @@ If you need more then use this to create a new one, up to a maximum of 10.

    Source:
    @@ -6114,7 +6421,7 @@ If you need more then use this to create a new one, up to a maximum of 10.

    Source:
    @@ -6232,7 +6539,7 @@ If you need more then use this to create a new one, up to a maximum of 10.

    Source:
    @@ -6373,7 +6680,7 @@ If you need more then use this to create a new one, up to a maximum of 10.

    Source:
    @@ -6514,7 +6821,7 @@ If you need more then use this to create a new one, up to a maximum of 10.

    Source:
    @@ -6655,7 +6962,150 @@ If you need more then use this to create a new one, up to a maximum of 10.

    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    setMoveCallback(callback, callbackContext)

    + + +
    +
    + + +
    +

    Sets a callback that is fired every time the activePointer receives a DOM move event such as a mousemove or touchmove. +It will be called every time the activePointer moves, which in a multi-touch game can be a lot of times, so this is best +to only use if you've limited input to a single pointer (i.e. mouse or touch)

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    callback + + +function + + + +

    The callback that will be called each time the activePointer receives a DOM move event.

    callbackContext + + +object + + + +

    The context in which the callback will be called.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -6773,7 +7223,7 @@ If you need more then use this to create a new one, up to a maximum of 10.

    Source:
    @@ -6914,7 +7364,7 @@ If you need more then use this to create a new one, up to a maximum of 10.

    Source:
    @@ -7006,7 +7456,7 @@ If you need more then use this to create a new one, up to a maximum of 10.

    Source:
    @@ -7124,7 +7574,7 @@ If you need more then use this to create a new one, up to a maximum of 10.

    Source:
    @@ -7192,13 +7642,13 @@ If you need more then use this to create a new one, up to a maximum of 10.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:30 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.InputHandler.html b/docs/Phaser.InputHandler.html index 07ac1b8b..d9e43038 100644 --- a/docs/Phaser.InputHandler.html +++ b/docs/Phaser.InputHandler.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -659,7 +653,7 @@
    Source:
    @@ -764,7 +758,7 @@
    Source:
    @@ -869,7 +863,7 @@
    Source:
    @@ -974,7 +968,7 @@
    Source:
    @@ -1079,7 +1073,7 @@
    Source:
    @@ -1189,7 +1183,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
    Source:
    @@ -1294,7 +1288,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
    Source:
    @@ -1606,7 +1600,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
    Source:
    @@ -1711,7 +1705,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
    Source:
    @@ -1816,7 +1810,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
    Source:
    @@ -1921,7 +1915,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
    Source:
    @@ -2024,6 +2018,111 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    snapOffsetX

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    snapOffsetX + + +number + + + +

    This defines the top-left X coordinate of the snap grid.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • 0
    + + +
    Source:
    + + + +
    + + + +
    +

    snapOffsetY

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    snapOffsetY + + +number + + + +

    This defines the top-left Y coordinate of the snap grid..

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • 0
    + + + +
    Source:
    +
    + + + + + + +
    @@ -2131,7 +2335,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
    Source:
    @@ -2236,7 +2440,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
    Source:
    @@ -2341,7 +2545,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
    Source:
    @@ -2446,7 +2650,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
    Source:
    @@ -2653,7 +2857,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
    Source:
    @@ -2718,7 +2922,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
    Source:
    @@ -2787,7 +2991,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
    Source:
    @@ -2929,7 +3133,7 @@ It compares the alpha value of the pixel and if >= InputHandler.pixelPerfectA
    Source:
    @@ -3070,7 +3274,7 @@ It compares the alpha value of the pixel and if >= InputHandler.pixelPerfectA
    Source:
    @@ -3158,7 +3362,7 @@ It compares the alpha value of the pixel and if >= InputHandler.pixelPerfectA
    Source:
    @@ -3227,7 +3431,7 @@ It compares the alpha value of the pixel and if >= InputHandler.pixelPerfectA
    Source:
    @@ -3296,7 +3500,7 @@ It compares the alpha value of the pixel and if >= InputHandler.pixelPerfectA
    Source:
    @@ -3414,7 +3618,7 @@ It compares the alpha value of the pixel and if >= InputHandler.pixelPerfectA
    Source:
    @@ -3770,7 +3974,7 @@ It compares the alpha value of the pixel and if >= InputHandler.pixelPerfectA
    Source:
    @@ -3798,7 +4002,7 @@ It compares the alpha value of the pixel and if >= InputHandler.pixelPerfectA
    -

    enableSnap(snapX, snapY, onDrag, onRelease)

    +

    enableSnap(snapX, snapY, onDrag, onRelease, snapOffsetX, snapOffsetX)

    @@ -3990,6 +4194,84 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16 + + + + snapOffsetX + + + + + +number + + + + + + + + + <optional>
    + + + + + + + + + + + + 0 + + + + +

    Used to offset the top-left starting point of the snap grid.

    + + + + + + + snapOffsetX + + + + + +number + + + + + + + + + <optional>
    + + + + + + + + + + + + 0 + + + + +

    Used to offset the top-left starting point of the snap grid.

    + + + @@ -4018,7 +4300,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -4159,7 +4441,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -4319,7 +4601,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -4479,7 +4761,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -4639,7 +4921,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -4776,7 +5058,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -4917,7 +5199,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -5066,7 +5348,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -5219,7 +5501,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -5360,7 +5642,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -5497,7 +5779,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -5634,7 +5916,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -5771,7 +6053,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -5908,7 +6190,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -6045,7 +6327,7 @@ For example 16x16 as the snapX and snapY would make the sprite snap to every 16
    Source:
    @@ -6183,7 +6465,7 @@ This value is only set when the pointer is over this Sprite.

    Source:
    @@ -6325,7 +6607,7 @@ This value is only set when the pointer is over this Sprite.

    Source:
    @@ -6417,7 +6699,7 @@ This value is only set when the pointer is over this Sprite.

    Source:
    @@ -6594,7 +6876,7 @@ This value is only set when the pointer is over this Sprite.

    Source:
    @@ -6735,7 +7017,7 @@ This value is only set when the pointer is over this Sprite.

    Source:
    @@ -6876,7 +7158,7 @@ This value is only set when the pointer is over this Sprite.

    Source:
    @@ -6945,7 +7227,7 @@ This value is only set when the pointer is over this Sprite.

    Source:
    @@ -7063,7 +7345,7 @@ This value is only set when the pointer is over this Sprite.

    Source:
    @@ -7181,7 +7463,7 @@ This value is only set when the pointer is over this Sprite.

    Source:
    @@ -7299,7 +7581,7 @@ This value is only set when the pointer is over this Sprite.

    Source:
    @@ -7363,13 +7645,13 @@ This value is only set when the pointer is over this Sprite.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:30 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Key.html b/docs/Phaser.Key.html index 0c7e96ca..1f8e66e1 100644 --- a/docs/Phaser.Key.html +++ b/docs/Phaser.Key.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -2530,13 +2524,13 @@ If the key is up it holds the duration of the previous down session.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:30 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Keyboard.html b/docs/Phaser.Keyboard.html index 3d97273c..3e720486 100644 --- a/docs/Phaser.Keyboard.html +++ b/docs/Phaser.Keyboard.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1362,7 +1356,7 @@ The Key object can then be polled, have events attached to it, etc.

    -

    The keycode of the key, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR

    +

    The keycode of the key, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR

    @@ -1785,7 +1779,7 @@ Pass in either a single keycode or an array/hash of keycodes.

    -

    The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR

    +

    The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR

    @@ -1942,7 +1936,7 @@ Pass in either a single keycode or an array/hash of keycodes.

    -

    The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR

    +

    The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR

    @@ -2064,7 +2058,7 @@ Pass in either a single keycode or an array/hash of keycodes.

    -

    justPressed(keycode, duration) → {boolean}

    +

    justReleased(keycode, duration) → {boolean}

    @@ -2138,7 +2132,7 @@ Pass in either a single keycode or an array/hash of keycodes.

    -

    The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR

    +

    The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR

    @@ -2554,7 +2548,7 @@ Pass in either a single keycode or an array/hash of keycodes.

    -

    The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR

    +

    The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR

    @@ -2957,13 +2951,13 @@ This is called automatically by Phaser.Input and should not normally be invoked - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:30 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Line.html b/docs/Phaser.Line.html new file mode 100644 index 00000000..5f974cbf --- /dev/null +++ b/docs/Phaser.Line.html @@ -0,0 +1,3100 @@ + + + + + + Phaser Class: Line + + + + + + + + + + +
    + + +
    + + +
    + +
    + + + +

    Class: Line

    +
    + +
    +

    + Phaser. + + Line +

    + +

    Phaser - Line

    + +
    + +
    +
    + + + + +
    +

    new Line(x1, y1, x2, y2) → {Phaser.Line}

    + + +
    +
    + + +
    +

    Creates a new Line object with a start and an end point.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    x1 + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    The x coordinate of the start of the line.

    y1 + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    The y coordinate of the start of the line.

    x2 + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    The x coordinate of the end of the line.

    y2 + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    The y coordinate of the end of the line.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    This line object

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.Line + + +
    +
    + + + + + +
    + + +
    + + + + + + + + + + + + +

    Members

    + +
    + +
    +

    <readonly> angle

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    angle + + +number + + + +

    Gets the angle of the line.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    end

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    end + + +Phaser.Point + + + +

    The end point of the line.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> length

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    length + + +number + + + +

    Gets the length of the line segment.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> perpSlope

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    perpSlope + + +number + + + +

    Gets the perpendicular slope of the line (x/y).

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> slope

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    slope + + +number + + + +

    Gets the slope of the line (y/x).

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    start

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    start + + +Phaser.Point + + + +

    The start point of the line.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + +
    + + + +

    Methods

    + +
    + +
    +

    <static> intersects(a, b, e, f, asSegment, result) → {Phaser.Point}

    + + +
    +
    + + +
    +

    Checks for intersection between two lines as defined by the given start and end points. +If asSegment is true it will check for line segment intersection. If asSegment is false it will check for line intersection. +Returns the intersection segment of AB and EF as a Point, or null if there is no intersection. +Adapted from code by Keith Hair

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    a + + +Phaser.Point + + + + + + + + + + + +

    The start of the first Line to be checked.

    b + + +Phaser.Point + + + + + + + + + + + +

    The end of the first line to be checked.

    e + + +Phaser.Point + + + + + + + + + + + +

    The start of the second Line to be checked.

    f + + +Phaser.Point + + + + + + + + + + + +

    The end of the second line to be checked.

    asSegment + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true it will check for segment intersection, otherwise full line intersection.

    result + + +Phaser.Point + + + + + + <optional>
    + + + + + +
    + +

    A Point object to store the result in, if not given a new one will be created.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The intersection segment of the two lines as a Point, or null if there is no intersection.

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.Point + + +
    +
    + + + + + +
    + + + +
    +

    <static> intersects(a, b, asSegment, result) → {Phaser.Point}

    + + +
    +
    + + +
    +

    Checks for intersection between two lines. +If asSegment is true it will check for segment intersection. +If asSegment is false it will check for line intersection. +Returns the intersection segment of AB and EF as a Point, or null if there is no intersection. +Adapted from code by Keith Hair

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    a + + +Phaser.Line + + + + + + + + + + + +

    The first Line to be checked.

    b + + +Phaser.Line + + + + + + + + + + + +

    The second Line to be checked.

    asSegment + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true it will check for segment intersection, otherwise full line intersection.

    result + + +Phaser.Point + + + + + + <optional>
    + + + + + +
    + +

    A Point object to store the result in, if not given a new one will be created.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The intersection segment of the two lines as a Point, or null if there is no intersection.

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.Point + + +
    +
    + + + + + +
    + + + +
    +

    fromSprite(startSprite, endSprite, useCenter) → {Phaser.Line}

    + + +
    +
    + + +
    +

    Sets the line to match the x/y coordinates of the two given sprites. +Can optionally be calculated from their center coordinates.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    startSprite + + +Phaser.Sprite + + + + + + + + + + + +

    The coordinates of this Sprite will be set to the Line.start point.

    endSprite + + +Phaser.Sprite + + + + + + + + + + + +

    The coordinates of this Sprite will be set to the Line.start point.

    useCenter + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true it will use startSprite.center.x, if false startSprite.x.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    This line object

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.Line + + +
    +
    + + + + + +
    + + + +
    +

    intersects(line, asSegment, result) → {Phaser.Point}

    + + +
    +
    + + +
    +

    Checks for intersection between this line and another Line. +If asSegment is true it will check for segment intersection. If asSegment is false it will check for line intersection. +Returns the intersection segment of AB and EF as a Point, or null if there is no intersection.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    line + + +Phaser.Line + + + + + + + + + + + +

    The line to check against this one.

    asSegment + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true it will check for segment intersection, otherwise full line intersection.

    result + + +Phaser.Point + + + + + + <optional>
    + + + + + +
    + +

    A Point object to store the result in, if not given a new one will be created.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The intersection segment of the two lines as a Point, or null if there is no intersection.

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.Point + + +
    +
    + + + + + +
    + + + +
    +

    pointOnLine(x, y) → {boolean}

    + + +
    +
    + + +
    +

    Tests if the given coordinates fall on this line. See pointOnSegment to test against just the line segment.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    x + + +number + + + +

    The line to check against this one.

    y + + +number + + + +

    The line to check against this one.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the point is on the line, false if not.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    pointOnSegment(x, y) → {boolean}

    + + +
    +
    + + +
    +

    Tests if the given coordinates fall on this line and within the segment. See pointOnLine to test against just the line.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    x + + +number + + + +

    The line to check against this one.

    y + + +number + + + +

    The line to check against this one.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the point is on the line and segment, false if not.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    setTo(x1, y1, x2, y2) → {Phaser.Line}

    + + +
    +
    + + +
    +

    Sets the components of the Line to the specified values.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    x1 + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    The x coordinate of the start of the line.

    y1 + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    The y coordinate of the start of the line.

    x2 + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    The x coordinate of the end of the line.

    y2 + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    The y coordinate of the end of the line.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    This line object

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.Line + + +
    +
    + + + + + +
    + +
    + + + + + +
    + +
    + + + + +
    + +
    +
    + + + + Phaser Copyright © 2012-2014 Photon Storm Ltd. + +
    + + + Documentation generated by JSDoc 3.3.0-dev + on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template. + +
    +
    + + +
    +
    +
    + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/Phaser.LinkedList.html b/docs/Phaser.LinkedList.html index 20f03dc3..8f1018e0 100644 --- a/docs/Phaser.LinkedList.html +++ b/docs/Phaser.LinkedList.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1449,13 +1443,13 @@ The function must exist on the member.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:30 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Loader.html b/docs/Phaser.Loader.html index 77f5cf83..eca96ed4 100644 --- a/docs/Phaser.Loader.html +++ b/docs/Phaser.Loader.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -617,7 +611,7 @@ It uses a combination of Image() loading and xhr and provides progress and compl
    Source:
    @@ -677,7 +671,7 @@ It uses a combination of Image() loading and xhr and provides progress and compl
    Source:
    @@ -737,7 +731,7 @@ It uses a combination of Image() loading and xhr and provides progress and compl
    Source:
    @@ -845,7 +839,7 @@ MUST have / on the end of it!

    Source:
    @@ -947,7 +941,7 @@ MUST have / on the end of it!

    Source:
    @@ -1361,7 +1355,7 @@ MUST have / on the end of it!

    Source:
    @@ -1463,7 +1457,7 @@ MUST have / on the end of it!

    Source:
    @@ -1565,7 +1559,7 @@ MUST have / on the end of it!

    Source:
    @@ -1667,7 +1661,7 @@ MUST have / on the end of it!

    Source:
    @@ -1735,7 +1729,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag -Description +Phaser.Sprite @@ -1777,7 +1771,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -1850,7 +1844,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag -

    The Load progress percentage value (from 0 to 100)

    +

    The rounded load progress percentage value (from 0 to 100)

    @@ -1891,6 +1885,111 @@ If you do so the Sprite's width or height will be cropped based on the percentag + + + + + + + + +
    +

    progressFloat

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    progressFloat + + +number + + + +

    The non-rounded load progress value (from 0.0 to 100.0)

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • 0
    + + + +
    Source:
    +
    + + + + + + +
    @@ -2065,7 +2164,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -2323,7 +2422,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -2571,7 +2670,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -2819,7 +2918,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -3067,7 +3166,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -3189,7 +3288,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag -Array +Array | string @@ -3257,7 +3356,257 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    + + + + + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    This Loader instance.

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.Loader + + +
    +
    + + + + + + + + + +
    +

    binary(key, url, callback, callbackContext) → {Phaser.Loader}

    + + +
    +
    + + +
    +

    Add a binary file to the Loader. It will be loaded via xhr with a responseType of "arraybuffer". You can specify an optional callback to process the file after load. +When the callback is called it will be passed 2 parameters: the key of the file and the file data. +WARNING: If you specify a callback, the file data will be set to whatever your callback returns. So always return the data object, even if you didn't modify it.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDescription
    key + + +string + + + + + + + + + +

    Unique asset key of the binary file.

    url + + +string + + + + + + + + + +

    URL of the binary file.

    callback + + +function + + + + + + <optional>
    + + + + + +

    Optional callback that will be passed the file after loading, so you can perform additional processing on it.

    callbackContext + + +function + + + + + + <optional>
    + + + + + +

    The context under which the callback will be applied. If not specified it will use the callback itself as the context.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -3505,7 +3854,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -3669,7 +4018,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -3810,7 +4159,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -3928,7 +4277,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -4046,7 +4395,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -4164,7 +4513,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -4305,7 +4654,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -4536,7 +4885,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -4677,7 +5026,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -4746,7 +5095,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -4887,7 +5236,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -5074,7 +5423,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -5143,7 +5492,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -5284,7 +5633,7 @@ If you do so the Sprite's width or height will be cropped based on the percentag
    Source:
    @@ -5482,7 +5831,7 @@ This allows you to easily make loading bars for games.

    Source:
    @@ -5510,7 +5859,7 @@ This allows you to easily make loading bars for games.

    -

    spritesheet(key, url, frameWidth, frameHeight, frameMax) → {Phaser.Loader}

    +

    spritesheet(key, url, frameWidth, frameHeight, frameMax, margin, spacing) → {Phaser.Loader}

    @@ -5732,6 +6081,84 @@ This allows you to easily make loading bars for games.

    + + + + margin + + + + + +number + + + + + + + + + <optional>
    + + + + + + + + + + + + 0 + + + + +

    If the frames have been drawn with a margin, specify the amount here.

    + + + + + + + spacing + + + + + +number + + + + + + + + + <optional>
    + + + + + + + + + + + + 0 + + + + +

    If the frames have been drawn with spacing between them, specify the amount here.

    + + + @@ -5760,7 +6187,7 @@ This allows you to easily make loading bars for games.

    Source:
    @@ -5852,7 +6279,7 @@ This allows you to easily make loading bars for games.

    Source:
    @@ -6060,7 +6487,7 @@ This allows you to easily make loading bars for games.

    Source:
    @@ -6330,386 +6757,7 @@ This allows you to easily make loading bars for games.

    Source:
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    This Loader instance.

    -
    - - - -
    -
    - Type -
    -
    - -Phaser.Loader - - -
    -
    - - - - - -
    - - - -
    -

    tileset(key, url, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) → {Phaser.Loader}

    - - -
    -
    - - -
    -

    Add a new tile set to the loader. These are used in the rendering of tile maps.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeArgumentDefaultDescription
    key - - -string - - - - - - - - - - - -

    Unique asset key of the tileset file.

    url - - -string - - - - - - - - - - - -

    URL of the tileset.

    tileWidth - - -number - - - - - - - - - - - -

    Width of each single tile in pixels.

    tileHeight - - -number - - - - - - - - - - - -

    Height of each single tile in pixels.

    tileMax - - -number - - - - - - <optional>
    - - - - - -
    - - -1 - -

    How many tiles in this tileset. If not specified it will divide the whole image into tiles.

    tileMargin - - -number - - - - - - <optional>
    - - - - - -
    - - 0 - -

    If the tiles have been drawn with a margin, specify the amount here.

    tileSpacing - - -number - - - - - - <optional>
    - - - - - -
    - - 0 - -

    If the tiles have been drawn with spacing between them, specify the amount here.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -6801,7 +6849,7 @@ This allows you to easily make loading bars for games.

    Source:
    @@ -6893,7 +6941,7 @@ This allows you to easily make loading bars for games.

    Source:
    @@ -7034,7 +7082,7 @@ This allows you to easily make loading bars for games.

    Source:
    @@ -7079,13 +7127,13 @@ This allows you to easily make loading bars for games.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:30 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.LoaderParser.html b/docs/Phaser.LoaderParser.html index 01765371..e5052246 100644 --- a/docs/Phaser.LoaderParser.html +++ b/docs/Phaser.LoaderParser.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -681,13 +675,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:31 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.MSPointer.html b/docs/Phaser.MSPointer.html index b3a18ed0..1726c1aa 100644 --- a/docs/Phaser.MSPointer.html +++ b/docs/Phaser.MSPointer.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1399,13 +1393,13 @@ It will work only in Internet Explorer 10 and Windows Store or Windows Phone 8 a - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:31 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Math.html b/docs/Phaser.Math.html index 155a841e..41f67fbc 100644 --- a/docs/Phaser.Math.html +++ b/docs/Phaser.Math.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -531,7 +525,7 @@
    -

    Find the angle of a segment from (x1, y1) -> (x2, y2 ).

    +

    Find the angle of a segment from (x1, y1) -> (x2, y2).

    @@ -865,7 +859,7 @@
    Source:
    @@ -1117,7 +1111,7 @@
    Source:
    @@ -1172,7 +1166,7 @@
    -

    Description.

    +

    A Bezier Interpolation Method, mostly used by Phaser.Tween.

    @@ -1277,7 +1271,7 @@
    Source:
    @@ -1506,7 +1500,7 @@
    Source:
    @@ -1561,7 +1555,7 @@
    -

    Description.

    +

    A Catmull Rom Interpolation Method, mostly used by Phaser.Tween.

    @@ -1666,7 +1660,7 @@
    Source:
    @@ -1803,7 +1797,7 @@
    Source:
    @@ -2127,7 +2121,7 @@ of getting a bonus, call chanceRoll(30) - true means the chance passed, false me
    Source:
    @@ -2315,7 +2309,7 @@ Clamp value to range <a, b>

    Source:
    @@ -2475,7 +2469,7 @@ Clamp value to range <a, b>

    Source:
    @@ -2563,7 +2557,7 @@ Clamp value to range <a, b>

    Source:
    @@ -2719,7 +2713,7 @@ Clamp value to range <a, b>

    Source:
    @@ -2925,7 +2919,7 @@ Clamp value to range <a, b>

    Source:
    @@ -2950,7 +2944,308 @@ Clamp value to range <a, b>

    -

    The distance between this Point object and the destination Point object.

    +

    The distance between the two sets of coordinates.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    distancePow(x1, y1, x2, y2, pow) → {number}

    + + +
    +
    + + +
    +

    Returns the distance between the two given set of coordinates at the power given.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    x1 + + +number + + + + + + + + + + + +
    y1 + + +number + + + + + + + + + + + +
    x2 + + +number + + + + + + + + + + + +
    y2 + + +number + + + + + + + + + + + +
    pow + + +number + + + + + + <optional>
    + + + + + +
    + + 2 + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The distance between the two sets of coordinates.

    @@ -3135,7 +3430,7 @@ Clamp value to range <a, b>

    Source:
    @@ -3276,7 +3571,7 @@ Clamp value to range <a, b>

    Source:
    @@ -4524,7 +4819,7 @@ Will return null if random selection is missing, or array has no entries.

    Source:
    @@ -4757,7 +5052,7 @@ Will return null if random selection is missing, or array has no entries.

    Source:
    @@ -5077,7 +5372,7 @@ Will return null if random selection is missing, or array has no entries.

    Source:
    @@ -5218,7 +5513,7 @@ Will return null if random selection is missing, or array has no entries.

    Source:
    @@ -5405,7 +5700,7 @@ Will return null if random selection is missing, or array has no entries.

    Source:
    @@ -5460,7 +5755,7 @@ Will return null if random selection is missing, or array has no entries.

    -

    Description.

    +

    A Linear Interpolation Method, mostly used by Phaser.Tween.

    @@ -5565,7 +5860,7 @@ Will return null if random selection is missing, or array has no entries.

    Source:
    @@ -5817,7 +6112,7 @@ Will return null if random selection is missing, or array has no entries.

    Source:
    @@ -5906,7 +6201,7 @@ See http://jsperf.com/m
    Source:
    @@ -5952,6 +6247,98 @@ See http://jsperf.com/m + + + + +
    +

    max() → {number}

    + + +
    +
    + + +
    +

    Updated version of Math.max that can be passed either an array of numbers or the numbers as parameters.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The largest value from those given.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + +
    @@ -6093,7 +6480,7 @@ See http://jsperf.com/m
    Source:
    @@ -6135,6 +6522,99 @@ See http://jsperf.com/m + + + + +
    +

    maxProperty() → {number}

    + + +
    +
    + + +
    +

    Updated version of Math.max that can be passed a property and either an array of objects or the objects as parameters. +It will find the largest matching property value from the given objects.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The largest value from those given.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + +
    @@ -6148,7 +6628,7 @@ See http://jsperf.com/m @@ -6182,7 +6662,100 @@ See http://jsperf.com/m
    Source:
    + + + + + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The lowest value from those given.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + +
    +

    minProperty() → {number}

    + + +
    +
    + + +
    +

    Updated version of Math.min that can be passed a property and either an array of objects or the objects as parameters. +It will find the lowest matching property value from the given objects.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -6369,7 +6942,7 @@ See http://jsperf.com/m
    Source:
    @@ -6428,8 +7001,7 @@ See http://jsperf.com/m
    -

    Closest angle between two angles from a1 to a2 -absolute value the return for exact angle

    +

    Closest angle between two angles from a1 to a2 absolute value the return for exact angle

    @@ -6557,7 +7129,7 @@ absolute value the return for exact angle

    Source:
    @@ -6604,7 +7176,7 @@ absolute value the return for exact angle

    -

    normalizeAngle(angle, radians) → {number}

    +

    normalizeAngle(angleRad) → {number}

    @@ -6612,7 +7184,7 @@ absolute value the return for exact angle

    -

    Set an angle within the bounds of -π toπ.

    +

    Normalizes an angle to the [0,2pi) range.

    @@ -6646,7 +7218,7 @@ absolute value the return for exact angle

    - angle + angleRad @@ -6662,30 +7234,7 @@ absolute value the return for exact angle

    - - - - - - - - radians - - - - - -boolean - - - - - - - - - -

    True if angle size is expressed in radians.

    +

    The angle to normalize, in radians.

    @@ -6717,7 +7266,7 @@ absolute value the return for exact angle

    Source:
    @@ -6741,6 +7290,292 @@ absolute value the return for exact angle

    Returns:
    +
    +

    Returns the angle, fit within the [0,2pi] range, in radians.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    normalizeLatitude(lat) → {number}

    + + +
    +
    + + +
    +

    Normalizes a latitude to the [-90,90] range. Latitudes above 90 or below -90 are capped, not wrapped.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    lat + + +number + + + +

    The latitude to normalize, in degrees.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    Returns the latitude, fit within the [-90,90] range.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    normalizeLongitude(lng) → {number}

    + + +
    +
    + + +
    +

    Normalizes a longitude to the [-180,180] range. Longitudes above 180 or below -180 are wrapped.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    lng + + +number + + + +

    The longitude to normalize, in degrees.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    Returns the longitude, fit within the [-180,180] range.

    +
    +
    @@ -6877,7 +7712,7 @@ absolute value the return for exact angle

    Source:
    @@ -7038,7 +7873,7 @@ absolute value the return for exact angle

    Source:
    @@ -7126,7 +7961,7 @@ absolute value the return for exact angle

    Source:
    @@ -7172,6 +8007,147 @@ absolute value the return for exact angle

    +
    + + + +
    +

    reverseAngle(angleRad) → {number}

    + + +
    +
    + + +
    +

    Reverses an angle.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    angleRad + + +number + + + +

    The angle to reverse, in radians.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    Returns the reverse angle, in radians.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + +
    @@ -7611,7 +8587,7 @@ The original stack is modified in the process. This effectively moves the positi
    Source:
    @@ -7752,7 +8728,7 @@ The original stack is modified in the process. This effectively moves the positi
    Source:
    @@ -7894,7 +8870,7 @@ The original stack is modified in the process. This effectively moves the positi
    Source:
    @@ -7941,7 +8917,7 @@ The original stack is modified in the process. This effectively moves the positi
    -

    sinCosGenerator(length, sinAmplitude, cosAmplitude, frequency) → {Array}

    +

    sinCosGenerator(length, sinAmplitude, cosAmplitude, frequency) → {Array}

    @@ -8104,7 +9080,7 @@ you should get the results via getSinTable() and getCosTable(). This generator i
    Source:
    @@ -8140,7 +9116,7 @@ you should get the results via getSinTable() and getCosTable(). This generator i
    -Array +Array
    @@ -8291,7 +9267,7 @@ you should get the results via getSinTable() and getCosTable(). This generator i
    Source:
    @@ -8474,7 +9450,7 @@ you should get the results via getSinTable() and getCosTable(). This generator i
    Source:
    @@ -9609,7 +10585,7 @@ you should get the results via getSinTable() and getCosTable(). This generator i
    Source:
    @@ -9668,8 +10644,8 @@ you should get the results via getSinTable() and getCosTable(). This generator i
    -

    Ensures that the value always stays between min and max, by wrapping the value around.

    -

    <p>max should be larger than min, or the function will return 0</p>

    +

    Ensures that the value always stays between min and max, by wrapping the value around. +max should be larger than min, or the function will return 0.

    @@ -9708,13 +10684,18 @@ you should get the results via getSinTable() and getCosTable(). This generator i + +number + + + -

    The value to wrap

    +

    The value to wrap.

    @@ -9726,13 +10707,18 @@ you should get the results via getSinTable() and getCosTable(). This generator i + +number + + + -

    The minimum the value is allowed to be

    +

    The minimum the value is allowed to be.

    @@ -9744,13 +10730,18 @@ you should get the results via getSinTable() and getCosTable(). This generator i + +number + + + -

    The maximum the value is allowed to be

    +

    The maximum the value is allowed to be.

    @@ -9782,7 +10773,7 @@ you should get the results via getSinTable() and getCosTable(). This generator i
    Source:
    @@ -9807,7 +10798,7 @@ you should get the results via getSinTable() and getCosTable(). This generator i
    -

    The wrapped value

    +

    The wrapped value.

    @@ -9924,7 +10915,7 @@ Should be called whenever the angle is updated on the Sprite to stop it from goi
    Source:
    @@ -10112,7 +11103,7 @@ Should be called whenever the angle is updated on the Sprite to stop it from goi
    Source:
    @@ -10180,13 +11171,13 @@ Should be called whenever the angle is updated on the Sprite to stop it from goi - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:31 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Mouse.html b/docs/Phaser.Mouse.html index f4b01f6c..03806212 100644 --- a/docs/Phaser.Mouse.html +++ b/docs/Phaser.Mouse.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -614,7 +608,7 @@
    Source:
    @@ -674,7 +668,7 @@
    Source:
    @@ -734,7 +728,7 @@
    Source:
    @@ -794,7 +788,7 @@
    Source:
    @@ -1278,7 +1272,7 @@ -

    The browser mouse event.

    +

    The browser mouse DOM event. Will be set to null if no mouse event has ever been received.

    @@ -1303,11 +1297,14 @@ +
    Default Value:
    +
    • null
    +
    Source:
    @@ -2036,7 +2033,7 @@
    Source:
    @@ -2154,7 +2151,7 @@
    Source:
    @@ -2272,7 +2269,7 @@
    Source:
    @@ -2390,7 +2387,7 @@
    Source:
    @@ -2459,7 +2456,7 @@
    Source:
    @@ -2530,7 +2527,7 @@ If the browser successfully enters a locked state the event Phaser.Mouse.pointer
    Source:
    @@ -2599,7 +2596,7 @@ If the browser successfully enters a locked state the event Phaser.Mouse.pointer
    Source:
    @@ -2668,7 +2665,7 @@ If the browser successfully enters a locked state the event Phaser.Mouse.pointer
    Source:
    @@ -2713,13 +2710,13 @@ If the browser successfully enters a locked state the event Phaser.Mouse.pointer - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:31 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Net.html b/docs/Phaser.Net.html index 2bda1c19..5c69959d 100644 --- a/docs/Phaser.Net.html +++ b/docs/Phaser.Net.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1343,13 +1337,13 @@ Optionally you can redirect to the new url, or just return it as a string.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:31 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Particles.Arcade.Emitter.html b/docs/Phaser.Particles.Arcade.Emitter.html index 31518443..bc65c282 100644 --- a/docs/Phaser.Particles.Arcade.Emitter.html +++ b/docs/Phaser.Particles.Arcade.Emitter.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -710,6 +704,116 @@ at set intervals, and fixes their positions and velocities accorindgly.

    +
    +

    alive

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    alive + + +boolean + + + +

    The alive property is useful for Groups that are children of other Groups and need to be included/excluded in checks like forEachAlive.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + +
    Default Value:
    +
    • true
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + +

    alpha

    @@ -799,7 +903,7 @@ at set intervals, and fixes their positions and velocities accorindgly.

    Source:
    @@ -911,7 +1015,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -935,10 +1039,6 @@ This will have no impact on the rotation value of its children, but it will upda
    -
    -

    The angular drag component of particles launched from the emitter if they are rotating.

    -
    - @@ -988,7 +1088,7 @@ This will have no impact on the rotation value of its children, but it will upda - +

    The angular drag component of particles launched from the emitter if they are rotating.

    @@ -1020,7 +1120,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -1122,7 +1222,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -1146,10 +1246,6 @@ This will have no impact on the rotation value of its children, but it will upda
    -
    -

    How much each particle should bounce on each axis. 1 = full bounce, 0 = no bounce.

    -
    - @@ -1199,7 +1295,7 @@ This will have no impact on the rotation value of its children, but it will upda - +

    How much each particle should bounce on each axis. 1 = full bounce, 0 = no bounce.

    @@ -1228,7 +1324,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -1340,7 +1436,7 @@ The cursor is set to the first child added to the Group and doesn't change unles
    Source:
    @@ -1448,7 +1544,7 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/
    Source:
    @@ -1556,7 +1652,7 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/
    Source:
    @@ -1580,10 +1676,6 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/
    -
    -

    Determines whether the emitter is being updated by the core game loop.

    -
    - @@ -1633,7 +1725,7 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/ - +

    Determines whether the emitter is being updated by the core game loop.

    @@ -1665,7 +1757,7 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/
    Source:
    @@ -1689,10 +1781,6 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/
    -
    -

    How often a particle is emitted in ms (if emitter is started with Explode === false).

    -
    - @@ -1742,7 +1830,7 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/ - +

    How often a particle is emitted in ms (if emitter is started with Explode === false).

    @@ -1774,7 +1862,7 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/
    Source:
    @@ -1881,7 +1969,7 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/
    Source:
    @@ -1905,10 +1993,6 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/
    -
    -

    Sets the <code>gravity.y</code> of each particle to this value on launch.

    -
    - @@ -1958,7 +2042,7 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/ - +

    Sets the body.gravity.y of each particle sprite to this value on launch.

    @@ -1984,13 +2068,120 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/
    Default Value:
    -
    • 2
    +
    • 100
    Source:
    + + + + + + + + + + + + + + + +
    +

    group

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    group + + +Phaser.Group + + + +

    The parent Group of this Group, if a child of another.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    @@ -2197,7 +2388,7 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/
    Source:
    @@ -2270,7 +2461,7 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/ -

    The number of children in this Group.

    +

    The total number of children in this Group, regardless of their exists/alive status.

    @@ -2304,7 +2495,7 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/
    Source:
    @@ -2328,11 +2519,6 @@ Emitter.emitX and Emitter.emitY control the emission location relative to the x/
    -
    -

    How long each particle lives once it is emitted in ms. Default is 2 seconds. -Set lifespan to 'zero' for particles to live forever.

    -
    - @@ -2382,7 +2568,7 @@ Set lifespan to 'zero' for particles to live forever.

    - +

    How long each particle lives once it is emitted in ms. Default is 2 seconds. Set lifespan to 'zero' for particles to live forever.

    @@ -2414,7 +2600,7 @@ Set lifespan to 'zero' for particles to live forever.

    Source:
    @@ -2438,10 +2624,6 @@ Set lifespan to 'zero' for particles to live forever.

    -
    -

    The total number of particles in this emitter.

    -
    - @@ -2520,7 +2702,7 @@ Set lifespan to 'zero' for particles to live forever.

    Source:
    @@ -2544,11 +2726,6 @@ Set lifespan to 'zero' for particles to live forever.

    -
    -

    The maximum possible scale of a particle. -The default value is 1.

    -
    - @@ -2598,7 +2775,7 @@ The default value is 1.

    - +

    The maximum possible scale of a particle.

    @@ -2630,7 +2807,7 @@ The default value is 1.

    Source:
    @@ -2654,11 +2831,6 @@ The default value is 1.

    -
    -

    The maximum possible velocity of a particle. -The default value is (100,100).

    -
    - @@ -2708,7 +2880,7 @@ The default value is (100,100).

    - +

    The maximum possible velocity of a particle.

    @@ -2737,7 +2909,7 @@ The default value is (100,100).

    Source:
    @@ -2761,10 +2933,6 @@ The default value is (100,100).

    -
    -

    The maximum possible angular velocity of a particle. The default value is 360.

    -
    - @@ -2814,7 +2982,7 @@ The default value is (100,100).

    - +

    The maximum possible angular velocity of a particle.

    @@ -2846,7 +3014,7 @@ The default value is (100,100).

    Source:
    @@ -2870,11 +3038,6 @@ The default value is (100,100).

    -
    -

    The minimum possible scale of a particle. -The default value is 1.

    -
    - @@ -2924,7 +3087,7 @@ The default value is 1.

    - +

    The minimum possible scale of a particle.

    @@ -2956,7 +3119,7 @@ The default value is 1.

    Source:
    @@ -2980,11 +3143,6 @@ The default value is 1.

    -
    -

    The minimum possible velocity of a particle. -The default value is (-100,-100).

    -
    - @@ -3034,7 +3192,7 @@ The default value is (-100,-100).

    - +

    The minimum possible velocity of a particle.

    @@ -3063,7 +3221,7 @@ The default value is (-100,-100).

    Source:
    @@ -3087,10 +3245,6 @@ The default value is (-100,-100).

    -
    -

    The minimum possible angular velocity of a particle. The default value is -360.

    -
    - @@ -3140,7 +3294,7 @@ The default value is (-100,-100).

    - +

    The minimum possible angular velocity of a particle.

    @@ -3169,7 +3323,7 @@ The default value is (-100,-100).

    Source:
    @@ -3271,7 +3425,7 @@ The default value is (-100,-100).

    Source:
    @@ -3295,11 +3449,6 @@ The default value is (-100,-100).

    -
    -

    Determines whether the emitter is currently emitting particles. -It is totally safe to directly toggle this.

    -
    - @@ -3349,7 +3498,7 @@ It is totally safe to directly toggle this.

    - +

    Determines whether the emitter is currently emitting particles. It is totally safe to directly toggle this.

    @@ -3381,7 +3530,7 @@ It is totally safe to directly toggle this.

    Source:
    @@ -3405,10 +3554,6 @@ It is totally safe to directly toggle this.

    -
    -

    Set your own particle class type here.

    -
    - @@ -3448,7 +3593,7 @@ It is totally safe to directly toggle this.

    -Description +any @@ -3458,7 +3603,7 @@ It is totally safe to directly toggle this.

    - +

    For emitting your own particle class types.

    @@ -3490,7 +3635,7 @@ It is totally safe to directly toggle this.

    Source:
    @@ -3508,16 +3653,12 @@ It is totally safe to directly toggle this.

    -

    particleDrag

    +

    particleFriction

    -
    -

    The X and Y drag component of particles launched from the emitter.

    -
    - @@ -3551,13 +3692,13 @@ It is totally safe to directly toggle this.

    - particleDrag + particleFriction -Phaser.Point +number @@ -3567,7 +3708,7 @@ It is totally safe to directly toggle this.

    - +

    The friction component of particles launched from the emitter.

    @@ -3592,11 +3733,121 @@ It is totally safe to directly toggle this.

    +
    Default Value:
    +
    • 0
    +
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    pivot

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    pivot + + +Phaser.Point + + + +

    The pivot point of the Group container.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    @@ -3698,7 +3949,7 @@ It is totally safe to directly toggle this.

    Source:
    @@ -3810,7 +4061,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -3883,7 +4134,7 @@ This will have no impact on the rotation value of its children, but it will upda -

    Replaces the PIXI.Point with a slightly more flexible one.

    +

    The scane of the Group container.

    @@ -3917,7 +4168,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -4019,7 +4270,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -4092,7 +4343,7 @@ This will have no impact on the rotation value of its children, but it will upda -

    The total number of children in this Group, regardless of their alive state.

    +

    The total number of children in this Group who have a state of exists = true.

    @@ -4126,7 +4377,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -4144,7 +4395,7 @@ This will have no impact on the rotation value of its children, but it will upda
    -

    type

    +

    <protected> type

    @@ -4189,7 +4440,7 @@ This will have no impact on the rotation value of its children, but it will upda -Description +number @@ -4199,7 +4450,7 @@ This will have no impact on the rotation value of its children, but it will upda -

    Description.

    +

    Internal Phaser Type value.

    @@ -4334,7 +4585,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -4541,7 +4792,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -4748,7 +4999,7 @@ This will have no impact on the rotation value of its children, but it will upda
    Source:
    @@ -4974,7 +5225,7 @@ that then see the addAt method.

    Source:
    @@ -5199,7 +5450,7 @@ Group.addAll('x', 10) will add 10 to the child.x value.

    Source:
    @@ -5346,7 +5597,7 @@ The child is added to the Group at the location specified by the index value, th
    Source:
    @@ -5405,7 +5656,7 @@ The child is added to the Group at the location specified by the index value, th
    -

    Change the emitter's midpoint to match the midpoint of a <code>Object</code>.

    +

    Change the emitters center to match the center of any object with a center property, such as a Sprite.

    @@ -5446,6 +5697,9 @@ The child is added to the Group at the location specified by the index value, th object +| + +Phaser.Sprite @@ -5455,7 +5709,7 @@ The child is added to the Group at the location specified by the index value, th -

    The <code>Object</code> that you want to sync up with.

    +

    The object that you wish to match the center with.

    @@ -5487,7 +5741,7 @@ The child is added to the Group at the location specified by the index value, th
    Source:
    @@ -5610,7 +5864,7 @@ The child is added to the Group at the location specified by the index value, th
    Source:
    @@ -5770,12 +6024,12 @@ After the method parameter and context you can add as many extra parameters as y - '' + null -

    A string containing the context under which the method will be executed. Leave to '' to default to the child.

    +

    A string containing the context under which the method will be executed. Set to null to default to the child.

    @@ -5849,7 +6103,7 @@ After the method parameter and context you can add as many extra parameters as y
    Source:
    @@ -6047,7 +6301,7 @@ After the existsValue parameter you can add as many parameters as you like, whic
    Source:
    @@ -6083,7 +6337,7 @@ After the existsValue parameter you can add as many parameters as you like, whic
    -

    Calls a function on all of the children that have exists=true in this Group.

    +

    Returns a reference to a function that exists on a child of the Group based on the given callback array.

    @@ -6216,7 +6470,81 @@ After the existsValue parameter you can add as many parameters as you like, whic
    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    childTest()

    + + +
    +
    + + +
    +

    Internal test.

    +
    + + + + + + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    @@ -6290,7 +6618,7 @@ After the existsValue parameter you can add as many parameters as you like, whic
    Source:
    @@ -6315,7 +6643,7 @@ After the existsValue parameter you can add as many parameters as you like, whic
    -

    The number of children flagged as dead. Returns -1 if Group is empty.

    +

    The number of children flagged as dead.

    @@ -6387,7 +6715,7 @@ After the existsValue parameter you can add as many parameters as you like, whic
    Source:
    @@ -6412,7 +6740,7 @@ After the existsValue parameter you can add as many parameters as you like, whic
    -

    The number of children flagged as alive. Returns -1 if Group is empty.

    +

    The number of children flagged as alive.

    @@ -6699,7 +7027,7 @@ Useful if you don't need to create the Sprite instances before-hand.

    Source:
    @@ -6977,7 +7305,7 @@ and will be positioned at 0, 0 (relative to the Group.x/y)

    Source:
    @@ -7005,7 +7333,7 @@ and will be positioned at 0, 0 (relative to the Group.x/y)

    -

    destroy()

    +

    destroy(destroyChildren)

    @@ -7022,6 +7350,75 @@ and will be positioned at 0, 0 (relative to the Group.x/y)

    +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    destroyChildren + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    Should every child of this Group have its destroy method called?

    + +
    @@ -7051,7 +7448,7 @@ and will be positioned at 0, 0 (relative to the Group.x/y)

    Source:
    @@ -7244,150 +7641,7 @@ Group.divideAll('x', 2) will half the child.x value.

    Source:
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    dump(full)

    - - -
    -
    - - -
    -

    Dumps out a list of Group children and their index positions to the browser console. Useful for group debugging.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeArgumentDefaultDescription
    full - - -boolean - - - - - - <optional>
    - - - - - -
    - - false - -

    If full the dump will include the entire display list, start from the Stage. Otherwise it will only include this container.

    - - - - -
    - - - - - - - -
    Inherited From:
    -
    - - - - - - - - - - - - - -
    Source:
    -
    @@ -7456,7 +7710,7 @@ Group.divideAll('x', 2) will half the child.x value.

    Source:
    @@ -7494,7 +7748,8 @@ Group.divideAll('x', 2) will half the child.x value.

    Allows you to call your own function on each member of this Group. You must pass the callback and context in which it will run. After the checkExists parameter you can add as many parameters as you like, which will all be passed to the callback along with the child. -For example: Group.forEach(awardBonusGold, this, true, 100, 500)

    +For example: Group.forEach(awardBonusGold, this, true, 100, 500) +Note: Currently this will skip any children which are Groups themselves.

    @@ -7627,7 +7882,7 @@ For example: Group.forEach(awardBonusGold, this, true, 100, 500)

    Source:
    @@ -7775,7 +8030,7 @@ For example: Group.forEachAlive(causeDamage, this, 500)

    Source:
    @@ -7923,7 +8178,7 @@ For example: Group.forEachAlive(causeDamage, this, 500)

    Source:
    @@ -8071,7 +8326,7 @@ For example: Group.forEachDead(bringToLife, this)

    Source:
    @@ -8194,7 +8449,7 @@ For example: Group.forEachDead(bringToLife, this)

    Source:
    @@ -8292,7 +8547,7 @@ This is handy for checking if everything has been wiped out, or choosing a squad
    Source:
    @@ -8390,7 +8645,7 @@ This is handy for checking if everything has been wiped out, or choosing a squad
    Source:
    @@ -8536,7 +8791,7 @@ This is handy for checking if everything has been wiped out, or choosing a squad
    Source:
    @@ -8682,7 +8937,7 @@ This is handy for checking if everything has been wiped out, or choosing a squad
    Source:
    @@ -8851,7 +9106,7 @@ This is handy for checking if everything has been wiped out, or choosing a squad
    Source:
    @@ -8902,7 +9157,7 @@ This is handy for checking if everything has been wiped out, or choosing a squad
    -

    iterate(key, value, returnType, callback, callbackContext)

    +

    iterate(key, value, returnType, callback, callbackContext) → {any}

    @@ -9161,7 +9416,7 @@ You can add as many callback parameters as you like, which will all be passed to
    Source:
    @@ -9182,6 +9437,29 @@ You can add as many callback parameters as you like, which will all be passed to +
    Returns:
    + + +
    +

    Returns either a numeric total (if RETURN_TOTAL was specified) or the child object.

    +
    + + + +
    +
    + Type +
    +
    + +any + + +
    +
    + + +
    @@ -9230,7 +9508,7 @@ You can add as many callback parameters as you like, which will all be passed to
    Source:
    @@ -9258,7 +9536,7 @@ You can add as many callback parameters as you like, which will all be passed to
    -

    makeParticles(keys, frames, quantity, collide, collideWorldBounds)

    +

    makeParticles(keys, frames, quantity, collide, collideWorldBounds) → {Phaser.Particles.Arcade.Emitter}

    @@ -9288,8 +9566,12 @@ You can add as many callback parameters as you like, which will all be passed to Type + Argument + + Default + Description @@ -9306,17 +9588,32 @@ You can add as many callback parameters as you like, which will all be passed to -Description +array +| + +string + + + + + + -

    Description.

    + + + + + + +

    A string or an array of strings that the particle sprites will use as their texture. If an array one is picked at random.

    @@ -9329,6 +9626,9 @@ You can add as many callback parameters as you like, which will all be passed to +array +| + number @@ -9336,10 +9636,22 @@ You can add as many callback parameters as you like, which will all be passed to + + + + + + -

    Description.

    + + + + + + +

    A frame number, or array of frames that the sprite will use. If an array one is picked at random.

    @@ -9359,10 +9671,22 @@ You can add as many callback parameters as you like, which will all be passed to + + + + + + -

    The number of particles to generate when using the "create from image" option.

    + + + + + + +

    The number of particles to generate.

    @@ -9375,17 +9699,33 @@ You can add as many callback parameters as you like, which will all be passed to -number +boolean + + + <optional>
    + + + + + -

    Description.

    + + + + false + + + + +

    Sets the checkCollision.none flag on the particle sprites body.

    @@ -9405,10 +9745,26 @@ You can add as many callback parameters as you like, which will all be passed to + + + <optional>
    + + + + + -

    Description.

    + + + + false + + + + +

    A particle can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World.

    @@ -9440,7 +9796,7 @@ You can add as many callback parameters as you like, which will all be passed to
    Source:
    @@ -9465,11 +9821,23 @@ You can add as many callback parameters as you like, which will all be passed to
    -

    This Emitter instance (nice for chaining stuff together, if you're into that).

    +

    This Emitter instance.

    +
    +
    + Type +
    +
    + +Phaser.Particles.Arcade.Emitter + + +
    +
    + @@ -9644,7 +10012,7 @@ Group.multiplyAll('x', 2) will x2 the child.x value.

    Source:
    @@ -9718,7 +10086,7 @@ Group.multiplyAll('x', 2) will x2 the child.x value.

    Source:
    @@ -9792,7 +10160,7 @@ Group.multiplyAll('x', 2) will x2 the child.x value.

    Source:
    @@ -9915,7 +10283,7 @@ Group.multiplyAll('x', 2) will x2 the child.x value.

    Source:
    @@ -10013,7 +10381,7 @@ The Group container remains on the display list.

    Source:
    @@ -10159,7 +10527,7 @@ The Group container remains on the display list.

    Source:
    @@ -10305,7 +10673,7 @@ The Group container remains on the display list.

    Source:
    @@ -10341,8 +10709,7 @@ The Group container remains on the display list.

    -

    Handy for bringing game objects "back to life". Just sets alive and exists back to true. -In practice, this is most often called by <code>Object.reset()</code>.

    +

    Handy for bringing game objects "back to life". Just sets alive and exists back to true.

    @@ -10375,7 +10742,334 @@ In practice, this is most often called by <code>Object.reset()</code>
    Source:
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    set(child, key, value, checkAlive, checkVisible, operation)

    + + +
    +
    + + +
    +

    This function allows you to quickly set a property on a single child of this Group to a new value. +The operation parameter controls how the new value is assigned to the property, from simple replacement to addition and multiplication.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    child + + +Phaser.Sprite + + + + + + + + + + + +

    The child to set the property on.

    key + + +string + + + + + + + + + + + +

    The property, as a string, to be set. For example: 'body.velocity.x'

    value + + +* + + + + + + + + + + + +

    The value that will be set.

    checkAlive + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    If set then the child will only be updated if alive=true.

    checkVisible + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    If set then the child will only be updated if visible=true.

    operation + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    Controls how the value is assigned. A value of 0 replaces the value with the new one. A value of 1 adds it, 2 subtracts it, 3 multiplies it and 4 divides it.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    @@ -10667,7 +11361,7 @@ The operation parameter controls how the new value is assigned to the property,
    Source:
    @@ -10915,7 +11609,7 @@ The operation parameter controls how the new value is assigned to the property,
    Source:
    @@ -10943,7 +11637,7 @@ The operation parameter controls how the new value is assigned to the property,
    -

    setRotation(min, max)

    +

    setRotation(min, max)

    @@ -10973,8 +11667,12 @@ The operation parameter controls how the new value is assigned to the property, Type + Argument + + Default + Description @@ -10998,7 +11696,23 @@ The operation parameter controls how the new value is assigned to the property, + + + <optional>
    + + + + + + + + + + + 0 + +

    The minimum value for this range.

    @@ -11021,7 +11735,23 @@ The operation parameter controls how the new value is assigned to the property, + + + <optional>
    + + + + + + + + + + + 0 + +

    The maximum value for this range.

    @@ -11056,7 +11786,7 @@ The operation parameter controls how the new value is assigned to the property,
    Source:
    @@ -11197,7 +11927,7 @@ The operation parameter controls how the new value is assigned to the property,
    Source:
    @@ -11225,7 +11955,7 @@ The operation parameter controls how the new value is assigned to the property,
    -

    setXSpeed(min, max)

    +

    setXSpeed(min, max)

    @@ -11255,8 +11985,12 @@ The operation parameter controls how the new value is assigned to the property, Type + Argument + + Default + Description @@ -11280,7 +12014,23 @@ The operation parameter controls how the new value is assigned to the property, + + + <optional>
    + + + + + + + + + + + 0 + +

    The minimum value for this range.

    @@ -11303,7 +12053,23 @@ The operation parameter controls how the new value is assigned to the property, + + + <optional>
    + + + + + + + + + + + 0 + +

    The maximum value for this range.

    @@ -11338,7 +12104,7 @@ The operation parameter controls how the new value is assigned to the property,
    Source:
    @@ -11366,7 +12132,7 @@ The operation parameter controls how the new value is assigned to the property,
    -

    setYSpeed(min, max)

    +

    setYSpeed(min, max)

    @@ -11396,8 +12162,12 @@ The operation parameter controls how the new value is assigned to the property, Type + Argument + + Default + Description @@ -11421,7 +12191,23 @@ The operation parameter controls how the new value is assigned to the property, + + + <optional>
    + + + + + + + + + + + 0 + +

    The minimum value for this range.

    @@ -11444,7 +12230,23 @@ The operation parameter controls how the new value is assigned to the property, + + + <optional>
    + + + + + + + + + + + 0 + +

    The maximum value for this range.

    @@ -11479,7 +12281,7 @@ The operation parameter controls how the new value is assigned to the property,
    Source:
    @@ -11662,7 +12464,7 @@ For example to depth sort Sprites for Zelda-style game you might call grou
    Source:
    @@ -11690,7 +12492,7 @@ For example to depth sort Sprites for Zelda-style game you might call grou
    -

    start(explode, lifespan, frequency, quantity)

    +

    start(explode, lifespan, frequency, quantity)

    @@ -11720,8 +12522,12 @@ For example to depth sort Sprites for Zelda-style game you might call grou Type + Argument + + Default + Description @@ -11745,7 +12551,23 @@ For example to depth sort Sprites for Zelda-style game you might call grou + + + <optional>
    + + + + + + + + + + + true + +

    Whether the particles should all burst out at once.

    @@ -11768,7 +12590,23 @@ For example to depth sort Sprites for Zelda-style game you might call grou + + + <optional>
    + + + + + + + + + + + 0 + +

    How long each particle lives once emitted. 0 = forever.

    @@ -11791,7 +12629,23 @@ For example to depth sort Sprites for Zelda-style game you might call grou + + + <optional>
    + + + + + + + + + + + 250 + +

    Ignored if Explode is set to true. Frequency is how often to emit a particle in ms.

    @@ -11814,7 +12668,23 @@ For example to depth sort Sprites for Zelda-style game you might call grou + + + <optional>
    + + + + + + + + + + + 0 + +

    How many particles to launch. 0 = "all of the particles".

    @@ -11849,7 +12719,7 @@ For example to depth sort Sprites for Zelda-style game you might call grou
    Source:
    @@ -12042,7 +12912,7 @@ Group.subAll('x', 10) will minus 10 from the child.x value.

    Source:
    @@ -12189,7 +13059,7 @@ You cannot swap a child with itself, or swap un-parented children, doing so will
    Source:
    @@ -12235,6 +13105,80 @@ You cannot swap a child with itself, or swap un-parented children, doing so will +
    + + + +
    +

    swapIndex()

    + + +
    +
    + + +
    +

    Internal test.

    +
    + + + + + + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + +
    @@ -12281,7 +13225,7 @@ You cannot swap a child with itself, or swap un-parented children, doing so will
    Source:
    @@ -12326,13 +13270,13 @@ You cannot swap a child with itself, or swap un-parented children, doing so will - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:31 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Particles.html b/docs/Phaser.Particles.html index aeae5dca..293c88e1 100644 --- a/docs/Phaser.Particles.html +++ b/docs/Phaser.Particles.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1232,13 +1226,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:31 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Physics.Arcade.Body.html b/docs/Phaser.Physics.Arcade.Body.html index 10e22248..fb9cd106 100644 --- a/docs/Phaser.Physics.Arcade.Body.html +++ b/docs/Phaser.Physics.Arcade.Body.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -446,8 +440,9 @@
    -

    The Physics Body is linked to a single Sprite. All physics operations should be performed against the body rather than -the Sprite itself. For example you can set the velocity, acceleration, bounce values etc all on the Body.

    +

    The Physics Body is linked to a single Sprite and defines properties that determine how the physics body is simulated. +These properties affect how the body reacts to forces, what forces it generates on itself (to simulate friction), and how it reacts to collisions in the scene. In most cases, the properties are used to simulate physical effects. +Each body also has its own property values that determine exactly how it reacts to forces and collisions in the scene.

    @@ -529,7 +524,7 @@ the Sprite itself. For example you can set the velocity, acceleration, bounce va
    Source:
    @@ -628,7 +623,7 @@ the Sprite itself. For example you can set the velocity, acceleration, bounce va -

    The velocity in pixels per second sq. of the Body.

    +

    The acceleration in pixels per second sq. of the Body.

    @@ -657,114 +652,7 @@ the Sprite itself. For example you can set the velocity, acceleration, bounce va
    Source:
    - - - - - - - - - - - - - - - -
    -

    allowCollision

    - - -
    -
    - -
    -

    Set the allowCollision properties to control which directions collision is processed for this Body. -For example allowCollision.up = false means it won't collide when the collision happened while moving up.

    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    allowCollision - - -object - - - -

    An object containing allowed collision.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -837,7 +725,7 @@ For example allowCollision.up = false means it won't collide when the collision -

    Allow this Body to be influenced by the global Gravity?

    +

    Allow this Body to be influenced by the global Gravity value? Note: It will always be influenced by the local gravity if set.

    @@ -869,7 +757,7 @@ For example allowCollision.up = false means it won't collide when the collision
    Source:
    @@ -942,7 +830,7 @@ For example allowCollision.up = false means it won't collide when the collision -

    Allow this Body to be rotated? (via angularVelocity, etc)

    +

    Allow angular rotation? This will cause the Sprite to be rotated via angularVelocity, etc.

    @@ -974,7 +862,109 @@ For example allowCollision.up = false means it won't collide when the collision
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    angle

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    angle + + +number + + + +

    The angle of the Body based on its velocity in radians.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1047,7 +1037,7 @@ For example allowCollision.up = false means it won't collide when the collision -

    The angular acceleration in pixels per second sq. of the Body.

    +

    The angular acceleration of the Body.

    @@ -1079,7 +1069,7 @@ For example allowCollision.up = false means it won't collide when the collision
    Source:
    @@ -1152,7 +1142,7 @@ For example allowCollision.up = false means it won't collide when the collision -

    The angular drag applied to the rotation of the Body.

    +

    angularDrag is used to calculate friction on the body as it rotates.

    @@ -1184,7 +1174,7 @@ For example allowCollision.up = false means it won't collide when the collision
    Source:
    @@ -1257,7 +1247,7 @@ For example allowCollision.up = false means it won't collide when the collision -

    The angular velocity in pixels per second sq. of the Body.

    +

    The angular velocity of the Body.

    @@ -1289,7 +1279,7 @@ For example allowCollision.up = false means it won't collide when the collision
    Source:
    @@ -1307,7 +1297,114 @@ For example allowCollision.up = false means it won't collide when the collision
    -

    bottom

    +

    blocked

    + + +
    +
    + +
    +

    This object is populated with boolean values when the Body collides with the World bounds or a Tile. +For example if blocked.up is true then the Body cannot move up.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    blocked + + +object + + + +

    An object containing on which faces this Body is blocked from moving, if any.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> bottom

    @@ -1362,7 +1459,7 @@ For example allowCollision.up = false means it won't collide when the collision -

    The bottom value of this Body (same as Body.y + Body.height)

    +

    The bottom-most point of this Body.

    @@ -1391,7 +1488,7 @@ For example allowCollision.up = false means it won't collide when the collision
    Source:
    @@ -1464,7 +1561,7 @@ For example allowCollision.up = false means it won't collide when the collision -

    The elasticitiy of the Body when colliding. bounce.x/y = 1 means full rebound, bounce.x/y = 0.5 means 50% rebound velocity.

    +

    The elasticitiy of the Body when colliding. This property determines how much energy a body maintains during a collision, i.e. its bounciness.

    @@ -1493,7 +1590,7 @@ For example allowCollision.up = false means it won't collide when the collision
    Source:
    @@ -1511,7 +1608,114 @@ For example allowCollision.up = false means it won't collide when the collision
    -

    center

    +

    checkCollision

    + + +
    +
    + +
    +

    Set the checkCollision properties to control which directions collision is processed for this Body. +For example checkCollision.up = false means it won't collide when the collision happened while moving up.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    checkCollision + + +object + + + +

    An object containing allowed collision.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    collideCallback

    @@ -1550,13 +1754,13 @@ For example allowCollision.up = false means it won't collide when the collision - center + collideCallback -Phaser.Point +function @@ -1566,7 +1770,7 @@ For example allowCollision.up = false means it won't collide when the collision -

    The center coordinate of the Physics Body.

    +

    If set this callback will be fired whenever this Body is hit (on any face). It will send three parameters, the face it hit on, this Body and the Body that hit it.

    @@ -1591,11 +1795,119 @@ For example allowCollision.up = false means it won't collide when the collision +
    Default Value:
    +
    • null
    +
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    collideCallbackContext

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    collideCallbackContext + + +object + + + +

    The context in which the collideCallback is called.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • null
    + + + +
    Source:
    +
    @@ -1701,7 +2013,7 @@ For example allowCollision.up = false means it won't collide when the collision
    Source:
    @@ -1719,17 +2031,12 @@ For example allowCollision.up = false means it won't collide when the collision
    -

    customSeparateX

    +

    <protected> contacts

    -
    -

    This flag allows you to disable the custom x separation that takes place by Physics.Arcade.separate. -Used in combination with your own collision processHandler you can create whatever type of collision response you need.

    -
    - @@ -1763,13 +2070,13 @@ Used in combination with your own collision processHandler you can create whatev - customSeparateX + contacts -boolean +array.<Phaser.Physics.Arcade.Body> @@ -1779,7 +2086,109 @@ Used in combination with your own collision processHandler you can create whatev -

    Use a custom separation system or the built-in one?

    +

    Used to store references to bodies this Body is in contact with.

    + + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + + + + + + + + + +
    +

    customSeparateCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -1805,13 +2214,13 @@ Used in combination with your own collision processHandler you can create whatev
    Default Value:
    -
    • false
    +
    • null
    Source:
    @@ -1829,17 +2238,12 @@ Used in combination with your own collision processHandler you can create whatev
    -

    customSeparateY

    +

    customSeparateContext

    -
    -

    This flag allows you to disable the custom y separation that takes place by Physics.Arcade.separate. -Used in combination with your own collision processHandler you can create whatever type of collision response you need.

    -
    - @@ -1873,13 +2277,13 @@ Used in combination with your own collision processHandler you can create whatev
    - + + @@ -1915,221 +2319,13 @@ Used in combination with your own collision processHandler you can create whatev
    Default Value:
    -
    • false
    +
    • null
    Source:
    - - - - - - - - - - - - - - - -
    -

    drag

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - -
    NameTypeDescription
    customSeparateCallback + + +function + + + +

    If set this callback will be used for Body separation instead of the built-in one. Callback should return true if separated, otherwise false.

    customSeparateYcustomSeparateContext -boolean +object @@ -1889,7 +2293,7 @@ Used in combination with your own collision processHandler you can create whatev -

    Use a custom separation system or the built-in one?

    The context in which the customSeparateCallback is called.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    drag - - -Phaser.Point - - - -

    The drag applied to the motion of the Body.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    embedded

    - - -
    -
    - -
    -

    If a body is overlapping with another body, but neither of them are moving (maybe they spawned on-top of each other?) this is set to true.

    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    embedded - - -boolean - - - -

    Body embed value.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -2231,7 +2427,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    @@ -2333,7 +2529,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    @@ -2406,7 +2602,7 @@ Used in combination with your own collision processHandler you can create whatev -

    A private Gravity setting for the Body.

    +

    The gravity applied to the motion of the Body. This works in addition to any gravity set on the world.

    @@ -2435,7 +2631,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    @@ -2453,7 +2649,7 @@ Used in combination with your own collision processHandler you can create whatev
    -

    halfHeight

    +

    <readonly> height

    @@ -2492,7 +2688,7 @@ Used in combination with your own collision processHandler you can create whatev - halfHeight + height @@ -2508,7 +2704,7 @@ Used in combination with your own collision processHandler you can create whatev -

    The calculated height / 2 of the physics body.

    +

    The current height of the Body, taking into account the point rotation.

    @@ -2537,410 +2733,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    - - - - - - - -
    - - - -
    - - - -
    -

    halfWidth

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    halfWidth - - -number - - - -

    The calculated width / 2 of the physics body.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    height

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    .numInternal - -

    ID cache

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    hullX

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    hullX - - -Phaser.Rectangle - - - -

    The dynamically calculated hull used during collision.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    hullY

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    hullY - - -Phaser.Rectangle - - - -

    The dynamically calculated hull used during collision.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -3013,7 +2806,7 @@ Used in combination with your own collision processHandler you can create whatev -

    An immovable Body will not receive any impacts from other bodies.

    +

    An immovable Body will not receive any impacts or exchanges of velocity from other bodies.

    @@ -3045,7 +2838,214 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> left

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    left + + +number + + + +

    The left-most point of this Body.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    linearDamping

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    linearDamping + + +number + + + +

    linearDamping is used to calculate friction on the body as it moves through the world. For example, this might be used to simulate air or water friction.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • 0.0
    + + + +
    Source:
    +
    @@ -3118,7 +3118,7 @@ Used in combination with your own collision processHandler you can create whatev -

    The mass of the Body.

    +

    The mass property determines how forces affect the body, as well as how much momentum the body has when it is involved in a collision.

    @@ -3150,7 +3150,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    @@ -3223,7 +3223,7 @@ Used in combination with your own collision processHandler you can create whatev -

    The maximum angular velocity in pixels per second sq. that the Body can reach.

    +

    The maximum angular velocity that the Body can reach.

    @@ -3255,7 +3255,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    @@ -3328,7 +3328,7 @@ Used in combination with your own collision processHandler you can create whatev -

    The maximum velocity in pixels per second sq. that the Body can reach.

    +

    The maximum velocity that the Body can reach.

    @@ -3357,7 +3357,109 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    minVelocity

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    minVelocity + + +Phaser.Point + + + +

    When a body rebounds off another body or a wall the minVelocity is checked. If the new velocity is lower than minVelocity the body is stopped.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -3430,7 +3532,7 @@ Used in combination with your own collision processHandler you can create whatev -

    Set to true to allow the Physics system to move this Body, other false to move it manually.

    +

    Set to true to allow the Physics system (such as velocity) to move this Body, or false to move it manually.

    @@ -3462,7 +3564,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    @@ -3564,7 +3666,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    @@ -3582,16 +3684,12 @@ Used in combination with your own collision processHandler you can create whatev
    -

    overlapX

    +

    <protected> overlapX

    -
    -

    When this body collides with another, the amount of overlap is stored here.

    -
    - @@ -3641,7 +3739,7 @@ Used in combination with your own collision processHandler you can create whatev -

    The amount of horizontal overlap during the collision.

    +

    Mostly used internally to store the overlap values from Tile seperation.

    @@ -3670,7 +3768,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    @@ -3688,16 +3786,12 @@ Used in combination with your own collision processHandler you can create whatev
    -

    overlapY

    +

    <protected> overlapY

    -
    -

    When this body collides with another, the amount of overlap is stored here.

    -
    - @@ -3747,7 +3841,7 @@ Used in combination with your own collision processHandler you can create whatev -

    The amount of vertical overlap during the collision.

    +

    Mostly used internally to store the overlap values from Tile seperation.

    @@ -3776,7 +3870,109 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    polygon

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    polygon + + +SAT.Polygon + + + +

    The SAT Polygons, as derived from the Shape.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -3878,7 +4074,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    @@ -3980,7 +4176,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    @@ -4082,7 +4278,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    @@ -4100,7 +4296,7 @@ Used in combination with your own collision processHandler you can create whatev
    -

    <protected> quadTreeIDs

    +

    rebound

    @@ -4139,13 +4335,13 @@ Used in combination with your own collision processHandler you can create whatev - quadTreeIDs + rebound -Array +boolean @@ -4155,7 +4351,7 @@ Used in combination with your own collision processHandler you can create whatev -

    Internal ID cache.

    +

    A Body set to rebound will exchange velocity with another Body during collision. Set to false to allow this body to be 'pushed' rather than exchange velocity.

    @@ -4180,11 +4376,14 @@ Used in combination with your own collision processHandler you can create whatev +
    Default Value:
    +
    • true
    +
    Source:
    @@ -4202,109 +4401,7 @@ Used in combination with your own collision processHandler you can create whatev
    -

    <protected> quadTreeIndex

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    quadTreeIndex - - -number - - - -

    Internal ID cache.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    - +
    @@ -4359,7 +4456,7 @@ Used in combination with your own collision processHandler you can create whatev -

    The right value of this Body (same as Body.x + Body.width)

    +

    The right-most point of this Body.

    @@ -4388,7 +4485,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    @@ -4461,7 +4558,7 @@ Used in combination with your own collision processHandler you can create whatev -

    The amount the Body is rotated.

    +

    The amount the parent Sprite is rotated.

    @@ -4493,7 +4590,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    @@ -4511,7 +4608,7 @@ Used in combination with your own collision processHandler you can create whatev
    -

    <readonly> screenX

    +

    shape

    @@ -4550,7 +4647,115 @@ Used in combination with your own collision processHandler you can create whatev - screenX + shape + + + + + +SAT.Box +| + +SAT.Circle +| + +SAT.Polygon + + + + + + + + + +

    The SAT Collision shape.

    + + + + + +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + + + + + + + + + +
    +

    speed

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4595,418 +4800,7 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    - - - - - - - - - - - - - - - -
    -

    <readonly> screenY

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - -
    NameTypeDescription
    speed @@ -4566,7 +4771,7 @@ Used in combination with your own collision processHandler you can create whatev -

    The x position of the physics body translated to screen space.

    The speed in pixels per second sq. of the Body.

    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    screenY - - -number - - - -

    The y position of the physics body translated to screen space.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    skipQuadTree

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    skipQuadTree - - -boolean - - - -

    If the Body is an irregular shape you can set this to true to avoid it being added to the World quad tree.

    -
    - - - - - - - - - - - - - - - - - - -
    Default Value:
    -
    • false
    - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    <readonly> sourceHeight

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    sourceHeight - - -number - - - -

    The un-scaled original size.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    <readonly> sourceWidth

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    sourceWidth - - -number - - - -

    The un-scaled original size.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -5108,7 +4902,109 @@ Used in combination with your own collision processHandler you can create whatev
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> top

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    top + + +number + + + +

    The top-most point of this Body.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -5215,7 +5111,112 @@ touching.up = true means the collision happened to the top of this Body for exam
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    type

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    type + + +Phaser.Physics.Arcade.RECT +| + +Phaser.Physics.Arcade.CIRCLE + + + +

    The type of SAT Shape.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -5288,7 +5289,7 @@ touching.up = true means the collision happened to the top of this Body for exam -

    The velocity in pixels per second sq. of the Body.

    +

    The velocity of the Body.

    @@ -5317,7 +5318,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    Source:
    @@ -5335,113 +5336,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    -

    wasTouching

    - - -
    -
    - -
    -

    This object is populated with previous touching values from the bodies previous collision.

    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    wasTouching - - -object - - - -

    An object containing previous touching results.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    width

    +

    <readonly> width

    @@ -5496,7 +5391,7 @@ touching.up = true means the collision happened to the top of this Body for exam -

    The calculated width of the physics body.

    +

    The current width of the Body, taking into account the point rotation.

    @@ -5525,7 +5420,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    Source:
    @@ -5543,7 +5438,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    -

    <readonly> x

    +

    x

    @@ -5598,7 +5493,7 @@ touching.up = true means the collision happened to the top of this Body for exam -

    The x position of the physics body.

    +

    The x coordinate of this Body.

    @@ -5627,7 +5522,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    Source:
    @@ -5645,7 +5540,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    -

    <readonly> y

    +

    y

    @@ -5700,7 +5595,7 @@ touching.up = true means the collision happened to the top of this Body for exam -

    The y position of the physics body.

    +

    The y coordinate of this Body.

    @@ -5729,7 +5624,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    Source:
    @@ -5753,7 +5648,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    -

    deltaAbsX() → {number}

    +

    <protected> add(v)

    @@ -5761,7 +5656,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    -

    Returns the absolute delta x value.

    +

    Adds the given Vector to this Body.

    @@ -5770,6 +5665,55 @@ touching.up = true means the collision happened to the top of this Body for exam +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    v + + +SAT.Vector + + + +

    The vector to add to this Body.

    + +
    @@ -5794,7 +5738,125 @@ touching.up = true means the collision happened to the top of this Body for exam
    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    addContact(body) → {boolean}

    + + +
    +
    + + +
    +

    Adds the given Body to the contact list of this Body. Also adds this Body to the contact list of the given Body.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body to be added.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -5819,7 +5881,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    -

    The absolute delta value.

    +

    True if the given Body was added to this contact list, false if already on it.

    @@ -5830,7 +5892,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    -number +boolean
    @@ -5845,7 +5907,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    -

    deltaAbsY() → {number}

    +

    <protected> applyDamping()

    @@ -5853,7 +5915,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    -

    Returns the absolute delta y value.

    +

    Internal method that checks the acceleration and applies damping if not set.

    @@ -5886,7 +5948,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    Source:
    @@ -5907,29 +5969,75 @@ touching.up = true means the collision happened to the top of this Body for exam -
    Returns:
    - -
    -

    The absolute delta value.

    -
    - - - -
    -
    - Type -
    -
    - -number - - -
    -
    - + +
    + +
    +

    <protected> checkBlocked()

    + + +
    +
    + + +
    +

    Internal method that checks and potentially resets the blocked status flags.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + +
    @@ -5945,7 +6053,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    -

    Returns the delta x value. The difference between Body.x now and in the previous step.

    +

    Returns the delta x value. The amount the Body has moved horizontally in the current step.

    @@ -5978,7 +6086,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    Source:
    @@ -6003,7 +6111,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    -

    The delta value.

    +

    The delta value. Positive if the motion was to the right, negative if to the left.

    @@ -6037,7 +6145,7 @@ touching.up = true means the collision happened to the top of this Body for exam
    -

    Returns the delta y value. The difference between Body.y now and in the previous step.

    +

    Returns the delta y value. The amount the Body has moved vertically in the current step.

    @@ -6070,7 +6178,99 @@ touching.up = true means the collision happened to the top of this Body for exam
    Source:
    + + + + + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The delta value. Positive if the motion was downwards, negative if upwards.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + + + + + +
    +

    deltaZ() → {number}

    + + +
    +
    + + +
    +

    Returns the delta z value. The amount the Body has rotated in the current step.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -6116,6 +6316,3776 @@ touching.up = true means the collision happened to the top of this Body for exam +
    + + + +
    +

    destroy()

    + + +
    +
    + + +
    +

    Destroys this Body and all references it holds to other objects.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> exchange(body)

    + + +
    +
    + + +
    +

    Exchange velocity with the given Body.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body that collided.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    getDownwardForce() → {number}

    + + +
    +
    + + +
    +

    Gets the total force being applied on the X axis, including gravity and velocity.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The total force being applied on the Y axis.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    getUpwardForce() → {number}

    + + +
    +
    + + +
    +

    Gets the total force being applied on the X axis, including gravity and velocity.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The total force being applied on the X axis.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    <protected> give(body, response)

    + + +
    +
    + + +
    +

    Separation response handler.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body that collided.

    response + + +SAT.Response + + + +

    The SAT Response object containing the collision data.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> hitBottom(body, response)

    + + +
    +
    + + +
    +

    Process a collision with the bottom face of this Body. +Collision and separation can be further checked by setting a collideCallback. +This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response. +If the callback returns true then separation, rebounds and the touching flags will all be set. +If it returns false this will be skipped and must be handled manually.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body that collided.

    response + + +SAT.Response + + + +

    The SAT Response object containing the collision data.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> hitLeft(body, response)

    + + +
    +
    + + +
    +

    Process a collision with the left face of this Body. +Collision and separation can be further checked by setting a collideCallback. +This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response. +If the callback returns true then separation, rebounds and the touching flags will all be set. +If it returns false this will be skipped and must be handled manually.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body that collided.

    response + + +SAT.Response + + + +

    The SAT Response object containing the collision data.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> hitRight(body, response)

    + + +
    +
    + + +
    +

    Process a collision with the right face of this Body. +Collision and separation can be further checked by setting a collideCallback. +This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response. +If the callback returns true then separation, rebounds and the touching flags will all be set. +If it returns false this will be skipped and must be handled manually.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body that collided.

    response + + +SAT.Response + + + +

    The SAT Response object containing the collision data.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> hitTop(body, response)

    + + +
    +
    + + +
    +

    Process a collision with the top face of this Body. +Collision and separation can be further checked by setting a collideCallback. +This callback will be sent 4 parameters: The face of collision, this Body, the colliding Body and the SAT Response. +If the callback returns true then separation, rebounds and the touching flags will all be set. +If it returns false this will be skipped and must be handled manually.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body that collided.

    response + + +SAT.Response + + + +

    The SAT Response object containing the collision data.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    inContact(body) → {boolean}

    + + +
    +
    + + +
    +

    Checks if this Body is already in contact with the given Body.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body to be checked.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the given Body is already in contact with this Body.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    <protected> integrateVelocity()

    + + +
    +
    + + +
    +

    Internal method. Integrates velocity, global gravity and the delta timer.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    onFloor() → {boolean}

    + + +
    +
    + + +
    +

    Determines if this Body is 'on the floor', which means in contact with a Tile or World bounds, or other object that has set 'down' as blocked.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if this Body is 'on the floor', which means in contact with a Tile or World bounds, or object that has set 'down' as blocked.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    onWall() → {boolean}

    + + +
    +
    + + +
    +

    Determins if this Body is 'on a wall', which means horizontally in contact with a Tile or World bounds, or other object but not the ground.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if this Body is 'on a wall', which means horizontally in contact with a Tile or World bounds, or other object but not the ground.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    overlap(body, response) → {boolean}

    + + +
    +
    + + +
    +

    Checks for an overlap between this Body and the given Body.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body that is being checked against this Body.

    response + + +SAT.Response + + + +

    SAT Response handler.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the two bodies overlap, otherwise false.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    <protected> postUpdate()

    + + +
    +
    + + +
    +

    Internal method. This is called directly before the sprites are sent to the renderer and after the update function has finished.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> preUpdate()

    + + +
    +
    + + +
    +

    Internal method that updates the Body position in relation to the parent Sprite.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> processRebound(body)

    + + +
    +
    + + +
    +

    Rebound the velocity of this Body.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body that collided.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> reboundCheck(x, y, rebound)

    + + +
    +
    + + +
    +

    Check if we're below minVelocity and gravity isn't trying to drag us in the opposite direction.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    x + + +boolean + + + +

    Check the X axis?

    y + + +boolean + + + +

    Check the Y axis?

    rebound + + +boolean + + + +

    If true it will reverse the velocity on the given axis

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    removeContact(body) → {boolean}

    + + +
    +
    + + +
    +

    Removes the given Body from the contact list of this Body. Also removes this Body from the contact list of the given Body.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body to be removed.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the given Body was removed from this contact list, false if wasn't on it.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    reset(full)

    + + +
    +
    + + +
    +

    Resets the Body motion values: velocity, acceleration, angularVelocity and angularAcceleration. +Also resets the forces to defaults: gravity, bounce, minVelocity,maxVelocity, angularDrag, maxAngular, mass, friction and checkCollision if 'full' specified.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    full + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    A full reset clears down settings you may have set, such as gravity, bounce and drag. A non-full reset just clears motion values.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> separate(body, response) → {boolean}

    + + +
    +
    + + +
    +

    This separates this Body from the given Body unless a customSeparateCallback is set. +It assumes they have already been overlap checked and the resulting overlap is stored in the SAT response.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body to be separated from this one.

    response + + +SAT.Response + + + +

    SAT Response handler.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the bodies were separated, false if not (for example checkCollide allows them to pass through)

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    setCircle(radius, offsetX, offsetY)

    + + +
    +
    + + +
    +

    Sets this Body to use a circle of the given radius for all collision. +The Circle will be centered on the center of the Sprite by default, but can be adjusted via the Body.offset property and the setCircle x/y parameters.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    radius + + +number + + + + + + + + + + + +

    The radius of this circle (in pixels)

    offsetX + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    The x amount the circle will be offset from the Sprites center.

    offsetY + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    The y amount the circle will be offset from the Sprites center.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    setPolygon(points)

    + + +
    +
    + + +
    +

    Sets this Body to use a convex polygon for collision. +The points are specified in a counter-clockwise direction and must create a convex polygon. +Use Body.translate and/or Body.offset to re-position the polygon from the Sprite origin.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    points + + +Array.<SAT.Vector> +| + +Array.<number> +| + +SAT.Vector +| + +number + + + +

    This can be an array of Vectors that form the polygon, + a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be + all the points of the polygon e.g. setPolygon(new SAT.Vector(), new SAT.Vector(), ...), or the + arguments passed can be flat x,y values e.g. setPolygon(x,y, x,y, x,y, ...) where x and y are Numbers.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    setRectangle(width, height, translateX, translateY)

    + + +
    +
    + + +
    +

    Sets this Body to use a rectangle for all collision. +If you don't specify any parameters it will be sized to match the parent Sprites current width and height (including scale factor) and centered on the sprite.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDescription
    width + + +number + + + + + + <optional>
    + + + + + +

    The width of the rectangle. If not specified it will default to the width of the parent Sprite.

    height + + +number + + + + + + <optional>
    + + + + + +

    The height of the rectangle. If not specified it will default to the height of the parent Sprite.

    translateX + + +number + + + + + + <optional>
    + + + + + +

    The x amount the rectangle will be translated from the Sprites center.

    translateY + + +number + + + + + + <optional>
    + + + + + +

    The y amount the rectangle will be translated from the Sprites center.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> split(body, response)

    + + +
    +
    + + +
    +

    Split the collision response evenly between the two bodies.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body that collided.

    response + + +SAT.Response + + + +

    The SAT Response object containing the collision data.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> sub(v)

    + + +
    +
    + + +
    +

    Subtracts the given Vector from this Body.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    v + + +SAT.Vector + + + +

    The vector to substract from this Body.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> take(body, response)

    + + +
    +
    + + +
    +

    Separation response handler.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +Phaser.Physics.Arcade.Body + + + +

    The Body that collided.

    response + + +SAT.Response + + + +

    The SAT Response object containing the collision data.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    translate(x, y)

    + + +
    +
    + + +
    +

    Used for translating rectangle and polygon bodies from the Sprite parent. Doesn't apply to Circles. +See also the Body.offset property.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    x + + +number + + + +

    The x amount the polygon or rectangle will be translated by from the Sprite.

    y + + +number + + + +

    The y amount the polygon or rectangle will be translated by from the Sprite.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> updateBounds()

    + + +
    +
    + + +
    +

    Internal method that updates the left, right, top, bottom, width and height properties.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> updateScale()

    + + +
    +
    + + +
    +

    Internal method that updates the Body scale in relation to the parent Sprite.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + +
    @@ -6138,13 +10108,13 @@ touching.up = true means the collision happened to the top of this Body for exam - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:32 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Physics.Arcade.html b/docs/Phaser.Physics.Arcade.html index 3b00f559..b048804c 100644 --- a/docs/Phaser.Physics.Arcade.html +++ b/docs/Phaser.Physics.Arcade.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -579,7 +573,7 @@
    -

    bounds

    +

    <static, constant> CIRCLE :number

    @@ -587,63 +581,21 @@ +
    Type:
    +
      +
    • + +number + + +
    • +
    +
    -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    bounds - - -Phaser.Rectangle - - - -

    The bounds inside of which the physics world exists. Defaults to match the world bounds.

    -
    - - - @@ -663,7 +615,127 @@
    Source:
    + + + + + + + +
    + + + + + + + +
    +

    <static, constant> POLYGON :number

    + + +
    +
    + + + +
    Type:
    +
      +
    • + +number + + +
    • +
    + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <static, constant> RECT :number

    + + +
    +
    + + + +
    Type:
    +
      +
    • + +number + + +
    • +
    + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -969,7 +1041,7 @@
    Source:
    @@ -1071,109 +1143,7 @@
    Source:
    - - - - - - - -
    - - - -
    - - - -
    -

    OVERLAP_BIAS

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    OVERLAP_BIAS - - -number - - - -

    A value added to the delta values during collision checks.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -1275,7 +1245,7 @@
    Source:
    @@ -1293,7 +1263,7 @@
    -

    quadTreeID

    +

    worldBottom

    @@ -1332,13 +1302,13 @@ - quadTreeID + worldBottom -number +SAT.Box @@ -1348,7 +1318,7 @@ -

    The QuadTree ID.

    +

    The bottom of the physics bounds.

    @@ -1377,7 +1347,415 @@
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    worldLeft

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    worldLeft + + +SAT.Box + + + +

    The left hand side of the physics bounds.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    worldPolys

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    worldPolys + + +array.<SAT.Polygon> + + + +

    An array of the polygon data from the physics bounds.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    worldRight

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    worldRight + + +SAT.Box + + + +

    The right hand side of the physics bounds.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    worldTop

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    worldTop + + +SAT.Box + + + +

    The top side of the physics bounds.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1662,7 +2040,7 @@ Note: The display object doesn't stop moving once it reaches the destination coo
    Source:
    @@ -1976,7 +2354,7 @@ Note: The display object doesn't stop moving once it reaches the destination coo
    Source:
    @@ -2323,7 +2701,7 @@ Note: The display object doesn't stop moving once it reaches the destination coo
    Source:
    @@ -2383,7 +2761,7 @@ Note: The display object doesn't stop moving once it reaches the destination coo

    Given the rotation (in radians) and speed calculate the acceleration and return it as a Point object, or set it to the given point object. -One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) which will set the values directly to the sprites velocity and not create a new Point object.

    +One way to use this is: accelerationFromRotation(rotation, 200, sprite.acceleration) which will set the values directly to the sprites acceleration and not create a new Point object.

    @@ -2560,7 +2938,7 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi
    Source:
    @@ -2726,7 +3104,7 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi
    Source:
    @@ -2910,7 +3288,7 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi
    Source:
    @@ -3097,7 +3475,7 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi
    Source:
    @@ -3148,7 +3526,7 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi
    -

    <protected> checkWorldBounds()

    +

    checkBounds(The) → {boolean}

    @@ -3156,7 +3534,7 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi
    -

    Internal method.

    +

    Checks the given Physics.Body against the Physics Bounds, if any are set, and separates them, setting the blocked flags on the Body as it does so.

    @@ -3165,6 +3543,55 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    The + + +Phaser.Physics.Arcade.Body + + + +

    Body object to be checked.

    + +
    @@ -3189,7 +3616,7 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi
    Source:
    @@ -3210,6 +3637,29 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi +
    Returns:
    + + +
    +

    True if the body hit the bounds, otherwise false.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + +
    @@ -3225,9 +3675,12 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi
    -

    Checks for collision between two game objects. The objects can be Sprites, Groups, Emitters or Tilemap Layers. -You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions. -The objects are also automatically separated.

    +

    Checks for collision between two game objects. You can perform Sprite vs. Sprite, Sprite vs. Group, Group vs. Group, Sprite vs. Tilemap Layer or Group vs. Tilemap Layer collisions. +The second parameter can be an array of objects, of differing types. +The objects are also automatically separated. If you don't require separation then use ArcadePhysics.overlap instead. +An optional processCallback can be provided. If given this function will be called when two sprites are found to be colliding. It is called before any separation takes place, +giving you the chance to perform additional checks. If the function returns true then the collision and separation is carried out. If it returns false it is skipped. +The collideCallback is an optional function that is only called if two sprites collide. If a processCallback has been set then it needs to return true for collideCallback to be called.

    @@ -3302,7 +3755,7 @@ The objects are also automatically separated.

    -

    The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap

    +

    The first object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter, or Phaser.Tilemap.

    @@ -3325,6 +3778,9 @@ The objects are also automatically separated.

    | Phaser.Tilemap +| + +array @@ -3346,7 +3802,7 @@ The objects are also automatically separated.

    -

    The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap

    +

    The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group, Phaser.Particles.Emitter or Phaser.Tilemap.

    @@ -3385,7 +3841,7 @@ The objects are also automatically separated.

    -

    An optional callback function that is called if the objects overlap. The two objects will be passed to this function in the same order in which you specified them.

    +

    An optional callback function that is called if the objects collide. The two objects will be passed to this function in the same order in which you specified them.

    @@ -3424,7 +3880,7 @@ The objects are also automatically separated.

    -

    A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collideCallback will only be called if processCallback returns true.

    +

    A callback function that lets you perform additional checks against the two objects if they overlap. If this is set then collision will only happen if processCallback returns true. The two objects will be passed to this function in the same order in which you specified them.

    @@ -3493,7 +3949,7 @@ The objects are also automatically separated.

    Source:
    @@ -3539,262 +3995,6 @@ The objects are also automatically separated.

    - - - - -
    -

    computeVelocity(axis, body, velocity, acceleration, drag, mMax) → {number}

    - - -
    -
    - - -
    -

    A tween-like function that takes a starting velocity and some other factors and returns an altered velocity.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    axis - - -number - - - -

    1 for horizontal, 2 for vertical.

    body - - -Phaser.Physics.Arcade.Body - - - -

    The Body object to be updated.

    velocity - - -number - - - -

    Any component of velocity (e.g. 20).

    acceleration - - -number - - - -

    Rate at which the velocity is changing.

    drag - - -number - - - -

    Really kind of a deceleration, this is how much the velocity changes if Acceleration is not set.

    mMax - - -number - - - -

    An absolute value cap for the velocity.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    The altered Velocity value.

    -
    - - - -
    -
    - Type -
    -
    - -number - - -
    -
    - - - - -
    @@ -3913,7 +4113,7 @@ The objects are also automatically separated.

    Source:
    @@ -4099,7 +4299,7 @@ If you need to calculate from the center of a display object instead use the met
    Source:
    @@ -4288,7 +4488,7 @@ If you need to calculate from the center of a display object instead use the met
    Source:
    @@ -4334,6 +4534,171 @@ If you need to calculate from the center of a display object instead use the met + + + + +
    +

    intersects(a, b) → {boolean}

    + + +
    +
    + + +
    +

    Performs a rect intersection test against the two objects. +Objects must expose properties: width, height, left, right, top, bottom.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    a + + +object + + + +

    The first object to test.

    b + + +object + + + +

    The second object to test.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    Returns true if the objects intersect, otherwise false.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + +
    @@ -4563,7 +4928,7 @@ Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set
    Source:
    @@ -4839,7 +5204,7 @@ Note: The display object doesn't stop moving once it reaches the destination coo
    Source:
    @@ -5149,7 +5514,7 @@ Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set
    Source:
    @@ -5210,7 +5575,8 @@ Note: Doesn't take into account acceleration, maxVelocity or drag (if you've set

    Checks for overlaps between two game objects. The objects can be Sprites, Groups or Emitters. You can perform Sprite vs. Sprite, Sprite vs. Group and Group vs. Group overlap checks. -Unlike collide the objects are NOT automatically separated or have any physics applied, they merely test for overlap results.

    +Unlike collide the objects are NOT automatically separated or have any physics applied, they merely test for overlap results. +The second parameter can be an array of objects, of differing types.

    @@ -5302,6 +5668,9 @@ Unlike collide the objects are NOT automatically separated or have any physics a | Phaser.Particles.Emitter +| + +array @@ -5323,7 +5692,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a -

    The second object to check. Can be an instance of Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.

    +

    The second object or array of objects to check. Can be Phaser.Sprite, Phaser.Group or Phaser.Particles.Emitter.

    @@ -5470,7 +5839,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    Source:
    @@ -5521,7 +5890,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    -

    <protected> postUpdate()

    +

    <protected> processTileSeparation(body1) → {boolean}

    @@ -5529,352 +5898,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    -

    Called automatically by the core game loop.

    -
    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - - - - - -
    -

    <protected> postUpdate()

    - - -
    -
    - - -
    -

    Internal method.

    -
    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    <protected> preUpdate()

    - - -
    -
    - - -
    -

    Called automatically by the core game loop.

    -
    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    <protected> preUpdate()

    - - -
    -
    - - -
    -

    Internal method.

    -
    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    reset()

    - - -
    -
    - - -
    -

    Resets all Body values (velocity, acceleration, rotation, etc)

    -
    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    separate(body1, body2) → {boolean}

    - - -
    -
    - - -
    -

    The core separation function to separate two physics bodies.

    +

    Internal function to process the separation of a physics body from a tile.

    @@ -5928,6 +5952,163 @@ Unlike collide the objects are NOT automatically separated or have any physics a + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    Returns true if separated, false if not.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    separate(body1, body2, processCallback, callbackContext) → {boolean}

    + + +
    +
    + + +
    +

    The core separation function to separate two physics bodies.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -5944,13 +6125,101 @@ Unlike collide the objects are NOT automatically separated or have any physics a + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    body1 + + +Phaser.Physics.Arcade.Body + + + + + + + + + + + +

    The Body object to separate.

    + + + + + + +

    The Body object to separate.

    processCallback + + +function + + + + + + <optional>
    + + + + + +
    + + null + +

    A callback function that lets you perform additional checks against the two objects if they overlap. If this function is set then the sprites will only be collided if it returns true.

    callbackContext + + +object + + + + + + <optional>
    + + + + + +
    + +

    The context in which to run the process callback.

    @@ -5979,7 +6248,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    Source:
    @@ -6004,7 +6273,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    -

    Returns true if the bodies were separated, otherwise false.

    +

    Returns true if the bodies collided, otherwise false.

    @@ -6030,7 +6299,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    -

    separateTile(body1, tile) → {boolean}

    +

    separateTile(body, tile) → {boolean}

    @@ -6072,7 +6341,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a - body1 + body @@ -6143,7 +6412,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    Source:
    @@ -6168,7 +6437,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    -

    Returns true if the bodies were separated, otherwise false.

    +

    Returns true if the body was separated, otherwise false.

    @@ -6194,7 +6463,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    -

    separateTileX(body1, tile) → {boolean}

    +

    separateTiles(body, tiles) → {boolean}

    @@ -6202,7 +6471,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    -

    The core separation function to separate a physics body and a tile on the x axis.

    +

    The core separation function to separate a physics body and an array of tiles.

    @@ -6236,7 +6505,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a - body1 + body @@ -6259,13 +6528,13 @@ Unlike collide the objects are NOT automatically separated or have any physics a - tile + tiles -Phaser.Tile +array.<Phaser.Tile> @@ -6275,7 +6544,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a -

    The tile to collide against.

    +

    The array of tiles to collide against.

    @@ -6307,7 +6576,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    Source:
    @@ -6332,7 +6601,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    -

    Returns true if the bodies were separated, otherwise false.

    +

    Returns true if the body was separated, otherwise false.

    @@ -6358,7 +6627,7 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    -

    separateTileY(body1, tile) → {boolean}

    +

    setBounds(x, y, width, height, left, right, top, bottom)

    @@ -6366,7 +6635,8 @@ Unlike collide the objects are NOT automatically separated or have any physics a
    -

    The core separation function to separate a physics body and a tile on the x axis.

    +

    Sets the bounds of the Physics world to match the given world pixel dimensions. +You can optionally set which 'walls' to create: left, right, top or bottom.

    @@ -6388,8 +6658,12 @@ Unlike collide the objects are NOT automatically separated or have any physics a Type + Argument + + Default + Description @@ -6400,497 +6674,73 @@ Unlike collide the objects are NOT automatically separated or have any physics a - body1 + x -Phaser.Physics.Arcade.Body +number + + + + + + -

    The Body object to separate.

    + + + + + + +

    The x coordinate of the top-left corner of the bounds.

    - tile + y -Phaser.Tile +number - - - -

    The tile to collide against.

    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    Returns true if the bodies were separated, otherwise false.

    -
    - - - -
    -
    - Type -
    -
    - -boolean - - -
    -
    - - - - - - - - - -
    -

    separateX(body1, body2) → {boolean}

    - - -
    -
    - - -
    -

    The core separation function to separate two physics bodies on the x axis.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    body1 - + -Phaser.Physics.Arcade.Body - - -

    The Body object to separate.

    body2 - -Phaser.Physics.Arcade.Body - - -

    The Body object to separate.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    Returns true if the bodies were separated, otherwise false.

    -
    - - - -
    -
    - Type -
    -
    - -boolean - - -
    -
    - - - - - -
    - - - -
    -

    separateY(body1, body2) → {boolean}

    - - -
    -
    - - -
    -

    The core separation function to separate two physics bodies on the y axis.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + - - - - - - - - - - - - - + - - - + - -
    NameTypeDescription
    body1 - -Phaser.Physics.Arcade.Body - - - -

    The Body object to separate.

    body2 - + -Phaser.Physics.Arcade.Body - - - -

    The Body object to separate.

    The y coordinate of the top-left corner of the bounds.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    Returns true if the bodies were separated, otherwise false.

    -
    - - - -
    -
    - Type -
    -
    - -boolean - - -
    -
    - - - - - -
    - - - -
    -

    setSize(width, height, offsetX, offsetY)

    - - -
    -
    - - -
    -

    You can modify the size of the physics Body to be any dimension you need. -So it could be smaller or larger than the parent Sprite. You can also control the x and y offset, which -is the position of the Body relative to the top-left of the Sprite.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - @@ -6907,10 +6757,22 @@ is the position of the Body relative to the top-left of the Sprite.

    + - + + + + + @@ -6930,56 +6792,178 @@ is the position of the Body relative to the top-left of the Sprite.

    + - + + + + + - + + - + + + + + - + + - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -7011,7 +6995,7 @@ is the position of the Body relative to the top-left of the Sprite.

    Source:
    @@ -7039,7 +7023,7 @@ is the position of the Body relative to the top-left of the Sprite.

    -

    <protected> updateBounds()

    +

    setBoundsToWorld(left, right, top, bottom)

    @@ -7047,7 +7031,8 @@ is the position of the Body relative to the top-left of the Sprite.

    -

    Internal method.

    +

    Sets the bounds of the Physics world to match the Game.World. +You can optionally set which 'walls' to create: left, right, top or bottom.

    @@ -7056,6 +7041,192 @@ is the position of the Body relative to the top-left of the Sprite.

    +
    Parameters:
    + + +
    NameTypeDescription
    + + + + +

    The width of the Body.

    + +

    The width of the bounds.

    + + + + +

    The height of the Body.

    + +

    The height of the bounds.

    offsetXleft -number +boolean + + <optional>
    + + + + +

    The X offset of the Body from the Sprite position.

    + + true + +

    If true will create the left bounds wall.

    offsetYright -number +boolean + + <optional>
    + + + + +

    The Y offset of the Body from the Sprite position.

    + + true + +

    If true will create the right bounds wall.

    top + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true will create the top bounds wall.

    bottom + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true will create the bottom bounds wall.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    left + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true will create the left bounds wall.

    right + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true will create the right bounds wall.

    top + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true will create the top bounds wall.

    bottom + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true will create the bottom bounds wall.

    + +
    @@ -7080,7 +7251,7 @@ is the position of the Body relative to the top-left of the Sprite.

    Source:
    @@ -7108,7 +7279,7 @@ is the position of the Body relative to the top-left of the Sprite.

    -

    <protected> updateHulls()

    +

    tileIntersects(body, tile) → {boolean}

    @@ -7116,7 +7287,8 @@ is the position of the Body relative to the top-left of the Sprite.

    -

    Internal method.

    +

    Performs a rect intersection test against the two objects. +Objects must expose properties: width, height, left, right, top, bottom.

    @@ -7125,6 +7297,78 @@ is the position of the Body relative to the top-left of the Sprite.

    +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    body + + +object + + + +

    The Body to test.

    tile + + +object + + + +

    The Tile to test.

    + +
    @@ -7149,7 +7393,7 @@ is the position of the Body relative to the top-left of the Sprite.

    Source:
    @@ -7170,6 +7414,29 @@ is the position of the Body relative to the top-left of the Sprite.

    +
    Returns:
    + + +
    +

    Returns true if the objects intersect, otherwise false.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + +
    @@ -7267,7 +7534,7 @@ is the position of the Body relative to the top-left of the Sprite.

    Source:
    @@ -7481,7 +7748,7 @@ One way to use this is: velocityFromAngle(angle, 200, sprite.velocity) which wil
    Source:
    @@ -7720,7 +7987,7 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi
    Source:
    @@ -7790,13 +8057,13 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:32 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Physics.html b/docs/Phaser.Physics.html index d52ac8e5..9379c4c4 100644 --- a/docs/Phaser.Physics.html +++ b/docs/Phaser.Physics.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -539,13 +533,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:31 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Plugin.html b/docs/Phaser.Plugin.html index eda6097c..4816bc54 100644 --- a/docs/Phaser.Plugin.html +++ b/docs/Phaser.Plugin.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1906,13 +1900,13 @@ It is only called if active is set to true.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:32 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.PluginManager.html b/docs/Phaser.PluginManager.html index 70d82f0c..8e608895 100644 --- a/docs/Phaser.PluginManager.html +++ b/docs/Phaser.PluginManager.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1571,13 +1565,13 @@ It only calls plugins who have active=true.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:32 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Point.html b/docs/Phaser.Point.html index eac2ec37..3290f887 100644 --- a/docs/Phaser.Point.html +++ b/docs/Phaser.Point.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -969,7 +963,7 @@
    Source:
    @@ -1184,7 +1178,7 @@
    Source:
    @@ -1399,7 +1393,7 @@
    Source:
    @@ -1563,7 +1557,7 @@
    Source:
    @@ -1778,7 +1772,7 @@
    Source:
    @@ -2034,7 +2028,7 @@
    Source:
    @@ -2249,7 +2243,7 @@
    Source:
    @@ -5267,13 +5261,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:32 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Pointer.html b/docs/Phaser.Pointer.html index b83546a3..260e519c 100644 --- a/docs/Phaser.Pointer.html +++ b/docs/Phaser.Pointer.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1099,7 +1093,7 @@ The Circle size is 44px (Apples recommended "finger tip" size).

    Source:
    @@ -3065,7 +3059,7 @@ The Circle size is 44px (Apples recommended "finger tip" size).

    Source:
    @@ -3171,7 +3165,7 @@ The Circle size is 44px (Apples recommended "finger tip" size).

    Source:
    @@ -3503,7 +3497,7 @@ If you wish to check if the Pointer was pressed down just once then see the Spri
    Source:
    @@ -3658,7 +3652,7 @@ If you wish to check if the Pointer was released just once then see the Sprite.e
    Source:
    @@ -3805,7 +3799,7 @@ If you wish to check if the Pointer was released just once then see the Sprite.e
    Source:
    @@ -3998,7 +3992,7 @@ If you wish to check if the Pointer was released just once then see the Sprite.e
    Source:
    @@ -4240,7 +4234,7 @@ If you wish to check if the Pointer was released just once then see the Sprite.e
    Source:
    @@ -4276,7 +4270,7 @@ If you wish to check if the Pointer was released just once then see the Sprite.e
    -

    Called internall by the Input Manager.

    +

    Called by the Input Manager.

    @@ -4354,13 +4348,13 @@ If you wish to check if the Pointer was released just once then see the Sprite.e - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:32 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Polygon.html b/docs/Phaser.Polygon.html index e2f43bb0..026558c8 100644 --- a/docs/Phaser.Polygon.html +++ b/docs/Phaser.Polygon.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -489,10 +483,10 @@ arguments passed can be flat x,y values e.g. new PIXI.Polygon(x,y, x,y, x, -Array.<Phaser.Point> +Array.<Phaser.Point> | -Array.<number> +Array.<number> @@ -699,13 +693,13 @@ arguments passed can be flat x,y values e.g. new PIXI.Polygon(x,y, x,y, x, - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:32 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.QuadTree.html b/docs/Phaser.QuadTree.html index b53274fc..83f23cd6 100644 --- a/docs/Phaser.QuadTree.html +++ b/docs/Phaser.QuadTree.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -427,8 +421,9 @@ QuadTree -

    A QuadTree implementation. The original code was a conversion of the Java code posted to GameDevTuts. However I've tweaked -it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result. Original version at https://github.com/timohausmann/quadtree-js/

    +

    A QuadTree implementation. The original code was a conversion of the Java code posted to GameDevTuts. +However I've tweaked it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result. +Original version at https://github.com/timohausmann/quadtree-js/

    @@ -439,7 +434,7 @@ it massively to add node indexing, removed lots of temp. var creation and signif
    -

    new QuadTree(physicsManager, x, y, width, height, maxObjects, maxLevels, level)

    +

    new QuadTree(x, y, width, height, maxObjects, maxLevels, level)

    @@ -469,8 +464,12 @@ it massively to add node indexing, removed lots of temp. var creation and signif Type + Argument + + Default + Description @@ -479,29 +478,6 @@ it massively to add node indexing, removed lots of temp. var creation and signif - - - physicsManager - - - - - -Description - - - - - - - - - -

    Description.

    - - - - x @@ -510,17 +486,29 @@ it massively to add node indexing, removed lots of temp. var creation and signif -Description +number + + + + + + -

    Description.

    + + + + + + +

    The top left coordinate of the quadtree.

    @@ -533,17 +521,29 @@ it massively to add node indexing, removed lots of temp. var creation and signif -Description +number + + + + + + -

    Description.

    + + + + + + +

    The top left coordinate of the quadtree.

    @@ -563,10 +563,22 @@ it massively to add node indexing, removed lots of temp. var creation and signif + + + + + + -

    The width of your game in game pixels.

    + + + + + + +

    The width of the quadtree in pixels.

    @@ -586,10 +598,22 @@ it massively to add node indexing, removed lots of temp. var creation and signif + + + + + + -

    The height of your game in game pixels.

    + + + + + + +

    The height of the quadtree in pixels.

    @@ -609,10 +633,26 @@ it massively to add node indexing, removed lots of temp. var creation and signif + + + <optional>
    + + + + + -

    Description.

    + + + + 10 + + + + +

    The maximum number of objects per node.

    @@ -632,10 +672,26 @@ it massively to add node indexing, removed lots of temp. var creation and signif + + + <optional>
    + + + + + -

    Description.

    + + + + 4 + + + + +

    The maximum number of levels to iterate to.

    @@ -655,10 +711,26 @@ it massively to add node indexing, removed lots of temp. var creation and signif + + + <optional>
    + + + + + -

    Description.

    + + + + 0 + + + + +

    Which level is this?

    @@ -778,7 +850,7 @@ Clear the quadtree.

    Source:
    @@ -855,6 +927,9 @@ Determine which node the object belongs to.

    +Phaser.Rectangle +| + object @@ -865,7 +940,7 @@ Determine which node the object belongs to.

    -

    Description.

    +

    The bounds in which to check.

    @@ -897,7 +972,7 @@ Determine which node the object belongs to.

    Source:
    @@ -957,9 +1032,7 @@ Determine which node the object belongs to.

    /* -Insert the object into the node. If the node -exceeds the capacity, it will split and add all -objects to their corresponding subnodes.

    +Insert the object into the node. If the node exceeds the capacity, it will split and add all objects to their corresponding subnodes.

    @@ -999,6 +1072,9 @@ objects to their corresponding subnodes.

    +Phaser.Physics.Arcade.Body +| + object @@ -1009,7 +1085,7 @@ objects to their corresponding subnodes.

    -

    Description.

    +

    The Body object to insert into the quadtree.

    @@ -1041,7 +1117,7 @@ objects to their corresponding subnodes.

    Source:
    @@ -1069,7 +1145,7 @@ objects to their corresponding subnodes.

    -

    retrieve(rect) → {array}

    +

    populate(group)

    @@ -1078,7 +1154,7 @@ objects to their corresponding subnodes.

    /* -Return all objects that could collide with the given object.

    +Populates this quadtree with the members of the given Group.

    @@ -1112,13 +1188,13 @@ Return all objects that could collide with the given object.

    - rect + group -object +Phaser.Group @@ -1128,7 +1204,7 @@ Return all objects that could collide with the given object.

    -

    Description.

    +

    The Group to add to the quadtree.

    @@ -1160,7 +1236,245 @@ Return all objects that could collide with the given object.

    Source:
    + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    +

    populateHandler(sprite)

    + + +
    +
    + + +
    +

    /* +Handler for the populate method.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    sprite + + +Phaser.Sprite + + + +

    The Sprite to check.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    retrieve(sprite) → {array}

    + + +
    +
    + + +
    +

    /* +Return all objects that could collide with the given Sprite.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    sprite + + +Phaser.Sprite + + + +

    The sprite to check against.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1255,7 +1569,7 @@ Split the node into 4 subnodes

    Source:
    @@ -1300,13 +1614,13 @@ Split the node into 4 subnodes

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:32 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.RandomDataGenerator.html b/docs/Phaser.RandomDataGenerator.html index 3671e6c9..6e2c5b66 100644 --- a/docs/Phaser.RandomDataGenerator.html +++ b/docs/Phaser.RandomDataGenerator.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1156,7 +1150,7 @@ Random number generator from -Array +Array @@ -1927,7 +1921,7 @@ Random number generator from -Array +Array @@ -2037,13 +2031,13 @@ Random number generator from - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by
    JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:33 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Rectangle.html b/docs/Phaser.Rectangle.html index 7dba884f..0472e0e8 100644 --- a/docs/Phaser.Rectangle.html +++ b/docs/Phaser.Rectangle.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -752,7 +746,7 @@
    Source:
    @@ -858,7 +852,7 @@
    Source:
    @@ -964,7 +958,7 @@
    Source:
    @@ -1070,7 +1064,7 @@
    Source:
    @@ -1177,7 +1171,7 @@ If set to true then all of the Rectangle properties are set to 0.

    Source:
    @@ -1279,7 +1273,7 @@ If set to true then all of the Rectangle properties are set to 0.

    Source:
    @@ -1381,7 +1375,7 @@ If set to true then all of the Rectangle properties are set to 0.

    Source:
    @@ -1589,7 +1583,7 @@ If set to true then all of the Rectangle properties are set to 0.

    Source:
    @@ -1695,7 +1689,7 @@ If set to true then all of the Rectangle properties are set to 0.

    Source:
    @@ -1801,7 +1795,7 @@ If set to true then all of the Rectangle properties are set to 0.

    Source:
    @@ -1908,7 +1902,7 @@ However it does affect the height property, whereas changing the y value does no
    Source:
    @@ -2014,7 +2008,7 @@ However it does affect the height property, whereas changing the y value does no
    Source:
    @@ -2120,7 +2114,7 @@ However it does affect the height property, whereas changing the y value does no
    Source:
    @@ -2583,7 +2577,7 @@ However it does affect the height property, whereas changing the y value does no
    Source:
    @@ -2766,7 +2760,7 @@ However it does affect the height property, whereas changing the y value does no
    Source:
    @@ -2930,7 +2924,7 @@ However it does affect the height property, whereas changing the y value does no
    Source:
    @@ -3095,7 +3089,7 @@ A Rectangle object is said to contain another if the second Rectangle object fal
    Source:
    @@ -3260,7 +3254,7 @@ This method compares the x, y, width and height properties of each Rectangle.

    Source:
    @@ -3447,7 +3441,7 @@ This method compares the x, y, width and height properties of each Rectangle.

    Source:
    @@ -3611,7 +3605,7 @@ This method compares the x, y, width and height properties of each Rectangle.

    Source:
    @@ -3826,7 +3820,7 @@ This method compares the x, y, width and height properties of each Rectangle.

    Source:
    @@ -3991,7 +3985,7 @@ This method checks the x, y, width, and height properties of the Rectangles.

    Source:
    @@ -4224,7 +4218,7 @@ This method checks the x, y, width, and height properties of the Rectangles.

    Source:
    @@ -4408,7 +4402,7 @@ This method checks the x, y, width, and height properties of the Rectangles.

    Source:
    @@ -4623,7 +4617,7 @@ This method checks the x, y, width, and height properties of the Rectangles.

    Source:
    @@ -7378,13 +7372,13 @@ This method checks the x, y, width, and height properties of the Rectangles.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:33 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.RenderTexture.html b/docs/Phaser.RenderTexture.html index 223d59e0..d3854fb4 100644 --- a/docs/Phaser.RenderTexture.html +++ b/docs/Phaser.RenderTexture.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1356,6 +1350,612 @@ +

    Methods

    + +
    + +
    +

    render(displayObject, position, clear, renderHidden)

    + + +
    +
    + + +
    +

    This function will draw the display object to the texture. If the display object is a Group or has children it will +draw all children as well.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    displayObject + + +DisplayObject + + + + + + + + + + + +

    The display object to render this texture on.

    position + + +Phaser.Point + + + + + + <optional>
    + + + + + +
    + +

    Where to draw the display object.

    clear + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    If true the texture will be cleared before the displayObject is drawn.

    renderHidden + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    If true displayObjects that have their visible property set to false will still be rendered.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    renderXY(displayObject, x, y, clear, renderHidden)

    + + +
    +
    + + +
    +

    This function will draw the display object to the texture at the given x/y coordinates. +If the display object is a Group or has children it will draw all children as well.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    displayObject + + +DisplayObject + + + + + + + + + + + +

    The display object to render this texture on.

    x + + +number + + + + + + + + + + + +

    The x coordinate to draw the display object at.

    y + + +number + + + + + + + + + + + +

    The y coordinate to draw the display object at.

    clear + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    If true the texture will be cleared before the displayObject is drawn.

    renderHidden + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    If true displayObjects that have their visible property set to false will still be rendered.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    resize()

    + + +
    +
    + + +
    +

    Resizes the RenderTexture.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + +
    + @@ -1374,13 +1974,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:33 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.RequestAnimationFrame.html b/docs/Phaser.RequestAnimationFrame.html index d22978ad..724525ad 100644 --- a/docs/Phaser.RequestAnimationFrame.html +++ b/docs/Phaser.RequestAnimationFrame.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -969,7 +963,7 @@
    -

    Starts the requestAnimatioFrame running or setTimeout if unavailable in browser

    +

    Starts the requestAnimationFrame running or setTimeout if unavailable in browser

    @@ -1303,13 +1297,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:33 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Signal.html b/docs/Phaser.Signal.html index 795afa0f..176d68b9 100644 --- a/docs/Phaser.Signal.html +++ b/docs/Phaser.Signal.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -2288,13 +2282,13 @@ IMPORTANT: should be called only during signal dispatch, calling it before/after - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:33 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.SinglePad.html b/docs/Phaser.SinglePad.html new file mode 100644 index 00000000..5452d373 --- /dev/null +++ b/docs/Phaser.SinglePad.html @@ -0,0 +1,3822 @@ + + + + + + Phaser Class: SinglePad + + + + + + + + + + +
    + + +
    + + +
    + +
    + + + +

    Class: SinglePad

    +
    + +
    +

    + Phaser. + + SinglePad +

    + +

    A single Phaser Gamepad

    + +
    + +
    +
    + + + + +
    +

    new SinglePad(game, padParent)

    + + +
    +
    + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    game + + +Phaser.Game + + + +

    Current game instance.

    padParent + + +Object + + + +

    The parent Phaser.Gamepad object (all gamepads reside under this)

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + +
    + + + + + + + + + + + + +

    Members

    + +
    + +
    +

    _index

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    index + + +number + + + +

    The gamepad index as per browsers data

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • null
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    _padParent

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    padParent + + +Phaser.Gamepad + + + +

    Main Phaser Gamepad object

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    callbackContext

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    callbackContext + + +Object + + + +

    The context under which the callbacks are run.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> connected

    + + +
    +
    + +
    +

    Whether or not this particular gamepad is connected or not.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    connected + + +boolean + + + +

    Whether or not this particular gamepad is connected or not.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    deadZone

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    deadZone + + +number + + + +

    Dead zone for axis feedback - within this value you won't trigger updates.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    game

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    game + + +Phaser.Game + + + +

    Local reference to game.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> index

    + + +
    +
    + +
    +

    Gamepad index as per browser data

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    index + + +number + + + +

    The gamepad index, used to identify specific gamepads in the browser

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onAxisCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onAxisCallback + + +function + + + +

    This callback is invoked every time an axis is changed.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onConnectCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onConnectCallback + + +function + + + +

    This callback is invoked every time this gamepad is connected

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onDisconnectCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onDisconnectCallback + + +function + + + +

    This callback is invoked every time this gamepad is disconnected

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onDownCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onDownCallback + + +function + + + +

    This callback is invoked every time a button is pressed down.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onFloatCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onFloatCallback + + +function + + + +

    This callback is invoked every time a button is changed to a value where value > 0 and value < 1.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onUpCallback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onUpCallback + + +function + + + +

    This callback is invoked every time a gamepad button is released.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + +
    + + + +

    Methods

    + +
    + +
    +

    addButton(buttonCode) → {Phaser.GamepadButton}

    + + +
    +
    + + +
    +

    If you need more fine-grained control over a Key you can create a new Phaser.Key object via this method. +The Key object can then be polled, have events attached to it, etc.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    buttonCode + + +number + + + +

    The buttonCode of the button, i.e. Phaser.Gamepad.BUTTON_0 or Phaser.Gamepad.BUTTON_1

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The GamepadButton object which you can store locally and reference directly.

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.GamepadButton + + +
    +
    + + + + + +
    + + + +
    +

    buttonValue(buttonCode) → {boolean}

    + + +
    +
    + + +
    +

    Returns the value of a gamepad button. Intended mainly for cases when you have floating button values, for example +analog trigger buttons on the XBOX 360 controller

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    buttonCode + + +number + + + +

    The buttonCode of the button to check.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    Button value if available otherwise false.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    connect(rawPad)

    + + +
    +
    + + +
    +

    Gamepad connect function, should be called by Phaser.Gamepad

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    rawPad + + +Object + + + +

    The raw gamepad object

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    disconnect()

    + + +
    +
    + + +
    +

    Gamepad disconnect function, should be called by Phaser.Gamepad

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    isDown(axisCode) → {number}

    + + +
    +
    + + +
    +

    Returns value of requested axis

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    axisCode + + +number + + + +

    The index of the axis to check

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    Axis value if available otherwise false

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    isDown(buttonCode) → {boolean}

    + + +
    +
    + + +
    +

    Returns true if the button is currently pressed down.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    buttonCode + + +number + + + +

    The buttonCode of the key to check.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the key is currently down.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    justPressed(buttonCode, duration) → {boolean}

    + + +
    +
    + + +
    +

    Returns the "just released" state of a button from this gamepad. Just released is considered as being true if the button was released within the duration given (default 250ms).

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    buttonCode + + +number + + + + + + + + + + + +

    The buttonCode of the button to check for.

    duration + + +number + + + + + + <optional>
    + + + + + +
    + + 250 + +

    The duration below which the button is considered as being just released.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the button is just released otherwise false.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    justPressed(buttonCode, duration) → {boolean}

    + + +
    +
    + + +
    +

    Returns the "just pressed" state of a button from this gamepad. Just pressed is considered true if the button was pressed down within the duration given (default 250ms).

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    buttonCode + + +number + + + + + + + + + + + +

    The buttonCode of the button to check for.

    duration + + +number + + + + + + <optional>
    + + + + + +
    + + 250 + +

    The duration below which the button is considered as being just pressed.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the button is just pressed otherwise false.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    pollStatus()

    + + +
    +
    + + +
    +

    Main update function, should be called by Phaser.Gamepad

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    processAxisChange(axisState)

    + + +
    +
    + + +
    +

    Handles changes in axis

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    axisState + + +Object + + + +

    State of the relevant axis

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    processButtonDown(buttonCode, value)

    + + +
    +
    + + +
    +

    Handles button down press

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    buttonCode + + +number + + + +

    Which buttonCode of this button

    value + + +Object + + + +

    Button value

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    processButtonFloat(buttonCode, value)

    + + +
    +
    + + +
    +

    Handles buttons with floating values (like analog buttons that acts almost like an axis but still registers like a button)

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    buttonCode + + +number + + + +

    Which buttonCode of this button

    value + + +Object + + + +

    Button value (will range somewhere between 0 and 1, but not specifically 0 or 1.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    processButtonUp(buttonCode, value)

    + + +
    +
    + + +
    +

    Handles button release

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    buttonCode + + +number + + + +

    Which buttonCode of this button

    value + + +Object + + + +

    Button value

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    reset()

    + + +
    +
    + + +
    +

    Reset all buttons/axes of this gamepad

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + +
    + + + + + +
    + +
    + + + + +
    + +
    +
    + + + + Phaser Copyright © 2012-2014 Photon Storm Ltd. + +
    + + + Documentation generated by JSDoc 3.3.0-dev + on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template. + +
    +
    + + +
    +
    +
    + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/Phaser.Sound.html b/docs/Phaser.Sound.html index df0232b4..c8bf2e3f 100644 --- a/docs/Phaser.Sound.html +++ b/docs/Phaser.Sound.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1503,7 +1497,7 @@
    Source:
    @@ -1605,7 +1599,7 @@
    Source:
    @@ -2118,7 +2112,7 @@
    Source:
    @@ -4167,7 +4161,7 @@
    Source:
    @@ -5685,7 +5679,7 @@ This allows you to bundle multiple sounds together into a single audio file and
    Source:
    @@ -5799,13 +5793,13 @@ This allows you to bundle multiple sounds together into a single audio file and - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:33 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.SoundManager.html b/docs/Phaser.SoundManager.html index 98fb3406..4c50e2f2 100644 --- a/docs/Phaser.SoundManager.html +++ b/docs/Phaser.SoundManager.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1075,7 +1069,7 @@ Note: On Firefox 25+ on Linux if you have media.gstreamer disabled in about:conf
    Source:
    @@ -1693,7 +1687,7 @@ Note: On Firefox 25+ on Linux if you have media.gstreamer disabled in about:conf
    Source:
    @@ -2857,13 +2851,13 @@ Note: On Firefox 25+ on Linux if you have media.gstreamer disabled in about:conf - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:33 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Sprite.html b/docs/Phaser.Sprite.html index 0f01f12b..8338ac67 100644 --- a/docs/Phaser.Sprite.html +++ b/docs/Phaser.Sprite.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -979,7 +973,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -1293,7 +1287,7 @@ A culled sprite has its renderable property set to 'false'.

    Source:
    @@ -1395,7 +1389,7 @@ A culled sprite has its renderable property set to 'false'.

    Source:
    @@ -1497,7 +1491,7 @@ A culled sprite has its renderable property set to 'false'.

    Source:
    @@ -1605,7 +1599,7 @@ It's used for Camera culling and physics body alignment.

    Source:
    @@ -1707,7 +1701,7 @@ It's used for Camera culling and physics body alignment.

    Source:
    @@ -1809,7 +1803,7 @@ It's used for Camera culling and physics body alignment.

    Source:
    @@ -1916,7 +1910,7 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    Source:
    @@ -2021,7 +2015,7 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    Source:
    @@ -2132,6 +2126,323 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    +
    + + + +
    + + + +
    +

    debug

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    debug + + +boolean + + + +

    Handy flag to use with Game.enableStep

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> deltaX

    + + +
    +
    + +
    +

    Returns the delta x value. The difference between Sprite.x now and in the previous step.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    deltaX + + +number + + + +

    The delta value. Positive if the motion was to the right, negative if to the left.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> deltaY

    + + +
    +
    + +
    +

    Returns the delta x value. The difference between Sprite.y now and in the previous step.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    deltaY + + +number + + + +

    The delta value. Positive if the motion was downwards, negative if upwards.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + +
    @@ -2439,7 +2750,7 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    Source:
    @@ -2541,7 +2852,7 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    Source:
    @@ -2643,7 +2954,7 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    Source:
    @@ -2949,7 +3260,7 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    Source:
    @@ -3056,7 +3367,7 @@ If you wish to crop the Sprite instead see the Sprite.crop value.

    Source:
    @@ -3158,7 +3469,7 @@ If you wish to crop the Sprite instead see the Sprite.crop value.

    Source:
    @@ -3367,7 +3678,7 @@ activated for this Sprite instance and it will then start to process click/touch
    Source:
    @@ -3469,7 +3780,7 @@ activated for this Sprite instance and it will then start to process click/touch
    Source:
    @@ -3574,7 +3885,7 @@ activated for this Sprite instance and it will then start to process click/touch
    Source:
    @@ -3999,7 +4310,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
    Source:
    @@ -4104,7 +4415,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
    Source:
    @@ -4516,7 +4827,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
    Source:
    @@ -4618,7 +4929,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
    Source:
    @@ -4827,7 +5138,7 @@ If you wish to crop the Sprite instead see the Sprite.crop value.

    Source:
    @@ -4938,6 +5249,210 @@ If you wish to crop the Sprite instead see the Sprite.crop value.

    + + + + + + + + +
    +

    <readonly> worldCenterX

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    worldCenterX + + +number + + + +

    The center of the Sprite in world coordinates.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> worldCenterY

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    worldCenterY + + +number + + + +

    The center of the Sprite in world coordinates.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + +
    @@ -5199,7 +5714,7 @@ bought to the top of that Group, not the entire display list.

    Source:
    @@ -5352,7 +5867,7 @@ Doesn't change the anchor point of the sprite.

    Source:
    @@ -5482,7 +5997,7 @@ If health is then taken below zero Sprite.kill is called.

    Source:
    @@ -5632,7 +6147,7 @@ and nulls its reference to game, freeing it up for garbage collection.

    Source:
    @@ -5660,7 +6175,7 @@ and nulls its reference to game, freeing it up for garbage collection.

    -

    getLocalPosition(p, x, y, sx, sy) → {Phaser.Point}

    +

    getLocalPosition(p, x, y) → {Phaser.Point}

    @@ -5765,53 +6280,7 @@ Mostly only used internally.

    -

    x coordinate within the Sprite to translate.

    - - - - - - - sx - - - - - -number - - - - - - - - - -

    Scale factor to be applied.

    - - - - - - - sy - - - - - -number - - - - - - - - - -

    Scale factor to be applied.

    +

    y coordinate within the Sprite to translate.

    @@ -5843,7 +6312,7 @@ Mostly only used internally.

    Source:
    @@ -5894,7 +6363,7 @@ Mostly only used internally.

    -

    getLocalUnmodifiedPosition(p, x, y) → {Phaser.Point}

    +

    getLocalUnmodifiedPosition(p, gx, gy) → {Phaser.Point}

    @@ -5960,7 +6429,7 @@ Mostly only used internally by the Input Manager, but also useful for custom hit - x + gx @@ -5983,7 +6452,7 @@ Mostly only used internally by the Input Manager, but also useful for custom hit - y + gy @@ -5999,7 +6468,7 @@ Mostly only used internally by the Input Manager, but also useful for custom hit -

    x coordinate within the Sprite to translate.

    +

    y coordinate within the Sprite to translate.

    @@ -6031,7 +6500,7 @@ Mostly only used internally by the Input Manager, but also useful for custom hit
    Source:
    @@ -6126,7 +6595,7 @@ If you don't need this Sprite any more you should call Sprite.destroy instead.Source:
    @@ -6291,7 +6760,7 @@ This causes a WebGL texture update, so use sparingly or in low-intensity portion
    Source:
    @@ -6543,7 +7012,7 @@ If the requested animation is already playing this request will be ignored. If y
    Source:
    @@ -6635,7 +7104,7 @@ If the requested animation is already playing this request will be ignored. If y
    Source:
    @@ -6704,7 +7173,7 @@ If the requested animation is already playing this request will be ignored. If y
    Source:
    @@ -6914,7 +7383,7 @@ If the Sprite has a physics body that too is reset.

    Source:
    @@ -6994,7 +7463,7 @@ If the Sprite has a physics body that too is reset.

    Source:
    @@ -7134,7 +7603,7 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived
    Source:
    @@ -7214,7 +7683,7 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived
    Source:
    @@ -7283,7 +7752,7 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived
    Source:
    @@ -7352,7 +7821,7 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived
    Source:
    @@ -7421,7 +7890,7 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived
    Source:
    @@ -7466,13 +7935,13 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:33 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Stage.html b/docs/Phaser.Stage.html index 02c2381b..bace5b63 100644 --- a/docs/Phaser.Stage.html +++ b/docs/Phaser.Stage.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -703,7 +697,7 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree
    Source:
    @@ -808,7 +802,7 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree
    Source:
    @@ -881,7 +875,7 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree -

    Reference to the newly created <canvas> element.

    +

    Reference to the newly created canvas element.

    @@ -910,7 +904,7 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree
    Source:
    @@ -1018,7 +1012,214 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree
    Source:
    + + + + + + + + + + + + + + + +
    +

    disableVisibilityChange

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    disableVisibilityChange + + +boolean + + + +

    By default if the browser tab loses focus the game will pause. You can stop that behaviour by setting this property to true.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    display

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    display + + +PIXI.Stage + + + +

    The Pixi Stage which is hooked to the renderer.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1222,7 +1423,7 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree
    Source:
    @@ -1324,7 +1525,7 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree
    Source:
    @@ -1426,7 +1627,7 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree
    Source:
    @@ -1449,6 +1650,75 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree
    +
    +

    <protected> parseConfig()

    + + +
    +
    + + +
    +

    Parses a Game configuration object.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + +

    update()

    @@ -1491,7 +1761,7 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree
    Source:
    @@ -1609,7 +1879,7 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree
    Source:
    @@ -1654,13 +1924,13 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:34 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.StageScaleMode.html b/docs/Phaser.StageScaleMode.html index 33c6baa3..72ea2c10 100644 --- a/docs/Phaser.StageScaleMode.html +++ b/docs/Phaser.StageScaleMode.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -2016,7 +2010,7 @@
    Source:
    @@ -2118,7 +2112,7 @@
    Source:
    @@ -2220,7 +2214,7 @@
    Source:
    @@ -3690,7 +3684,7 @@ It doesn't care about any other DOM element that may be on the page, it literall
    Source:
    @@ -3759,7 +3753,7 @@ It doesn't care about any other DOM element that may be on the page, it literall
    Source:
    @@ -3877,7 +3871,7 @@ It doesn't care about any other DOM element that may be on the page, it literall
    Source:
    @@ -4090,7 +4084,7 @@ The optional orientationImage is displayed when the game is in the incorrect ori
    Source:
    @@ -4208,7 +4202,7 @@ The optional orientationImage is displayed when the game is in the incorrect ori
    Source:
    @@ -4277,7 +4271,7 @@ The optional orientationImage is displayed when the game is in the incorrect ori
    Source:
    @@ -4346,7 +4340,7 @@ The optional orientationImage is displayed when the game is in the incorrect ori
    Source:
    @@ -4415,7 +4409,7 @@ The optional orientationImage is displayed when the game is in the incorrect ori
    Source:
    @@ -4533,7 +4527,7 @@ The optional orientationImage is displayed when the game is in the incorrect ori
    Source:
    @@ -4602,7 +4596,7 @@ The optional orientationImage is displayed when the game is in the incorrect ori
    Source:
    @@ -4671,7 +4665,7 @@ The optional orientationImage is displayed when the game is in the incorrect ori
    Source:
    @@ -4859,7 +4853,7 @@ Please note that this needs to be supported by the web browser and isn't the sam
    Source:
    @@ -4904,13 +4898,13 @@ Please note that this needs to be supported by the web browser and isn't the sam - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:34 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.State.html b/docs/Phaser.State.html index 4abb2f28..d0a995ce 100644 --- a/docs/Phaser.State.html +++ b/docs/Phaser.State.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -2568,13 +2562,13 @@ If you need to use the loader, you may need to use them here.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:34 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.StateManager.html b/docs/Phaser.StateManager.html index 5443e918..bd5daaaf 100644 --- a/docs/Phaser.StateManager.html +++ b/docs/Phaser.StateManager.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -2134,7 +2128,8 @@
    -

    Description.

    +

    Checks i a given phaser state is valid. +State must exist and have at least one callback function registered..

    @@ -2308,7 +2303,7 @@
    Source:
    @@ -2331,6 +2326,86 @@ +
    + + + +
    +

    getCurrentState()

    + + +
    +
    + + +
    +

    Gets the current State.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    Phaser.State

    +
    + + + + + + +
    @@ -2426,7 +2501,7 @@
    Source:
    @@ -2491,7 +2566,7 @@
    Source:
    @@ -2556,7 +2631,7 @@
    Source:
    @@ -2621,7 +2696,7 @@
    Source:
    @@ -2804,7 +2879,7 @@
    Source:
    @@ -2869,125 +2944,7 @@
    Source:
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    -

    <protected> setCurrentState(key)

    - - -
    -
    - - -
    -

    Sets the current State. Should not be called directly (use StateManager.start)

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    key - - -string - - - -

    State key.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -3246,7 +3203,7 @@
    Source:
    @@ -3291,13 +3248,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:34 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Text.html b/docs/Phaser.Text.html index 7fe0b27d..ea84a034 100644 --- a/docs/Phaser.Text.html +++ b/docs/Phaser.Text.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -446,7 +440,7 @@
    -

    Create a new <code>Text</code>.

    +

    Create a new Text object.

    @@ -968,7 +962,109 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    cameraOffset

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    cameraOffset + + +Phaser.Point + + + +

    If this object is fixed to the camera then use this Point to specify how far away from the Camera x/y it's rendered.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1074,7 +1170,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -1188,6 +1284,115 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati +
    + + + +
    + + + +
    +

    fixedToCamera

    + + +
    +
    + +
    +

    An object that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    fixedToCamera + + +boolean + + + +

    Fixes this object to the Camera.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + +
    @@ -1285,7 +1490,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -1693,7 +1898,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -2003,7 +2208,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -2109,7 +2314,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -2170,7 +2375,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -2235,7 +2440,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -2304,7 +2509,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -2349,13 +2554,13 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:34 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Tile.html b/docs/Phaser.Tile.html index 699e5fa3..c6710c82 100644 --- a/docs/Phaser.Tile.html +++ b/docs/Phaser.Tile.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -427,7 +421,7 @@ Tile -

    A Tile is a single representation of a tile within a Tilemap.

    +

    A Tile is a representation of a single tile within the Tilemap.

    @@ -438,7 +432,7 @@
    -

    new Tile(tileset, index, x, y, width, height)

    +

    new Tile(layer, index, x, y, width, height)

    @@ -446,7 +440,7 @@
    -

    Create a new Tile object. Tiles live inside of Tilesets and are rendered via TilemapLayers.

    +

    Create a new Tile object.

    @@ -480,13 +474,13 @@ - tileset + layer -Phaser.Tileset +object @@ -496,7 +490,7 @@ -

    The tileset this tile belongs to.

    +

    The layer in the Tilemap data that this tile belongs to.

    @@ -686,6 +680,108 @@
    +
    +

    alpha

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    alpha + + +number + + + +

    The alpha value at which this tile is drawn to the canvas.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + +

    <readonly> bottom

    @@ -771,7 +867,316 @@
    Source:
    + + + + + + + +
    + + + + + + + +
    +

    callback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    callback + + +function + + + +

    Tile collision callback.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • null
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    callbackContext

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    callbackContext + + +object + + + +

    The context in which the collision callback will be called.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> canCollide

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    canCollide + + +boolean + + + +

    True if this tile can collide or has a collision callback.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -876,7 +1281,7 @@
    Source:
    @@ -981,7 +1386,7 @@
    Source:
    @@ -1086,7 +1491,7 @@
    Source:
    @@ -1191,7 +1596,109 @@
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    collides

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    collides + + +boolean + + + +

    Does this tile collide at all?

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1296,7 +1803,7 @@
    Source:
    @@ -1314,7 +1821,7 @@
    -

    collisionCallback

    +

    faceBottom

    @@ -1353,7 +1860,7 @@ - collisionCallback + faceBottom @@ -1369,7 +1876,7 @@ -

    Tilemap collision callback.

    +

    Is the bottom of this tile an interesting edge?

    @@ -1394,14 +1901,11 @@ -
    Default Value:
    -
    • null
    -
    Source:
    @@ -1419,7 +1923,7 @@
    -

    collisionCallbackContext

    +

    faceLeft

    @@ -1458,7 +1962,7 @@ - collisionCallback + faceLeft @@ -1474,7 +1978,7 @@ -

    Tilemap collision callback.

    +

    Is the left of this tile an interesting edge?

    @@ -1503,7 +2007,211 @@
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    faceRight

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    faceRight + + +boolean + + + +

    Is the right of this tile an interesting edge?

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    faceTop

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    faceTop + + +boolean + + + +

    Is the top of this tile an interesting edge?

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1605,7 +2313,7 @@
    Source:
    @@ -1678,7 +2386,7 @@ -

    The index of this tile within the tileset.

    +

    The index of this tile within the map data corresponding to the tileset.

    @@ -1725,7 +2433,7 @@
    -

    mass

    +

    layer

    @@ -1764,13 +2472,13 @@ - mass + layer -number +object @@ -1780,7 +2488,7 @@ -

    The virtual mass of the tile.

    +

    The layer in the Tilemap data that this tile belongs to.

    @@ -1805,14 +2513,215 @@ -
    Default Value:
    -
    • 1.0
    + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> left

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    left + + +number + + + +

    The x value.

    +
    + + + + + + + + + + + + + + + + +
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    properties

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    properties + + +object + + + +

    Tile specific properties.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1914,7 +2823,7 @@
    Source:
    @@ -1932,7 +2841,7 @@
    -

    separateX

    +

    scanned

    @@ -1971,7 +2880,7 @@ - separateX + scanned @@ -1987,7 +2896,7 @@ -

    Enable separation at x-axis.

    +

    Has this tile been walked / turned into a poly?

    @@ -2012,14 +2921,11 @@ -
    Default Value:
    -
    • true
    -
    Source:
    @@ -2037,7 +2943,7 @@
    -

    separateY

    +

    <readonly> top

    @@ -2076,13 +2982,13 @@ - separateY + top -boolean +number @@ -2092,112 +2998,7 @@ -

    Enable separation at y-axis.

    - - - - - -
    - - - - - - - - - - - - - - - - - - -
    Default Value:
    -
    • true
    - - - -
    Source:
    -
    - - - - - - - - - - - - - - - -
    -

    tileset

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -2226,7 +3027,7 @@
    Source:
    @@ -2328,7 +3129,7 @@
    Source:
    @@ -2401,7 +3202,7 @@ - + @@ -2430,7 +3231,7 @@
    Source:
    @@ -2503,7 +3304,7 @@ - + @@ -2532,7 +3333,7 @@
    Source:
    @@ -2555,6 +3356,124 @@
    +
    +

    copy(tile)

    + + +
    +
    + + +
    +

    Copies the tile data and properties from the given tile to this tile.

    +
    + + + + + + + +
    Parameters:
    + + +
    NameTypeDescription
    tileset - - -Phaser.Tileset - - - -

    The tileset this tile belongs to.

    The y value.

    The top-left corner of the tile within the tileset.

    The x map coordinate of this tile.

    The top-left corner of the tile within the tileset.

    The y map coordinate of this tile.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    tile + + +Phaser.Tile + + + +

    The tile to copy from.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + +

    destroy()

    @@ -2597,7 +3516,7 @@
    Source:
    @@ -2666,7 +3585,7 @@
    Source:
    @@ -2853,7 +3772,7 @@
    Source:
    @@ -2889,7 +3808,8 @@
    -

    Set callback to be called when this tilemap collides.

    +

    Set a callback to be called when this tile is hit by an object. +The callback must true true for collision processing to take place.

    @@ -2994,7 +3914,7 @@
    Source:
    @@ -3039,13 +3959,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:34 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.TileSprite.html b/docs/Phaser.TileSprite.html index 2f95aca9..04e6138a 100644 --- a/docs/Phaser.TileSprite.html +++ b/docs/Phaser.TileSprite.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -438,7 +432,7 @@
    -

    new TileSprite(game, x, y, width, height, key, frame)

    +

    new TileSprite(game, x, y, width, height, key)

    @@ -621,32 +615,6 @@ - - - - frame - - - - - -string -| - -number - - - - - - - - - -

    If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.

    - - - @@ -675,7 +643,7 @@
    Source:
    @@ -1025,11 +993,6 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati -
    Inherited From:
    -
    - @@ -1044,7 +1007,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
    Source:
    @@ -1373,7 +1336,7 @@ A culled sprite has its renderable property set to 'false'.

    Source:
    @@ -1480,7 +1443,7 @@ A culled sprite has its renderable property set to 'false'.

    Source:
    @@ -1587,7 +1550,7 @@ A culled sprite has its renderable property set to 'false'.

    Source:
    @@ -1700,7 +1663,7 @@ It's used for Camera culling and physics body alignment.

    Source:
    @@ -1807,7 +1770,7 @@ It's used for Camera culling and physics body alignment.

    Source:
    @@ -1914,7 +1877,7 @@ It's used for Camera culling and physics body alignment.

    Source:
    @@ -2026,7 +1989,7 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    Source:
    @@ -2136,7 +2099,7 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    Source:
    @@ -2252,6 +2215,338 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    + + + + + + + + +
    +

    debug

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    debug + + +boolean + + + +

    Handy flag to use with Game.enableStep

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> deltaX

    + + +
    +
    + +
    +

    Returns the delta x value. The difference between Sprite.x now and in the previous step.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    deltaX + + +number + + + +

    The delta value. Positive if the motion was to the right, negative if to the left.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> deltaY

    + + +
    +
    + +
    +

    Returns the delta x value. The difference between Sprite.y now and in the previous step.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    deltaY + + +number + + + +

    The delta value. Positive if the motion was downwards, negative if upwards.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + +
    @@ -2574,7 +2869,7 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    Source:
    @@ -2662,11 +2957,6 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    -
    Inherited From:
    -
    - @@ -2681,7 +2971,7 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    Source:
    @@ -2769,11 +3059,6 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    -
    Inherited From:
    -
    - @@ -2788,7 +3073,7 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    Source:
    @@ -3109,7 +3394,7 @@ The crop is only applied if you have set Sprite.cropEnabled to true.

    Source:
    @@ -3221,7 +3506,7 @@ If you wish to crop the Sprite instead see the Sprite.crop value.

    Source:
    @@ -3309,11 +3594,6 @@ If you wish to crop the Sprite instead see the Sprite.crop value.

    -
    Inherited From:
    -
    - @@ -3328,7 +3608,7 @@ If you wish to crop the Sprite instead see the Sprite.crop value.

    Source:
    @@ -3528,11 +3808,6 @@ activated for this Sprite instance and it will then start to process click/touch -
    Inherited From:
    -
    - @@ -3547,7 +3822,7 @@ activated for this Sprite instance and it will then start to process click/touch
    Source:
    @@ -3654,7 +3929,7 @@ activated for this Sprite instance and it will then start to process click/touch
    Source:
    @@ -3764,7 +4039,7 @@ activated for this Sprite instance and it will then start to process click/touch
    Source:
    @@ -4209,7 +4484,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
    Source:
    @@ -4319,7 +4594,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
    Source:
    @@ -4635,7 +4910,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
    Source:
    @@ -4848,7 +5123,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
    Source:
    @@ -4950,7 +5225,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
    Source:
    @@ -5057,7 +5332,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
    Source:
    @@ -5164,7 +5439,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
    Source:
    @@ -5266,7 +5541,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
    Source:
    @@ -5378,7 +5653,7 @@ If you wish to crop the Sprite instead see the Sprite.crop value.

    Source:
    @@ -5494,6 +5769,220 @@ If you wish to crop the Sprite instead see the Sprite.crop value.

    + + + + + + + + +
    +

    <readonly> worldCenterX

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    worldCenterX + + +number + + + +

    The center of the Sprite in world coordinates.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> worldCenterY

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    worldCenterY + + +number + + + +

    The center of the Sprite in world coordinates.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + +
    @@ -5770,7 +6259,7 @@ bought to the top of that Group, not the entire display list.

    Source:
    @@ -5928,7 +6417,7 @@ Doesn't change the anchor point of the sprite.

    Source:
    @@ -6063,7 +6552,7 @@ If health is then taken below zero Sprite.kill is called.

    Source:
    @@ -6223,7 +6712,7 @@ and nulls its reference to game, freeing it up for garbage collection.

    Source:
    @@ -6251,7 +6740,7 @@ and nulls its reference to game, freeing it up for garbage collection.

    -

    getLocalPosition(p, x, y, sx, sy) → {Phaser.Point}

    +

    getLocalPosition(p, x, y) → {Phaser.Point}

    @@ -6356,53 +6845,7 @@ Mostly only used internally.

    -

    x coordinate within the Sprite to translate.

    - - - - - - - sx - - - - - -number - - - - - - - - - -

    Scale factor to be applied.

    - - - - - - - sy - - - - - -number - - - - - - - - - -

    Scale factor to be applied.

    +

    y coordinate within the Sprite to translate.

    @@ -6439,7 +6882,7 @@ Mostly only used internally.

    Source:
    @@ -6490,7 +6933,7 @@ Mostly only used internally.

    -

    getLocalUnmodifiedPosition(p, x, y) → {Phaser.Point}

    +

    getLocalUnmodifiedPosition(p, gx, gy) → {Phaser.Point}

    @@ -6556,7 +6999,7 @@ Mostly only used internally by the Input Manager, but also useful for custom hit - x + gx @@ -6579,7 +7022,7 @@ Mostly only used internally by the Input Manager, but also useful for custom hit - y + gy @@ -6595,7 +7038,7 @@ Mostly only used internally by the Input Manager, but also useful for custom hit -

    x coordinate within the Sprite to translate.

    +

    y coordinate within the Sprite to translate.

    @@ -6632,7 +7075,7 @@ Mostly only used internally by the Input Manager, but also useful for custom hit
    Source:
    @@ -6732,7 +7175,7 @@ If you don't need this Sprite any more you should call Sprite.destroy instead.Source:
    @@ -6902,7 +7345,7 @@ This causes a WebGL texture update, so use sparingly or in low-intensity portion
    Source:
    @@ -7159,7 +7602,7 @@ If the requested animation is already playing this request will be ignored. If y
    Source:
    @@ -7256,7 +7699,7 @@ If the requested animation is already playing this request will be ignored. If y
    Source:
    @@ -7330,7 +7773,7 @@ If the requested animation is already playing this request will be ignored. If y
    Source:
    @@ -7545,7 +7988,7 @@ If the Sprite has a physics body that too is reset.

    Source:
    @@ -7630,7 +8073,7 @@ If the Sprite has a physics body that too is reset.

    Source:
    @@ -7775,7 +8218,7 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived
    Source:
    @@ -7860,7 +8303,7 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived
    Source:
    @@ -7934,7 +8377,7 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived
    Source:
    @@ -8008,7 +8451,7 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived
    Source:
    @@ -8082,7 +8525,7 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived
    Source:
    @@ -8127,13 +8570,13 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:35 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Tilemap.html b/docs/Phaser.Tilemap.html index 2d0976e6..feae7e2e 100644 --- a/docs/Phaser.Tilemap.html +++ b/docs/Phaser.Tilemap.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -658,7 +652,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -718,7 +712,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -820,7 +814,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -922,109 +916,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    - - - - - - - - - - - - - - - -
    -

    dirty

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    dirty - - -boolean - - - -

    Internal rendering related flag.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -1135,6 +1027,210 @@ A map may have multiple layers. You can perform operations on the map data such +
    + + + +
    + + + +
    +

    images

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    images + + +array + + + +

    An array of Tiled Image Layers.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    key

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    key + + +string + + + +

    The key of this map data in the Phaser.Cache.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + +
    @@ -1199,7 +1295,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    An array of Tilemap layers.

    +

    An array of Tilemap layer data.

    @@ -1228,7 +1324,313 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    + + + + + + + + + + + + + + + +
    +

    objects

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    objects + + +array + + + +

    An array of Tiled Object Layers.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    tiles

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    tiles + + +array + + + +

    The super array of Tiles.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    tilesets

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    tilesets + + +array + + + +

    An array of Tilesets.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1252,7 +1654,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    calculateIndexes()

    +

    addTilesetImage(tileset, key)

    @@ -1260,7 +1662,8 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    Internal function that calculates the tile indexes for the map data.

    +

    Adds an image to the map to be used as a tileset. A single map may use multiple tilesets. +Note that the tileset name can be found in the JSON file exported from Tiled, or in the Tiled editor.

    @@ -1269,6 +1672,98 @@ A map may have multiple layers. You can perform operations on the map data such +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDescription
    tileset + + +string + + + + + + + + + +

    The name of the tileset as specified in the map data.

    key + + +string + + + + + + <optional>
    + + + + + +

    The key of the Phaser.Cache image used for this tileset. If not specified it will look for an image with a key matching the tileset parameter.

    + +
    @@ -1293,7 +1788,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -1496,6 +1991,12 @@ A map may have multiple layers. You can perform operations on the map data such number +| + +string +| + +Phaser.TilemapLayer @@ -1515,7 +2016,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    The Tilemap Layer to operate on.

    +

    The layer to copy the tiles from.

    @@ -1547,7 +2048,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -1734,7 +2235,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -1803,7 +2304,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -1872,7 +2373,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -1908,7 +2409,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    Fill a block with a specific tile index.

    +

    Fills the given area with the specified tile.

    @@ -1968,7 +2469,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    Index of tiles you want to fill with.

    +

    The index of the tile that the area will be filled with.

    @@ -2106,6 +2607,12 @@ A map may have multiple layers. You can perform operations on the map data such number +| + +string +| + +Phaser.TilemapLayer @@ -2125,7 +2632,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    The Tilemap Layer to operate on.

    +

    The layer to operate on.

    @@ -2157,7 +2664,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -2193,7 +2700,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    For each tile in the given area (defined by x/y and width/height) run the given callback.

    +

    For each tile in the given area defined by x/y and width/height run the given callback.

    @@ -2422,6 +2929,12 @@ A map may have multiple layers. You can perform operations on the map data such number +| + +string +| + +Phaser.TilemapLayer @@ -2441,7 +2954,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    The Tilemap Layer to operate on.

    +

    The layer to operate on.

    @@ -2473,7 +2986,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -2501,7 +3014,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    getTile(x, y, layer) → {number}

    +

    getTile(x, y, layer) → {Phaser.Tile}

    @@ -2614,6 +3127,12 @@ A map may have multiple layers. You can perform operations on the map data such number +| + +string +| + +Phaser.TilemapLayer @@ -2633,7 +3152,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    The Tilemap Layer to operate on.

    +

    The layer to get the tile from.

    @@ -2665,7 +3184,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -2690,7 +3209,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    The index of the tile at the given coordinates.

    +

    The tile at the given coordinates.

    @@ -2701,7 +3220,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -number +Phaser.Tile
    @@ -2716,7 +3235,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    getTileWorldXY(x, y, layer) → {number}

    +

    getTileWorldXY(x, y, layer) → {Phaser.Tile}

    @@ -2829,6 +3348,12 @@ A map may have multiple layers. You can perform operations on the map data such number +| + +string +| + +Phaser.TilemapLayer @@ -2848,7 +3373,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    The Tilemap Layer to operate on.

    +

    The layer to get the tile from.

    @@ -2880,7 +3405,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -2905,7 +3430,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    The index of the tile at the given coordinates.

    +

    The tile at the given coordinates.

    @@ -2916,7 +3441,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -number +Phaser.Tile
    @@ -2931,7 +3456,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    paste(x, y, tileblock, layer)

    +

    paste(x, y, tileblock, layer)

    @@ -2961,6 +3486,8 @@ A map may have multiple layers. You can perform operations on the map data such Type + Argument + @@ -2986,6 +3513,14 @@ A map may have multiple layers. You can perform operations on the map data such + + + + + + + + @@ -3009,6 +3544,14 @@ A map may have multiple layers. You can perform operations on the map data such + + + + + + + + @@ -3032,6 +3575,14 @@ A map may have multiple layers. You can perform operations on the map data such + + + + + + + + @@ -3049,16 +3600,32 @@ A map may have multiple layers. You can perform operations on the map data such number +| + +string +| + +Phaser.TilemapLayer + + + <optional>
    + + + + + + + -

    The Tilemap Layer to operate on.

    +

    The layer to paste the tiles into.

    @@ -3090,7 +3657,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -3118,7 +3685,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    putTile(index, x, y, layer)

    +

    putTile(tile, x, y, layer)

    @@ -3162,12 +3729,15 @@ A map may have multiple layers. You can perform operations on the map data such - index + tile +Phaser.Tile +| + number @@ -3186,7 +3756,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    The index of this tile to set.

    +

    The index of this tile to set or a Phaser.Tile object.

    @@ -3262,6 +3832,12 @@ A map may have multiple layers. You can perform operations on the map data such number +| + +string +| + +Phaser.TilemapLayer @@ -3281,7 +3857,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    The Tilemap Layer to operate on.

    +

    The layer to modify.

    @@ -3313,7 +3889,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -3341,7 +3917,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    putTileWorldXY(index, x, y, tileWidth, tileHeight, layer)

    +

    putTileWorldXY(tile, x, y, tileWidth, tileHeight, layer)

    @@ -3385,12 +3961,15 @@ A map may have multiple layers. You can perform operations on the map data such - index + tile +Phaser.Tile +| + number @@ -3409,7 +3988,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    The index of the tile to put into the layer.

    +

    The index of this tile to set or a Phaser.Tile object.

    @@ -3547,6 +4126,12 @@ A map may have multiple layers. You can perform operations on the map data such number +| + +string +| + +Phaser.TilemapLayer @@ -3566,7 +4151,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    The Tilemap Layer to operate on.

    +

    The layer to modify.

    @@ -3598,7 +4183,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -3626,7 +4211,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    random(tileA, tileB, x, y, width, height, layer)

    +

    random(x, y, width, height, layer)

    @@ -3668,68 +4253,6 @@ A map may have multiple layers. You can perform operations on the map data such - - - tileA - - - - - -number - - - - - - - - - - - - - - - - - -

    First tile index.

    - - - - - - - tileB - - - - - -number - - - - - - - - - - - - - - - - - -

    Second tile index.

    - - - - x @@ -3863,6 +4386,12 @@ A map may have multiple layers. You can perform operations on the map data such number +| + +string +| + +Phaser.TilemapLayer @@ -3882,7 +4411,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    The Tilemap Layer to operate on.

    +

    The layer to operate on.

    @@ -3914,7 +4443,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -3983,7 +4512,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -4011,7 +4540,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    replace(tileA, tileB, x, y, width, height, layer)

    +

    replace(source, dest, x, y, width, height, layer)

    @@ -4019,7 +4548,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    Replaces one type of tile with another in the given area (defined by x/y and width/height).

    +

    Scans the given area for tiles with an index matching source and updates their index to match dest.

    @@ -4055,7 +4584,7 @@ A map may have multiple layers. You can perform operations on the map data such - tileA + source @@ -4079,14 +4608,14 @@ A map may have multiple layers. You can perform operations on the map data such -

    First tile index.

    +

    The tile index value to scan for.

    - tileB + dest @@ -4110,7 +4639,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    Second tile index.

    +

    The tile index value to replace found tiles with.

    @@ -4248,6 +4777,12 @@ A map may have multiple layers. You can perform operations on the map data such number +| + +string +| + +Phaser.TilemapLayer @@ -4267,7 +4802,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    The Tilemap Layer to operate on.

    +

    The layer to operate on.

    @@ -4299,7 +4834,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -4376,6 +4911,12 @@ A map may have multiple layers. You can perform operations on the map data such number +| + +string +| + +Phaser.TilemapLayer @@ -4385,7 +4926,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    Sets the current layer to the given index.

    +

    The layer to set as current.

    @@ -4417,7 +4958,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    @@ -4445,7 +4986,7 @@ A map may have multiple layers. You can perform operations on the map data such
    -

    shuffle(tileA, tileB, x, y, width, height, layer)

    +

    shuffle(x, y, width, height, layer)

    @@ -4462,6 +5003,266 @@ A map may have multiple layers. You can perform operations on the map data such +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDescription
    x + + +number + + + + + + + + + +

    X position of the top left of the area to operate one, given in tiles, not pixels.

    y + + +number + + + + + + + + + +

    Y position of the top left of the area to operate one, given in tiles, not pixels.

    width + + +number + + + + + + + + + +

    The width in tiles of the area to operate on.

    height + + +number + + + + + + + + + +

    The height in tiles of the area to operate on.

    layer + + +number +| + +string +| + +Phaser.TilemapLayer + + + + + + <optional>
    + + + + + +

    The layer to operate on.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    swapTile(tileA, tileB, x, y, width, height, layer)

    + + +
    +
    + + +
    +

    Scans the given area for tiles with an index matching tileA and swaps them with tileB.

    +
    + + + + + + +
    Parameters:
    @@ -4682,6 +5483,12 @@ A map may have multiple layers. You can perform operations on the map data such number +| + +string +| + +Phaser.TilemapLayer @@ -4701,7 +5508,7 @@ A map may have multiple layers. You can perform operations on the map data such -

    The Tilemap Layer to operate on.

    +

    The layer to operate on.

    @@ -4733,381 +5540,7 @@ A map may have multiple layers. You can perform operations on the map data such
    Source:
    - - - - - - - - - - - - - - - - - - - - - - - - - -
    -

    swapHandler(value, index)

    - - -
    -
    - - -
    -

    Internal function that handles the swapping of tiles.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    value - - -number - - - -
    index - - -number - - - -
    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    swapTile(tileA, tileB, x, y, width, height)

    - - -
    -
    - - -
    -

    Swap tiles with 2 kinds of indexes.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    tileA - - -number - - - -

    First tile index.

    tileB - - -number - - - -

    Second tile index.

    x - - -number - - - -

    X position of the top left of the area to operate one, given in tiles, not pixels.

    y - - -number - - - -

    Y position of the top left of the area to operate one, given in tiles, not pixels.

    width - - -number - - - -

    The width in tiles of the area to operate on.

    height - - -number - - - -

    The height in tiles of the area to operate on.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -5152,13 +5585,13 @@ A map may have multiple layers. You can perform operations on the map data such - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:34 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.TilemapLayer.html b/docs/Phaser.TilemapLayer.html index 074bbadf..6324e83e 100644 --- a/docs/Phaser.TilemapLayer.html +++ b/docs/Phaser.TilemapLayer.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -438,7 +432,7 @@
    -

    new TilemapLayer(game, x, y, renderWidth, renderHeight, tileset, tilemap, layer)

    +

    new TilemapLayer(game, tilemap, index, width, height)

    @@ -501,124 +495,6 @@ - - - x - - - - - -number - - - - - - - - - -

    The x coordinate of this layer.

    - - - - - - - y - - - - - -number - - - - - - - - - -

    The y coordinate of this layer.

    - - - - - - - renderWidth - - - - - -number - - - - - - - - - -

    Width of the layer.

    - - - - - - - renderHeight - - - - - -number - - - - - - - - - -

    Height of the layer.

    - - - - - - - tileset - - - - - -Phaser.Tileset -| - -string - - - - - - - - - -

    The tile set used for rendering.

    - - - - tilemap @@ -644,7 +520,7 @@ - layer + index @@ -660,7 +536,53 @@ -

    The layer index within the map.

    +

    The layer index within the map that this TilemapLayer represents.

    + + + + + + + width + + + + + +number + + + + + + + + + +

    Width of the renderable area of the layer.

    + + + + + + + height + + + + + +number + + + + + + + + + +

    Height of the renderable area of the layer.

    @@ -692,7 +614,7 @@
    Source:
    @@ -820,7 +742,109 @@
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    cameraOffset

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    cameraOffset + + +Phaser.Point + + + +

    If this object is fixed to the camera then use this Point to specify how far away from the Camera x/y it's rendered.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -893,7 +917,7 @@ -

    The canvas to which this BitmapData draws.

    +

    The canvas to which this TilemapLayer draws.

    @@ -922,7 +946,211 @@
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    collisionHeight

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    collisionHeight + + +number + + + +

    The height of the collision tiles.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    collisionWidth

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    collisionWidth + + +number + + + +

    The width of the collision tiles.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1024,7 +1252,637 @@
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    debug

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    debug + + +boolean + + + +

    If set to true the collideable tile edges path will be rendered. Only works when game is running in Phaser.CANVAS mode.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    debugAlpha

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    debugAlpha + + +number + + + +

    If debug is true then the tileset is rendered with this alpha level, to make the tile edges clearer.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • 0.5
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    debugCallbackColor

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    debugCallbackColor + + +string + + + +

    If debug is true this is the color used to outline the edges of tiles that have collision callbacks. Provide in hex or rgb/rgba string format.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • "rgba(255, 0, 0, 1)"
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    debugColor

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    debugColor + + +string + + + +

    If debug is true this is the color used to outline the edges of collidable tiles. Provide in hex or rgb/rgba string format.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • "rgba(0, 255, 0, 1)"
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    debugFill

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    debugFill + + +boolean + + + +

    If true the debug tiles are filled with debugFillColor AND stroked around.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    debugFillColor

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    debugFillColor + + +string + + + +

    If debugFill is true this is the color used to fill the tiles. Provide in hex or rgb/rgba string format.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • "rgba(0, 255, 0, 0.2)"
    + + + +
    Source:
    +
    @@ -1126,7 +1984,7 @@
    Source:
    @@ -1151,7 +2009,7 @@
    -

    A layer that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera.

    +

    An object that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera.

    @@ -1203,7 +2061,7 @@ -

    Fixes this layer to the Camera.

    +

    Fixes this object to the Camera.

    @@ -1235,7 +2093,7 @@
    Source:
    @@ -1337,109 +2195,7 @@
    Source:
    - - - - - - - -
    - - - -
    - - - -
    -

    <readonly> heightInPixels

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    heightInPixels - - -number - - - -

    Do NOT recommend changing after the map is loaded!

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -1512,7 +2268,7 @@ - +

    The index of this layer within the Tilemap.

    @@ -1541,7 +2297,7 @@
    Source:
    @@ -1604,7 +2360,7 @@ -number +object @@ -1614,7 +2370,7 @@ -

    Tilemap layer index.

    +

    The layer object within the Tilemap that this layer represents.

    @@ -1643,7 +2399,7 @@
    Source:
    @@ -1661,7 +2417,7 @@
    -

    renderHeight

    +

    map

    @@ -1700,13 +2456,13 @@ - renderHeight + map -number +Phaser.Tilemap @@ -1716,7 +2472,7 @@ -

    The height of the area being rendered.

    +

    The Tilemap to which this layer is bound.

    @@ -1745,7 +2501,7 @@
    Source:
    @@ -1763,7 +2519,7 @@
    -

    renderWidth

    +

    name

    @@ -1802,13 +2558,13 @@ - renderWidth + name -number +string @@ -1818,7 +2574,7 @@ -

    The width of the area being rendered.

    +

    The name of the layer.

    @@ -1847,7 +2603,7 @@
    Source:
    @@ -1954,7 +2710,7 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    @@ -2061,7 +2817,7 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    @@ -2163,7 +2919,7 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    @@ -2265,7 +3021,7 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    @@ -2367,7 +3123,7 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    @@ -2469,7 +3225,7 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    @@ -2487,7 +3243,7 @@ half as quickly as the 'normal' camera-locked layers do)

    -

    tileHeight

    +

    tileColor

    @@ -2526,13 +3282,13 @@ half as quickly as the 'normal' camera-locked layers do)

    - tileHeight + tileColor -number +string @@ -2542,7 +3298,7 @@ half as quickly as the 'normal' camera-locked layers do)

    -

    The height of a single tile in pixels.

    +

    If no tileset is given the tiles will be rendered as rectangles in this color. Provide in hex or rgb/rgba string format.

    @@ -2567,521 +3323,14 @@ half as quickly as the 'normal' camera-locked layers do)

    - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    tilemap

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    tilemap - - -Phaser.Tilemap - - - -

    The Tilemap to which this layer is bound.

    -
    - - - - - - - - - - - - - - - - - +
    Default Value:
    +
    • "rgb(255, 255, 255)"
    Source:
    - - - - - - - -
    - - - -
    - - - -
    -

    tileMargin

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    tileMargin - - -number - - - -

    The margin around the tiles.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    tileset

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    tileset - - -Phaser.Tileset - - - -

    The tile set used for rendering.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    tileSpacing

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    tileSpacing - - -number - - - -

    The spacing around the tiles.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - -
    - - - -
    -

    tileWidth

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    tileWidth - - -number - - - -

    The width of a single tile in pixels.

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -3183,109 +3432,7 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    - - - - - - - -
    - - - -
    - - - -
    -

    <readonly> widthInPixels

    - - -
    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    widthInPixels - - -number - - - -

    Do NOT recommend changing after the map is loaded!

    -
    - - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -3309,7 +3456,7 @@ half as quickly as the 'normal' camera-locked layers do)

    -

    deltaAbsX() → {number}

    +

    getTiles(x, y, width, height, collides) → {array}

    @@ -3317,375 +3464,7 @@ half as quickly as the 'normal' camera-locked layers do)

    -

    Returns the absolute delta x value.

    -
    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    Absolute delta X value

    -
    - - - -
    -
    - Type -
    -
    - -number - - -
    -
    - - - - - -
    - - - -
    -

    deltaAbsY() → {number}

    - - -
    -
    - - -
    -

    Returns the absolute delta y value.

    -
    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    Absolute delta Y value

    -
    - - - -
    -
    - Type -
    -
    - -number - - -
    -
    - - - - - -
    - - - -
    -

    deltaX() → {number}

    - - -
    -
    - - -
    -

    Returns the delta x value.

    -
    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    Delta X value

    -
    - - - -
    -
    - Type -
    -
    - -number - - -
    -
    - - - - - -
    - - - -
    -

    deltaY() → {number}

    - - -
    -
    - - -
    -

    Returns the delta y value.

    -
    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    Delta Y value

    -
    - - - -
    -
    - Type -
    -
    - -number - - -
    -
    - - - - - -
    - - - -
    -

    getTiles(x, y, width, height, collides) → {array}

    - - -
    -
    - - -
    -

    Get the tiles within the given area.

    +

    Get all tiles that exist within the given area, defined by the top-left corner, width and height. Values given are in pixels, not tiles.

    @@ -3707,8 +3486,12 @@ half as quickly as the 'normal' camera-locked layers do)

    Type + Argument + + Default + Description @@ -3732,10 +3515,22 @@ half as quickly as the 'normal' camera-locked layers do)

    + + + + + + -

    X position of the top left of the area to copy (given in tiles, not pixels)

    + + + + + + +

    X position of the top left corner.

    @@ -3755,10 +3550,22 @@ half as quickly as the 'normal' camera-locked layers do)

    + + + + + + -

    Y position of the top left of the area to copy (given in tiles, not pixels)

    + + + + + + +

    Y position of the top left corner.

    @@ -3778,10 +3585,22 @@ half as quickly as the 'normal' camera-locked layers do)

    + + + + + + -

    The width of the area to copy (given in tiles, not pixels)

    + + + + + + +

    Width of the area to get.

    @@ -3801,10 +3620,22 @@ half as quickly as the 'normal' camera-locked layers do)

    + + + + + + -

    The height of the area to copy (given in tiles, not pixels)

    + + + + + + +

    Height of the area to get.

    @@ -3824,7 +3655,23 @@ half as quickly as the 'normal' camera-locked layers do)

    + + + <optional>
    + + + + + + + + + + + false + +

    If true only return tiles that collide on one or more faces.

    @@ -3859,7 +3706,7 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    @@ -4000,7 +3847,7 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    @@ -4051,7 +3898,7 @@ half as quickly as the 'normal' camera-locked layers do)

    -

    getTileXY(x, y) → {Phaser.Tile}

    +

    getTileXY(x, y, point) → {Phaser.Point|object}

    @@ -4136,6 +3983,32 @@ half as quickly as the 'normal' camera-locked layers do)

    + + + + point + + + + + +Phaser.Point +| + +object + + + + + + + + + +

    The Point object to set the x and y values on.

    + + + @@ -4164,7 +4037,7 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    @@ -4189,7 +4062,7 @@ half as quickly as the 'normal' camera-locked layers do)

    -

    The tile with specific properties.

    +

    A Point object with its x and y properties set.

    @@ -4200,7 +4073,10 @@ half as quickly as the 'normal' camera-locked layers do)

    -Phaser.Tile +Phaser.Point +| + +object
    @@ -4305,7 +4181,7 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    @@ -4351,6 +4227,75 @@ half as quickly as the 'normal' camera-locked layers do)

    + + + + +
    +

    postUpdate()

    + + +
    +
    + + +
    +

    Automatically called by World.postUpdate. Handles cache updates.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + +
    @@ -4397,7 +4342,76 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    renderDebug()

    + + +
    +
    + + +
    +

    Renders a collision debug overlay on-top of the canvas. Called automatically by render when debug = true.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -4466,217 +4480,7 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    update()

    - - -
    -
    - - -
    -

    Automatically called by World.preUpdate. Handles cache updates.

    -
    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    updateMapData(tilemap, layer)

    - - -
    -
    - - -
    -

    Updates the Tilemap data.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    tilemap - - -Phaser.Tilemap - - - -

    The tilemap to which this layer belongs.

    layer - - -number - - - -

    The layer index within the map.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -4745,128 +4549,7 @@ half as quickly as the 'normal' camera-locked layers do)

    Source:
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    updateTileset(tileset)

    - - -
    -
    - - -
    -

    Updates the Tileset data.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    tileset - - -Phaser.Tileset -| - -string - - - -

    The tileset to use for this layer.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -4911,13 +4594,13 @@ half as quickly as the 'normal' camera-locked layers do)

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:34 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.TilemapParser.html b/docs/Phaser.TilemapParser.html index 71bfaf31..8da89b64 100644 --- a/docs/Phaser.TilemapParser.html +++ b/docs/Phaser.TilemapParser.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -523,7 +517,7 @@
    -

    <static> parse(game, data, format) → {Phaser.Tileset}

    +

    <static> parse(game, key) → {object}

    @@ -588,30 +582,7 @@ - data - - - - - -object - - - - - - - - - - - - - - - - - format + key @@ -627,7 +598,7 @@ - +

    The key of the tilemap in the Cache.

    @@ -659,7 +630,7 @@
    Source:
    @@ -684,7 +655,7 @@
    -

    Generated Tileset object.

    +

    The parsed map object.

    @@ -695,7 +666,7 @@
    -Phaser.Tileset +object
    @@ -800,7 +771,7 @@
    Source:
    @@ -851,7 +822,7 @@
    -

    <static> parseJSON(json-) → {object}

    +

    <static> parseJSON(json) → {object}

    @@ -893,7 +864,7 @@ - json- + json @@ -909,7 +880,7 @@ -

    The Tiled JSON data.

    +

    The JSON map data.

    @@ -941,7 +912,7 @@
    Source:
    @@ -966,7 +937,7 @@
    -

    Generated map data.

    +

    Generated and parsed map data.

    @@ -992,7 +963,7 @@
    -

    <static> tileset(game, key, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) → {Phaser.Tileset}

    +

    <static> tileset(game, key, tileWidth, tileHeight, tileMargin, tileSpacing, rows, columns, total) → {Phaser.Tileset}

    @@ -1022,8 +993,12 @@ Type + Argument + + Default + Description @@ -1047,7 +1022,19 @@ + + + + + + + + + + + +

    Game reference to the currently running game.

    @@ -1070,10 +1057,22 @@ + + + + + + - + + + + + + +

    The Cache key of this tileset.

    @@ -1093,10 +1092,22 @@ + + + + + + - + + + + + + +

    Width of each single tile in pixels.

    @@ -1116,33 +1127,22 @@ - - - - - - - - - - - tileMax - - - - + -number + - - - + + + + + + - +

    Height of each single tile in pixels.

    @@ -1162,10 +1162,26 @@ + + + <optional>
    + + + + + - + + + + 0 + + + + +

    If the tiles have been drawn with a margin, specify the amount here.

    @@ -1185,10 +1201,143 @@ + + + <optional>
    + + + + + - + + + + 0 + + + + +

    If the tiles have been drawn with spacing between them, specify the amount here.

    + + + + + + + rows + + + + + +number + + + + + + + + + <optional>
    + + + + + + + + + + + + -1 + + + + +

    How many tiles are placed horizontally in each row? If -1 it will calculate rows by dividing the image width by tileWidth.

    + + + + + + + columns + + + + + +number + + + + + + + + + <optional>
    + + + + + + + + + + + + -1 + + + + +

    How many tiles are placed vertically in each column? If -1 it will calculate columns by dividing the image height by tileHeight.

    + + + + + + + total + + + + + +number + + + + + + + + + <optional>
    + + + + + + + + + + + + -1 + + + + +

    The maximum number of tiles to extract from the image. If -1 it will extract rows * columns worth. You can also set a value lower than the actual number of tiles.

    @@ -1288,13 +1437,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:35 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Tileset.html b/docs/Phaser.Tileset.html index cd4e1e56..2a1cd745 100644 --- a/docs/Phaser.Tileset.html +++ b/docs/Phaser.Tileset.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -438,7 +432,7 @@
    -

    new Tileset(image, key, tileWidth, tileHeight, tileMargin, tileSpacing)

    +

    new Tileset(name, firstgid, width, height, margin, spacing, properties)

    @@ -446,7 +440,8 @@
    -

    A Tile set is a combination of an image containing the tiles and collision data per tile.

    +

    A Tile set is a combination of an image containing the tiles and collision data per tile. +You should not normally instantiate this class directly.

    @@ -468,8 +463,6 @@ Type - Argument - @@ -482,38 +475,7 @@ - image - - - - - -Image - - - - - - - - - - - - - - - - - -

    The Image object from the Cache.

    - - - - - - - key + name @@ -526,25 +488,17 @@ - - - - - - - - -

    The key of the tileset in the cache.

    +

    The name of the tileset in the map data.

    - tileWidth + firstgid @@ -557,25 +511,17 @@ - - - - - - - - -

    The width of the tile in pixels.

    +

    The Tiled firstgid value.

    - tileHeight + width @@ -588,25 +534,17 @@ - - - - - - - - -

    The height of the tile in pixels.

    +

    Width of each tile in pixels.

    - tileMargin + height @@ -619,27 +557,17 @@ - - - <optional>
    - - - - - - - -

    The margin around the tiles in the sheet.

    +

    Height of each tile in pixels.

    - tileSpacing + margin @@ -652,20 +580,56 @@ - - - <optional>
    - - + +

    The amount of margin around the tilesheet.

    + + + + + + + spacing + + + + - +number + + + + + -

    The spacing between the tiles in the sheet.

    +

    The amount of spacing between each tile in the sheet.

    + + + + + + + properties + + + + + +object + + + + + + + + + +

    Tileset properties.

    @@ -697,7 +661,7 @@
    Source:
    @@ -740,6 +704,213 @@
    +
    +

    columns

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    columns + + +number + + + +

    The number of columns in the tile sheet.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    firstgid

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    firstgid + + +number + + + +

    The Tiled firstgid value.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • firstgid
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + +

    image

    @@ -796,7 +967,7 @@ -

    The image used for rendering.

    +

    The image used for rendering. This is a reference to the image stored in Phaser.Cache.

    @@ -825,7 +996,7 @@
    Source:
    @@ -843,7 +1014,7 @@
    -

    key

    +

    name

    @@ -882,7 +1053,7 @@ - key + name @@ -898,7 +1069,7 @@ -

    The cache ID.

    +

    The name of the Tileset.

    @@ -927,7 +1098,7 @@
    Source:
    @@ -945,7 +1116,7 @@
    -

    margin

    +

    properties

    @@ -984,13 +1155,13 @@ - tileMargin + properties -number +object @@ -1000,7 +1171,7 @@ -

    The margin around the tiles in the sheet.

    +

    Tileset specific properties (typically defined in the Tiled editor).

    @@ -1029,7 +1200,7 @@
    Source:
    @@ -1047,7 +1218,7 @@
    -

    spacing

    +

    rows

    @@ -1086,7 +1257,7 @@ - tileSpacing + rows @@ -1102,7 +1273,7 @@ -

    The margin around the tiles in the sheet.

    +

    The number of rows in the tile sheet.

    @@ -1131,7 +1302,7 @@
    Source:
    @@ -1251,7 +1422,7 @@
    -

    tiles

    +

    tileMargin

    @@ -1290,13 +1461,13 @@ - tiles + tileMargin -array +number @@ -1306,7 +1477,7 @@ -

    An array of the tile collision data.

    +

    The margin around the tiles in the sheet.

    @@ -1335,7 +1506,109 @@
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    tileSpacing

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    tileSpacing + + +number + + + +

    The margin around the tiles in the sheet.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1455,7 +1728,7 @@
    -

    <readonly> total

    +

    total

    @@ -1510,7 +1783,7 @@ -

    The total number of tiles in this Tileset.

    +

    The total number of tiles in the tilesheet.

    @@ -1539,7 +1812,7 @@
    Source:
    @@ -1563,7 +1836,7 @@
    -

    addTile(tile)

    +

    <protected> calculateFaces(layer)

    @@ -1571,7 +1844,7 @@
    -

    Adds a Tile into this set.

    +

    Internal function.

    @@ -1605,125 +1878,7 @@ - tile - - - - - -Phaser.Tile - - - - - - - - - -

    The tile to add to this set.

    - - - - - - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    canCollide(index) → {boolean}

    - - -
    -
    - - -
    -

    Checks if the tile at the given index can collide.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - + + @@ -1771,7 +1926,7 @@
    Source:
    @@ -1792,29 +1947,6 @@ -
    Returns:
    - - -
    -

    True or false depending on the tile collision or null if no tile was found at the given index.

    -
    - - - -
    -
    - Type -
    -
    - -boolean - - -
    -
    - - - @@ -1912,7 +2044,7 @@
    Source:
    @@ -1937,7 +2069,11 @@
    -

    True if a tile exists at the given index otherwise false.

    +

    True if a tile exists at the given index otherwise false. + checkTileIndex: function (index) {

    +
        return (this.tiles[index]);
    +
    +}
    @@ -1963,7 +2099,1356 @@
    -

    getTile(index) → {Phaser.Tile}

    +

    createFromObjects(name, gid, key, frame, exists, autoCull, group)

    + + +
    +
    + + +
    +

    Creates a Sprite for every object matching the given gid in the map data. You can optionally specify the group that the Sprite will be created in. If none is +given it will be created in the World. All properties from the map data objectgroup are copied across to the Sprite, so you can use this as an easy way to +configure Sprite properties from within the map editor. For example giving an object a property if alpha: 0.5 in the map editor will duplicate that when the +Sprite is created. You could also give it a value like: body.velocity.x: 100 to set it moving automatically.

    +
    + + + + + + + +
    Parameters:
    + + +
    NameTypeDescription
    indexlayer @@ -1739,7 +1894,7 @@ -

    The index of the tile within the set.

    The index of the TilemapLayer to operate on.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    name + + +string + + + + + + + + + + + +

    The name of the Object Group to create Sprites from.

    gid + + +number + + + + + + + + + + + +

    The layer array index value, or if a string is given the layer name, within the map data that this TilemapLayer represents.

    key + + +string + + + + + + + + + + + +

    The Game.cache key of the image that this Sprite will use.

    frame + + +number +| + +string + + + + + + <optional>
    + + + + + +
    + +

    If the Sprite image contains multiple frames you can specify which one to use here.

    exists + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    The default exists state of the Sprite.

    autoCull + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    The default autoCull state of the Sprite. Sprites that are autoCulled are culled from the camera if out of its range.

    group + + +Phaser.Group + + + + + + <optional>
    + + + + + +
    + +

    Optional Group to add the Sprite to. If not specified it will be added to the World group.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    createLayer(layer, width, height, group) → {Phaser.TilemapLayer}

    + + +
    +
    + + +
    +

    Creates a new TilemapLayer object. By default TilemapLayers are fixed to the camera.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDescription
    layer + + +number +| + +string + + + + + + + + + +

    The layer array index value, or if a string is given the layer name, within the map data that this TilemapLayer represents.

    width + + +number + + + + + + <optional>
    + + + + + +

    The rendered width of the layer, should never be wider than Game.width. If not given it will be set to Game.width.

    height + + +number + + + + + + <optional>
    + + + + + +

    The rendered height of the layer, should never be wider than Game.height. If not given it will be set to Game.height.

    group + + +Phaser.Group + + + + + + <optional>
    + + + + + +

    Optional Group to add the object to. If not specified it will be added to the World group.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The TilemapLayer object. This is an extension of Phaser.Sprite and can be moved around the display list accordingly.

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.TilemapLayer + + +
    +
    + + + + + +
    + + + +
    +

    getImageIndex(name) → {number}

    + + +
    +
    + + +
    +

    Gets the image index based on its name.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    name + + +string + + + +

    The name of the image to get.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The index of the image in this tilemap, or null if not found.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    <protected> getIndex(location, name) → {number}

    + + +
    +
    + + +
    +

    Gets the layer index based on the layers name.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    location + + +array + + + +

    The local array to search.

    name + + +string + + + +

    The name of the array element to get.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The index of the element in the array, or null if not found.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    <protected> getLayer(layer) → {number}

    + + +
    +
    + + +
    +

    Gets the TilemapLayer index as used in the setCollision calls.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    layer + + +number +| + +string +| + +Phaser.TilemapLayer + + + +

    The layer to operate on. If not given will default to this.currentLayer.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The TilemapLayer index.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    getLayerIndex(name) → {number}

    + + +
    +
    + + +
    +

    Gets the layer index based on its name.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    name + + +string + + + +

    The name of the layer to get.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The index of the layer in this tilemap, or null if not found.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    getObjectIndex(name) → {number}

    + + +
    +
    + + +
    +

    Gets the object index based on its name.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    name + + +string + + + +

    The name of the object to get.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The index of the object in this tilemap, or null if not found.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    getTile(index) → {object}

    @@ -2053,7 +3538,7 @@
    Source:
    @@ -2078,7 +3563,11 @@
    -

    The tile.

    +

    The tile object. + getTile: function (index) {

    +
        return this.tiles[index];
    +
    +},
    @@ -2089,7 +3578,7 @@
    -Phaser.Tile +object
    @@ -2104,7 +3593,7 @@
    -

    setCollision(index, left, right, up, down)

    +

    getTileAbove(layer, x, y)

    @@ -2112,7 +3601,808 @@
    -

    Sets collision values on a tile in the set.

    +

    Gets the tile above the tile coordinates given. +Mostly used as an internal function by calculateFaces.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    layer + + +number + + + +

    The local layer index to get the tile from. Can be determined by Tilemap.getLayer().

    x + + +number + + + +

    The x coordinate to get the tile from. In tiles, not pixels.

    y + + +number + + + +

    The y coordinate to get the tile from. In tiles, not pixels.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    +

    getTileBelow(layer, x, y)

    + + +
    +
    + + +
    +

    Gets the tile below the tile coordinates given. +Mostly used as an internal function by calculateFaces.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    layer + + +number + + + +

    The local layer index to get the tile from. Can be determined by Tilemap.getLayer().

    x + + +number + + + +

    The x coordinate to get the tile from. In tiles, not pixels.

    y + + +number + + + +

    The y coordinate to get the tile from. In tiles, not pixels.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    getTileLeft(layer, x, y)

    + + +
    +
    + + +
    +

    Gets the tile to the left of the tile coordinates given. +Mostly used as an internal function by calculateFaces.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    layer + + +number + + + +

    The local layer index to get the tile from. Can be determined by Tilemap.getLayer().

    x + + +number + + + +

    The x coordinate to get the tile from. In tiles, not pixels.

    y + + +number + + + +

    The y coordinate to get the tile from. In tiles, not pixels.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    getTileRight(layer, x, y)

    + + +
    +
    + + +
    +

    Gets the tile to the right of the tile coordinates given. +Mostly used as an internal function by calculateFaces.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    layer + + +number + + + +

    The local layer index to get the tile from. Can be determined by Tilemap.getLayer().

    x + + +number + + + +

    The x coordinate to get the tile from. In tiles, not pixels.

    y + + +number + + + +

    The y coordinate to get the tile from. In tiles, not pixels.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    getTilesetIndex(name) → {number}

    + + +
    +
    + + +
    +

    Gets the tileset index based on its name.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    name + + +string + + + +

    The name of the tileset to get.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The index of the tileset in this tilemap, or null if not found.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    getTileX(index) → {object}

    + + +
    +
    + + +
    +

    Gets a Tile from this set.

    @@ -2166,98 +4456,6 @@ - - - - left - - - - - -boolean - - - - - - - - - -

    Should the tile collide on the left?

    - - - - - - - right - - - - - -boolean - - - - - - - - - -

    Should the tile collide on the right?

    - - - - - - - up - - - - - -boolean - - - - - - - - - -

    Should the tile collide on the top?

    - - - - - - - down - - - - - -boolean - - - - - - - - - -

    Should the tile collide on the bottom?

    - - - @@ -2286,7 +4484,7 @@
    Source:
    @@ -2307,6 +4505,33 @@ +
    Returns:
    + + +
    +

    The tile object. + getTileX: function (index) {

    +
        return this.tiles[index][0];
    +
    +},
    +
    + + + +
    +
    + Type +
    +
    + +object + + +
    +
    + + + @@ -2314,7 +4539,7 @@
    -

    setCollisionRange(start, stop, left, right, up, down)

    +

    getTileY(index) → {object}

    @@ -2322,7 +4547,7 @@
    -

    Sets collision values on a range of tiles in the set.

    +

    Gets a Tile from this set.

    @@ -2356,7 +4581,7 @@ - start + index @@ -2372,122 +4597,7 @@ -

    The index to start setting the collision data on.

    - - - - - - - stop - - - - - -number - - - - - - - - - -

    The index to stop setting the collision data on.

    - - - - - - - left - - - - - -boolean - - - - - - - - - -

    Should the tile collide on the left?

    - - - - - - - right - - - - - -boolean - - - - - - - - - -

    Should the tile collide on the right?

    - - - - - - - up - - - - - -boolean - - - - - - - - - -

    Should the tile collide on the top?

    - - - - - - - down - - - - - -boolean - - - - - - - - - -

    Should the tile collide on the bottom?

    +

    The index of the tile within the set.

    @@ -2519,7 +4629,974 @@
    Source:
    + + + + + + + + + + + + + + + + + + + +
    Returns:
    + + +
    +

    The tile object. + getTileY: function (index) {

    +
        return this.tiles[index][1];
    +
    +},
    +
    + + + +
    +
    + Type +
    +
    + +object + + +
    +
    + + + + + + + + + +
    +

    setCollision(indexes, collides, layer)

    + + +
    +
    + + +
    +

    Sets collision the given tile or tiles. You can pass in either a single numeric index or an array of indexes: [ 2, 3, 15, 20]. +The collides parameter controls if collision will be enabled (true) or disabled (false).

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    indexes + + +number +| + +array + + + + + + + + + + + +

    Either a single tile index, or an array of tile IDs to be checked for collision.

    collides + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true it will enable collision. If false it will clear collision.

    layer + + +number +| + +string +| + +Phaser.TilemapLayer + + + + + + <optional>
    + + + + + +
    + +

    The layer to operate on. If not given will default to this.currentLayer.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    setCollisionBetween(start, stop, collides, layer)

    + + +
    +
    + + +
    +

    Sets collision on a range of tiles where the tile IDs increment sequentially. +Calling this with a start value of 10 and a stop value of 14 would set collision for tiles 10, 11, 12, 13 and 14. +The collides parameter controls if collision will be enabled (true) or disabled (false).

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    start + + +number + + + + + + + + + + + +

    The first index of the tile to be set for collision.

    stop + + +number + + + + + + + + + + + +

    The last index of the tile to be set for collision.

    collides + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true it will enable collision. If false it will clear collision.

    layer + + +number +| + +string +| + +Phaser.TilemapLayer + + + + + + <optional>
    + + + + + +
    + +

    The layer to operate on. If not given will default to this.currentLayer.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    setCollisionByExclusion(indexes, collides, layer)

    + + +
    +
    + + +
    +

    Sets collision on all tiles in the given layer, except for the IDs of those in the given array. +The collides parameter controls if collision will be enabled (true) or disabled (false).

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    indexes + + +array + + + + + + + + + + + +

    An array of the tile IDs to not be counted for collision.

    collides + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true it will enable collision. If false it will clear collision.

    layer + + +number +| + +string +| + +Phaser.TilemapLayer + + + + + + <optional>
    + + + + + +
    + +

    The layer to operate on. If not given will default to this.currentLayer.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> setCollisionByIndex(index, collides, layer, recalculate)

    + + +
    +
    + + +
    +

    Sets collision values on a tile in the set. +You shouldn't usually call this method directly, instead use setCollision, setCollisionBetween or setCollisionByExclusion.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    index + + +number + + + + + + + + + + + +

    The index of the tile on the layer.

    collides + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    If true it will enable collision on the tile. If false it will clear collision values from the tile.

    layer + + +number + + + + + + <optional>
    + + + + + +
    + +

    The layer to operate on. If not given will default to this.currentLayer.

    recalculate + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    Recalculates the tile faces after the update.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -2682,7 +5759,565 @@
    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    setTileIndexCallback(indexes, callback, callbackContext, layer)

    + + +
    +
    + + +
    +

    Sets a global collision callback for the given tile index within the layer. This will affect all tiles on this layer that have the same index. +If a callback is already set for the tile index it will be replaced. Set the callback to null to remove it. +If you want to set a callback for a tile at a specific location on the map then see setTileLocationCallback.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDescription
    indexes + + +number +| + +array + + + + + + + + + +

    Either a single tile index, or an array of tile indexes to have a collision callback set for.

    callback + + +function + + + + + + + + + +

    The callback that will be invoked when the tile is collided with.

    callbackContext + + +object + + + + + + + + + +

    The context under which the callback is called.

    layer + + +number +| + +string +| + +Phaser.TilemapLayer + + + + + + <optional>
    + + + + + +

    The layer to operate on. If not given will default to this.currentLayer.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    setTileLocationCallback(x, y, width, height, callback, callbackContext, layer)

    + + +
    +
    + + +
    +

    Sets a global collision callback for the given tile index within the layer. This will affect all tiles on this layer that have the same index. +If a callback is already set for the tile index it will be replaced. Set the callback to null to remove it. +If you want to set a callback for a tile at a specific location on the map then see setTileLocationCallback.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDescription
    x + + +number + + + + + + + + + +

    X position of the top left of the area to copy (given in tiles, not pixels)

    y + + +number + + + + + + + + + +

    Y position of the top left of the area to copy (given in tiles, not pixels)

    width + + +number + + + + + + + + + +

    The width of the area to copy (given in tiles, not pixels)

    height + + +number + + + + + + + + + +

    The height of the area to copy (given in tiles, not pixels)

    callback + + +function + + + + + + + + + +

    The callback that will be invoked when the tile is collided with.

    callbackContext + + +object + + + + + + + + + +

    The context under which the callback is called.

    layer + + +number +| + +string +| + +Phaser.TilemapLayer + + + + + + <optional>
    + + + + + +

    The layer to operate on. If not given will default to this.currentLayer.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -2727,13 +6362,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:35 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Time.html b/docs/Phaser.Time.html index 137d9d1e..8daece68 100644 --- a/docs/Phaser.Time.html +++ b/docs/Phaser.Time.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -572,7 +566,7 @@
    -

    elapsed

    +

    <protected> elapsed

    @@ -627,7 +621,7 @@ -

    Elapsed time since the last frame.

    +

    Elapsed time since the last frame (in ms).

    @@ -656,7 +650,7 @@
    Source:
    @@ -674,7 +668,109 @@
    -

    fps

    +

    events

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    events + + +Phaser.Timer + + + +

    This is a Phaser.Timer object bound to the master clock to which you can add timed events.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <protected> fps

    @@ -758,7 +854,7 @@
    Source:
    @@ -860,7 +956,7 @@
    Source:
    @@ -962,7 +1058,7 @@
    Source:
    @@ -1064,7 +1160,7 @@
    Source:
    @@ -1268,7 +1364,7 @@
    Source:
    @@ -1370,7 +1466,7 @@
    Source:
    @@ -1475,7 +1571,7 @@
    Source:
    @@ -1493,7 +1589,7 @@
    -

    now

    +

    <protected> now

    @@ -1577,7 +1673,7 @@
    Source:
    @@ -1595,7 +1691,7 @@
    -

    pausedTime

    +

    <protected> pausedTime

    @@ -1679,7 +1775,7 @@
    Source:
    @@ -1781,7 +1877,7 @@
    Source:
    @@ -1883,7 +1979,7 @@
    Source:
    @@ -1901,7 +1997,7 @@
    -

    time

    +

    <protected> time

    @@ -1956,7 +2052,7 @@ -

    Game time counter.

    +

    Game time counter. If you need a value for in-game calculation please use Phaser.Time.now instead.

    @@ -1985,7 +2081,7 @@
    Source:
    @@ -2087,7 +2183,7 @@
    Source:
    @@ -2110,6 +2206,232 @@
    +
    +

    boot()

    + + +
    +
    + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    create(autoDestroy) → {Phaser.Timer}

    + + +
    +
    + + +
    +

    Creates a new stand-alone Phaser.Timer object.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    autoDestroy + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events).

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The Timer object that was created.

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.Timer + + +
    +
    + + + + + +
    + + +

    elapsedSecondsSince(since) → {number}

    @@ -2201,7 +2523,7 @@
    Source:
    @@ -2342,7 +2664,7 @@
    Source:
    @@ -2388,6 +2710,75 @@ +
    + + + +
    +

    removeAll()

    + + +
    +
    + + +
    +

    Remove all Timer objects, regardless of their state.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + +
    @@ -2434,7 +2825,7 @@
    Source:
    @@ -2503,7 +2894,7 @@
    Source:
    @@ -2640,7 +3031,7 @@
    Source:
    @@ -2685,13 +3076,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:35 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Timer.html b/docs/Phaser.Timer.html index fce8ebce..0457fc84 100644 --- a/docs/Phaser.Timer.html +++ b/docs/Phaser.Timer.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -427,7 +421,7 @@ Timer -

    A Timer

    +

    A Timer is a way to create small re-usable or disposable objects that do nothing but wait for a specific moment in time, and then dispatch an event.

    @@ -438,7 +432,7 @@
    -

    new Timer(game)

    +

    new Timer(game, autoDestroy)

    @@ -446,7 +440,9 @@
    -

    Timer constructor.

    +

    A Timer is a way to create small re-usable or disposable objects that do nothing but wait for a specific moment in time, and then dispatch an event. +You can add as many events to a Timer as you like, each with their own delays. A Timer uses milliseconds as its unit of time. There are 1000 ms in 1 second. +So if you want to fire an event every quarter of a second you'd need to set the delay to 250.

    @@ -468,8 +464,12 @@ Type + Argument + + Default + Description @@ -493,13 +493,64 @@ + + + + + + + + + + + +

    A reference to the currently running game.

    + + + + autoDestroy + + + + + +boolean + + + + + + + + + <optional>
    + + + + + + + + + + + + true + + + + +

    A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events).

    + + + @@ -528,7 +579,7 @@
    Source:
    @@ -571,6 +622,657 @@
    +
    +

    <static, constant> HALF :number

    + + +
    +
    + + + +
    Type:
    +
      +
    • + +number + + +
    • +
    + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <static, constant> MINUTE :number

    + + +
    +
    + + + +
    Type:
    +
      +
    • + +number + + +
    • +
    + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <static, constant> QUARTER :number

    + + +
    +
    + + + +
    Type:
    +
      +
    • + +number + + +
    • +
    + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <static, constant> SECOND :number

    + + +
    +
    + + + +
    Type:
    +
      +
    • + +number + + +
    • +
    + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    autoDestroy

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    autoDestroy + + +boolean + + + +

    A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events).

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> duration

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    duration + + +number + + + +

    The duration in ms remaining until the next event will occur.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    events

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    events + + +array.<Phaser.TimerEvent> + + + +

    An array holding all of this timers Phaser.TimerEvent objects. Use the methods add, repeat and loop to populate it.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> expired

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    expired + + +boolean + + + +

    An expired Timer is one in which all of its events have been dispatched and none are pending.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + +

    game

    @@ -656,7 +1358,829 @@
    Source:
    + + + + + + + +
    + + + + + + + +
    +

    <readonly> length

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    length + + +number + + + +

    The number of pending events in the queue.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> ms

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    ms + + +number + + + +

    The duration in milliseconds that this Timer has been running for.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> next

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    next + + +number + + + +

    The time at which the next event will occur.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <protected, readonly> nextTick

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    nextTick + + +number + + + +

    The time the next tick will occur.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    onComplete

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onComplete + + +Phaser.Signal + + + +

    This signal will be dispatched when this Timer has completed, meaning there are no more events in the queue.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> paused

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    paused + + +boolean + + + +

    The paused state of the Timer. You can pause the timer by calling Timer.pause() and Timer.resume() or by the game pausing.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    running

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    running + + +boolean + + + +

    True if the Timer is actively running. Do not switch this boolean, if you wish to pause the timer then use Timer.pause() instead.

    +
    + + + + + + + + + + + + + + + + + + +
    Default Value:
    +
    • false
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> seconds

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    seconds + + +number + + + +

    The duration in seconds that this Timer has been running for.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -675,6 +2199,1529 @@ +

    Methods

    + +
    + +
    +

    add(delay, callback, callbackContext, arguments) → {Phaser.TimerEvent}

    + + +
    +
    + + +
    +

    Adds a new Event to this Timer. The event will fire after the given amount of 'delay' in milliseconds has passed, once the Timer has started running. +Call Timer.start() once you have added all of the Events you require for this Timer. The delay is in relation to when the Timer starts, not the time it was added. +If the Timer is already running the delay will be calculated based on the timers current time.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDescription
    delay + + +number + + + + + + + + + +

    The number of milliseconds that should elapse before the Timer will call the given callback.

    callback + + +function + + + + + + + + + +

    The callback that will be called when the Timer event occurs.

    callbackContext + + +object + + + + + + + + + +

    The context in which the callback will be called.

    arguments + + +* + + + + + + + + + + <repeatable>
    + +

    The values to be sent to your callback function when it is called.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The Phaser.TimerEvent object that was created.

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.TimerEvent + + +
    +
    + + + + + +
    + + + +
    +

    destroy()

    + + +
    +
    + + +
    +

    Destroys this Timer. Events are not dispatched.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    loop(delay, callback, callbackContext, arguments) → {Phaser.TimerEvent}

    + + +
    +
    + + +
    +

    Adds a new looped Event to this Timer that will repeat forever or until the Timer is stopped. +The event will fire after the given amount of 'delay' milliseconds has passed once the Timer has started running. +Call Timer.start() once you have added all of the Events you require for this Timer. The delay is in relation to when the Timer starts, not the time it was added. +If the Timer is already running the delay will be calculated based on the timers current time.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDescription
    delay + + +number + + + + + + + + + +

    The number of milliseconds that should elapse before the Timer will call the given callback.

    callback + + +function + + + + + + + + + +

    The callback that will be called when the Timer event occurs.

    callbackContext + + +object + + + + + + + + + +

    The context in which the callback will be called.

    arguments + + +* + + + + + + + + + + <repeatable>
    + +

    The values to be sent to your callback function when it is called.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The Phaser.TimerEvent object that was created.

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.TimerEvent + + +
    +
    + + + + + +
    + + + +
    +

    order()

    + + +
    +
    + + +
    +

    Orders the events on this Timer so they are in tick order. This is called automatically when new events are created.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    pause()

    + + +
    +
    + + +
    +

    Pauses the Timer and all events in the queue.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    remove(event)

    + + +
    +
    + + +
    +

    Removes a pending TimerEvent from the queue.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    event + + +Phaser.TimerEvent + + + +

    The event to remove from the queue.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    repeat(delay, repeatCount, callback, callbackContext, arguments) → {Phaser.TimerEvent}

    + + +
    +
    + + +
    +

    Adds a new Event to this Timer that will repeat for the given number of iterations. +The event will fire after the given amount of 'delay' milliseconds has passed once the Timer has started running. +Call Timer.start() once you have added all of the Events you require for this Timer. The delay is in relation to when the Timer starts, not the time it was added. +If the Timer is already running the delay will be calculated based on the timers current time.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDescription
    delay + + +number + + + + + + + + + +

    The number of milliseconds that should elapse before the Timer will call the given callback.

    repeatCount + + +number + + + + + + + + + +

    The number of times the event will repeat.

    callback + + +function + + + + + + + + + +

    The callback that will be called when the Timer event occurs.

    callbackContext + + +object + + + + + + + + + +

    The context in which the callback will be called.

    arguments + + +* + + + + + + + + + + <repeatable>
    + +

    The values to be sent to your callback function when it is called.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The Phaser.TimerEvent object that was created.

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.TimerEvent + + +
    +
    + + + + + +
    + + + +
    +

    resume()

    + + +
    +
    + + +
    +

    Resumes the Timer and updates all pending events.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> sortHandler()

    + + +
    +
    + + +
    +

    Sort handler used by Phaser.Timer.order.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    start()

    + + +
    +
    + + +
    +

    Starts this Timer running.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    stop()

    + + +
    +
    + + +
    +

    Stops this Timer from running. Does not cause it to be destroyed if autoDestroy is set to true.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> update(time) → {boolean}

    + + +
    +
    + + +
    +

    The main Timer update event, called automatically by the Game clock.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    time + + +number + + + +

    The time from the core game clock.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if there are still events waiting to be dispatched, otherwise false if this Timer can be destroyed.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + +
    + @@ -693,13 +3740,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:35 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.TimerEvent.html b/docs/Phaser.TimerEvent.html new file mode 100644 index 00000000..ca35f0e0 --- /dev/null +++ b/docs/Phaser.TimerEvent.html @@ -0,0 +1,1616 @@ + + + + + + Phaser Class: TimerEvent + + + + + + + + + + +
    + + +
    + + +
    + +
    + + + +

    Class: TimerEvent

    +
    + +
    +

    + Phaser. + + TimerEvent +

    + +

    A TimerEvent is a single event that is processed by a Phaser.Timer. It consists of a delay, which is a value in milliseconds after which the event will fire.

    + +
    + +
    +
    + + + + +
    +

    new TimerEvent(timer, delay, tick, repeatCount, loop, callback, callbackContext, arguments)

    + + +
    +
    + + +
    +

    A TimerEvent is a single event that is processed by a Phaser.Timer. It consists of a delay, which is a value in milliseconds after which the event will fire. +It can call a specific callback, passing in optional parameters.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    timer + + +Phaser.Timer + + + +

    The Timer object that this TimerEvent belongs to.

    delay + + +number + + + +

    The delay in ms at which this TimerEvent fires.

    tick + + +number + + + +

    The tick is the next game clock time that this event will fire at.

    repeatCount + + +number + + + +

    If this TimerEvent repeats it will do so this many times.

    loop + + +boolean + + + +

    True if this TimerEvent loops, otherwise false.

    callback + + +function + + + +

    The callback that will be called when the TimerEvent occurs.

    callbackContext + + +object + + + +

    The context in which the callback will be called.

    arguments + + +array + + + +

    The values to be passed to the callback.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + +
    + + + + + + + + + + + + +

    Members

    + +
    + +
    +

    args

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    arguments + + +array + + + +

    The values to be passed to the callback.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    callback

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    callback + + +function + + + +

    The callback that will be called when the TimerEvent occurs.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    callbackContext

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    callbackContext + + +object + + + +

    The context in which the callback will be called.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    delay

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    delay + + +number + + + +

    The delay in ms at which this TimerEvent fires.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    loop

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    loop + + +boolean + + + +

    True if this TimerEvent loops, otherwise false.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    repeatCount

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    repeatCount + + +number + + + +

    If this TimerEvent repeats it will do so this many times.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    tick

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    tick + + +number + + + +

    The tick is the next game clock time that this event will fire at.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    timer

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    timer + + +Phaser.Timer + + + +

    The Timer object that this TimerEvent belongs to.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + +
    + + + + + + + +
    + +
    + + + + +
    + +
    +
    + + + + Phaser Copyright © 2012-2014 Photon Storm Ltd. + +
    + + + Documentation generated by JSDoc 3.3.0-dev + on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template. + +
    +
    + + +
    +
    +
    + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/docs/Phaser.Touch.html b/docs/Phaser.Touch.html index f91cd182..0bcca464 100644 --- a/docs/Phaser.Touch.html +++ b/docs/Phaser.Touch.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -831,7 +825,7 @@ -

    The browser touch event.

    +

    The browser touch DOM event. Will be set to null if no touch event has ever been received.

    @@ -856,11 +850,14 @@ +
    Default Value:
    +
    • null
    +
    Source:
    @@ -1744,7 +1741,7 @@
    Source:
    @@ -1863,7 +1860,7 @@ Occurs for example on iOS when you put down 4 fingers and the app selector UI ap
    Source:
    @@ -1981,7 +1978,7 @@ Occurs for example on iOS when you put down 4 fingers and the app selector UI ap
    Source:
    @@ -2100,7 +2097,7 @@ Doesn't appear to be supported by most browsers on a canvas element yet.

    Source:
    @@ -2219,7 +2216,7 @@ Doesn't appear to be supported by most browsers on a canvas element yet.

    Source:
    @@ -2337,7 +2334,7 @@ Doesn't appear to be supported by most browsers on a canvas element yet.

    Source:
    @@ -2455,7 +2452,7 @@ Doesn't appear to be supported by most browsers on a canvas element yet.

    Source:
    @@ -2524,7 +2521,7 @@ Doesn't appear to be supported by most browsers on a canvas element yet.

    Source:
    @@ -2593,7 +2590,7 @@ Doesn't appear to be supported by most browsers on a canvas element yet.

    Source:
    @@ -2638,13 +2635,13 @@ Doesn't appear to be supported by most browsers on a canvas element yet.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:35 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Tween.html b/docs/Phaser.Tween.html index c5c498ce..1730684c 100644 --- a/docs/Phaser.Tween.html +++ b/docs/Phaser.Tween.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -753,7 +747,7 @@ Create a new <code>Tween</code>.

    -

    Description.

    +

    If the tween is running this is set to true, otherwise false. Tweens that are in a delayed state, waiting to start, are considered as being running.

    @@ -785,7 +779,7 @@ Create a new <code>Tween</code>.

    Source:
    @@ -858,7 +852,7 @@ Create a new <code>Tween</code>.

    -

    Description.

    +

    The onComplete event is fired when the Tween completes. Does not fire if the Tween is set to loop.

    @@ -887,7 +881,109 @@ Create a new <code>Tween</code>.

    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    onLoop

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    onLoop + + +Phaser.Signal + + + +

    The onLoop event is fired if the Tween loops.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -960,7 +1056,7 @@ Create a new <code>Tween</code>.

    -

    Description.

    +

    The onStart event is fired when the Tween begins.

    @@ -989,7 +1085,7 @@ Create a new <code>Tween</code>.

    Source:
    @@ -1094,7 +1190,7 @@ Create a new <code>Tween</code>.

    Source:
    @@ -1160,7 +1256,7 @@ You can pass as many tweens as you like to this function, they will each be chai
    Source:
    @@ -1301,7 +1397,7 @@ You can pass as many tweens as you like to this function, they will each be chai
    Source:
    @@ -1442,7 +1538,7 @@ You can pass as many tweens as you like to this function, they will each be chai
    Source:
    @@ -1501,7 +1597,8 @@ You can pass as many tweens as you like to this function, they will each be chai
    -

    Set interpolation function the tween will use, by default it uses Phaser.Math.linearInterpolation.

    +

    Set interpolation function the tween will use, by default it uses Phaser.Math.linearInterpolation. +Also available: Phaser.Math.bezierInterpolation and Phaser.Math.catmullRomInterpolation.

    @@ -1583,7 +1680,7 @@ You can pass as many tweens as you like to this function, they will each be chai
    Source:
    @@ -1681,289 +1778,7 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true)
    Source:
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    Itself.

    -
    - - - -
    -
    - Type -
    -
    - -Phaser.Tween - - -
    -
    - - - - - -
    - - - -
    -

    onCompleteCallback(callback) → {Phaser.Tween}

    - - -
    -
    - - -
    -

    Sets a callback to be fired when the tween completes. Note: callback will be called in the context of the global scope.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    callback - - -function - - - -

    The callback to invoke on completion.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - -
    Returns:
    - - -
    -

    Itself.

    -
    - - - -
    -
    - Type -
    -
    - -Phaser.Tween - - -
    -
    - - - - - -
    - - - -
    -

    onStartCallback(callback) → {Phaser.Tween}

    - - -
    -
    - - -
    -

    Sets a callback to be fired when the tween starts. Note: callback will be called in the context of the global scope.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    callback - - -function - - - -

    The callback to invoke on start.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -2104,7 +1919,7 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true)
    Source:
    @@ -2196,7 +2011,7 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true)
    Source:
    @@ -2314,7 +2129,7 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true)
    Source:
    @@ -2406,7 +2221,7 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true)
    Source:
    @@ -2475,7 +2290,7 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true)
    Source:
    @@ -2567,7 +2382,7 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true)
    Source:
    @@ -2618,7 +2433,7 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true)
    -

    to(properties, duration, ease, autoStart, delay, repeat, yoyo) → {Phaser.Tween}

    +

    to(properties, duration, ease, autoStart, delay, repeat, yoyo) → {Phaser.Tween}

    @@ -2648,8 +2463,12 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true) Type + Argument + + Default + Description @@ -2673,7 +2492,19 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true) + + + + + + + + + + + +

    Properties you want to tween.

    @@ -2696,10 +2527,26 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true) + + + <optional>
    + + + + + -

    Duration of this tween.

    + + + + 1000 + + + + +

    Duration of this tween in ms.

    @@ -2719,10 +2566,26 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true) + + + <optional>
    + + + + + -

    Easing function.

    + + + + null + + + + +

    Easing function. If not set it will default to Phaser.Easing.Linear.None.

    @@ -2742,7 +2605,23 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true) + + + <optional>
    + + + + + + + + + + + false + +

    Whether this tween will start automatically or not.

    @@ -2765,10 +2644,26 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true) + + + <optional>
    + + + + + -

    Delay before this tween will start, defaults to 0 (no delay).

    + + + + 0 + + + + +

    Delay before this tween will start, defaults to 0 (no delay). Value given is in ms.

    @@ -2788,7 +2683,23 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true) + + + <optional>
    + + + + + + + + + + + 0 + +

    Should the tween automatically restart once complete? (ignores any chained tweens).

    @@ -2804,17 +2715,33 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true) -Phaser.Tween +boolean + + + <optional>
    + + + + + -

    Description.

    + + + + false + + + + +

    A tween that yoyos will reverse itself when it completes.

    @@ -2846,7 +2773,7 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true)
    Source:
    @@ -2871,7 +2798,7 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true)
    -

    Itself.

    +

    This Tween object.

    @@ -2987,7 +2914,7 @@ game.add.tween(p).to({ x: 700 }, 1000, Phaser.Easing.Linear.None, true)
    Source:
    @@ -3129,7 +3056,7 @@ Used in combination with repeat you can create endless loops.

    Source:
    @@ -3197,13 +3124,13 @@ Used in combination with repeat you can create endless loops.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:35 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.TweenManager.html b/docs/Phaser.TweenManager.html index c78babfb..93737650 100644 --- a/docs/Phaser.TweenManager.html +++ b/docs/Phaser.TweenManager.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -670,115 +664,6 @@ Please see https://github.com/sole/tw -
    - - - -
    - - - -
    -

    REVISION

    - - -
    -
    - -
    -

    Version number of this library.

    -
    - - - - - -
    - - -
    Properties:
    - -
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    REVISION - - -string - - - -
    -
    - - - - - - - - - - - - - - - - - - -
    Default Value:
    -
    • "11dev"
    - - - -
    Source:
    -
    - - - - - - -
    @@ -884,7 +769,7 @@ Please see https://github.com/sole/tw
    Source:
    @@ -1025,7 +910,7 @@ Please see https://github.com/sole/tw
    Source:
    @@ -1117,7 +1002,7 @@ Please see https://github.com/sole/tw
    Source:
    @@ -1258,7 +1143,7 @@ Please see https://github.com/sole/tw
    Source:
    @@ -1399,7 +1284,7 @@ Please see https://github.com/sole/tw
    Source:
    @@ -1435,7 +1320,7 @@ Please see https://github.com/sole/tw
    -

    Remove all tween objects.

    +

    Remove all tweens running and in the queue. Doesn't call any of the tween onComplete events.

    @@ -1468,7 +1353,7 @@ Please see
    https://github.com/sole/tw
    Source:
    @@ -1537,7 +1422,7 @@ Please see https://github.com/sole/tw
    Source:
    @@ -1606,7 +1491,7 @@ Please see https://github.com/sole/tw
    Source:
    @@ -1698,7 +1583,7 @@ Please see https://github.com/sole/tw
    Source:
    @@ -1743,13 +1628,13 @@ Please see https://github.com/sole/tw - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by
    JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:35 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Utils.Debug.html b/docs/Phaser.Utils.Debug.html index 0159e5d0..f4c4033c 100644 --- a/docs/Phaser.Utils.Debug.html +++ b/docs/Phaser.Utils.Debug.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -572,6 +566,108 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    +
    +

    columnWidth

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    columnWidth + + +number + + + +

    The spacing between columns.

    +
    + + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + +

    context

    @@ -762,7 +858,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -867,7 +963,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -972,7 +1068,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -1281,7 +1377,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -1383,7 +1479,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -1407,7 +1503,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    -

    line(text, x, y)

    +

    line(text, x, y)

    @@ -1437,6 +1533,8 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL Type + Argument + @@ -1462,6 +1560,14 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL + + + + + + + + @@ -1485,6 +1591,16 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL + + + <optional>
    + + + + + + + @@ -1508,6 +1624,16 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL + + + <optional>
    + + + + + + + @@ -1543,7 +1669,250 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    + + + + + + + +
    + + + + + + + + + + + + + + + + + +
    +

    renderBodyInfo(sprite, x, y, color)

    + + +
    +
    + + +
    +

    Render Sprite Body Physics Data as text.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    sprite + + +Phaser.Sprite + + + + + + + + + + + +

    The sprite to be rendered.

    x + + +number + + + + + + + + + + + +

    X position of the debug info to be rendered.

    y + + +number + + + + + + + + + + + +

    Y position of the debug info to be rendered.

    color + + +string + + + + + + <optional>
    + + + + + +
    + + 'rgb(255,255,255)' + +

    color of the debug info to be rendered. (format is css color string).

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1786,7 +2155,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -1947,7 +2316,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -2155,7 +2524,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -2183,7 +2552,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    -

    renderLocalTransformInfo(sprite, x, y, color)

    +

    renderLine(line, color)

    @@ -2191,7 +2560,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    -

    Render the Local Transform information of the given Sprite.

    +

    Renders a Line object in the given color.

    @@ -2229,13 +2598,13 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL - sprite + line -Phaser.Sprite +Phaser.Line @@ -2257,7 +2626,180 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL -

    Description.

    +

    The Line to render.

    + + + + + + + color + + + + + +string + + + + + + + + + <optional>
    + + + + + + + + + + + + 'rgb(255,255,255)' + + + + +

    color of the debug info to be rendered. (format is css color string).

    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    renderLineInfo(line, x, y, color)

    + + +
    +
    + + +
    +

    Renders Line information in the given color.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -2398,7 +2940,176 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    renderPhysicsBody(body, color)

    + + +
    +
    + + + + + + + + +
    Parameters:
    + + +
    NameTypeArgumentDefaultDescription
    line + + +Phaser.Line + + + + + + + + + + + +

    The Line to render.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    body + + +array + + + + + + + + + + + +
    color + + +string + + + + + + <optional>
    + + + + + +
    + + 'rgb(255,255,255)' + +

    The color the polygon is stroked in.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -2590,7 +3301,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -2751,7 +3462,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -3041,7 +3752,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -3284,7 +3995,176 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    renderPolygon(polygon, color)

    + + +
    +
    + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    polygon + + +array + + + + + + + + + + + +
    color + + +string + + + + + + <optional>
    + + + + + +
    + + 'rgb(255,255,255)' + +

    The color the polygon is stroked in.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -3425,7 +4305,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -3586,7 +4466,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -3829,168 +4709,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    renderSpriteBody(sprite, color)

    - - -
    -
    - - -
    -

    Renders just the Sprite.body bounds.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeArgumentDescription
    sprite - - -Phaser.Sprite - - - - - - - - - -

    Description.

    color - - -string - - - - - - <optional>
    - - - - - -

    Color of the debug info to be rendered (format is css color string).

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -4200,7 +4919,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -4228,7 +4947,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    -

    renderSpriteCollision(sprite, x, y, color)

    +

    renderSpriteBounds(sprite, color, fill)

    @@ -4236,7 +4955,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    -

    Render Sprite collision.

    +

    Renders just the full Sprite bounds.

    @@ -4302,7 +5021,217 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL -

    The sprite to be rendered.

    +

    Description.

    + + + + + + + color + + + + + +string + + + + + + + + + <optional>
    + + + + + + + + + + + + + + +

    Color of the debug info to be rendered (format is css color string).

    + + + + + + + fill + + + + + +boolean + + + + + + + + + <optional>
    + + + + + + + + + + + + false + + + + +

    If false the bounds outline is rendered, if true the whole rectangle is rendered.

    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    renderSpriteCoords(line, x, y, color)

    + + +
    +
    + + +
    +

    Renders the sprite coordinates in local, positional and world space.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -4443,7 +5372,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -4694,7 +5623,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -4937,7 +5866,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -5180,7 +6109,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -5434,7 +6363,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -5462,7 +6391,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    -

    renderWorldTransformInfo(sprite, x, y, color)

    +

    splitline(text)

    @@ -5470,7 +6399,125 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    -

    Render the World Transform information of the given Sprite.

    +

    Internal method that outputs a single line of text split over as many columns as needed, one per parameter.

    +
    + + + + + + + +
    Parameters:
    + + +
    NameTypeArgumentDefaultDescription
    line + + +Phaser.Sprite + + + + + + + + + + + +

    The sprite to inspect.

    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    text + + +string + + + +

    The text to render. You can have as many columns of text as you want, just pass them as additional parameters.

    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    start(x, y, color, columnWidth)

    + + +
    +
    + + +
    +

    Internal method that resets and starts the debug output values.

    @@ -5506,41 +6553,6 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL - - - sprite - - - - - -Phaser.Sprite - - - - - - - - - - - - - - - - - - - - - -

    Description.

    - - - - x @@ -5558,6 +6570,8 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL + <optional>
    + @@ -5568,10 +6582,12 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL + 0 + -

    X position of the debug info to be rendered.

    +

    The X value the debug info will start from.

    @@ -5593,6 +6609,8 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL + <optional>
    + @@ -5603,10 +6621,12 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL + 0 + -

    Y position of the debug info to be rendered.

    +

    The Y value the debug info will start from.

    @@ -5645,7 +6665,46 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL -

    color of the debug info to be rendered. (format is css color string).

    +

    The color the debug text will drawn in.

    + + + + + + + columnWidth + + + + + +number + + + + + + + + + <optional>
    + + + + + + + + + + + + 0 + + + + +

    The spacing between columns.

    @@ -5677,171 +6736,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    - - - - - - - -
    - - - - - - - - - - - - - - - - - -
    -

    start(x, y, color)

    - - -
    -
    - - -
    -

    Internal method that resets and starts the debug output values.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeDescription
    x - - -number - - - -

    The X value the debug info will start from.

    y - - -number - - - -

    The Y value the debug info will start from.

    color - - -string - - - -

    The color the debug info will drawn in.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    @@ -5910,7 +6805,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
    Source:
    @@ -5955,13 +6850,13 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:36 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.Utils.html b/docs/Phaser.Utils.html index 9297b0dc..840f9c11 100644 --- a/docs/Phaser.Utils.html +++ b/docs/Phaser.Utils.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -1259,13 +1253,13 @@ dir = 1 (left), 2 (right), 3 (both)

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:35 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.World.html b/docs/Phaser.World.html index 47136911..2328e0fa 100644 --- a/docs/Phaser.World.html +++ b/docs/Phaser.World.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -531,7 +525,7 @@ the world at world-based coordinates. By default a world is created the same siz
    Source:
    @@ -560,6 +554,12 @@ the world at world-based coordinates. By default a world is created the same siz +

    Extends

    + + + @@ -574,6 +574,335 @@ the world at world-based coordinates. By default a world is created the same siz
    +
    +

    alive

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    alive + + +boolean + + + +

    The alive property is useful for Groups that are children of other Groups and need to be included/excluded in checks like forEachAlive.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + +
    Default Value:
    +
    • true
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    alpha

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    alpha + + +number + + + +

    The alpha value of the Group container.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    angle

    + + +
    +
    + +
    +

    The angle of rotation of the Group container. This will adjust the Group container itself by modifying its rotation. +This will have no impact on the rotation value of its children, but it will update their worldTransform and on-screen position.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    angle + + +number + + + +

    The angle of rotation given in degrees, where 0 degrees = to the right.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + +

    bounds

    @@ -666,7 +995,7 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    @@ -768,7 +1097,7 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    @@ -870,7 +1199,7 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    @@ -972,7 +1301,7 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    @@ -1074,7 +1403,443 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    cursor

    + + +
    +
    + +
    +

    The cursor is a simple way to iterate through the objects in a Group using the Group.next and Group.previous functions. +The cursor is set to the first child added to the Group and doesn't change unless you call next, previous or set it directly with Group.cursor.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    cursor + + +any + + + +

    The current display object that the Group cursor is pointing to.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    exists

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    exists + + +boolean + + + +

    If exists is true the the Group is updated, otherwise it is skipped.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + +
    Default Value:
    +
    • true
    + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    game

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    game + + +Phaser.Game + + + +

    A reference to the currently running Game.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    group

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    group + + +Phaser.Group + + + +

    The parent Group of this Group, if a child of another.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    @@ -1176,7 +1941,328 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> length

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    length + + +number + + + +

    The total number of children in this Group, regardless of their exists/alive status.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    name

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    name + + +string + + + +

    A name for this Group. Not used internally but useful for debugging.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    pivot

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    pivot + + +Phaser.Point + + + +

    The pivot point of the Group container.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    @@ -1278,7 +2364,7 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    @@ -1380,7 +2466,119 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    rotation

    + + +
    +
    + +
    +

    The angle of rotation of the Group container. This will adjust the Group container itself by modifying its rotation. +This will have no impact on the rotation value of its children, but it will update their worldTransform and on-screen position.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    rotation + + +number + + + +

    The angle of rotation given in radians.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    @@ -1453,7 +2651,7 @@ So if you want to make a game in which the world itself will rotate you should a -

    Replaces the PIXI.Point with a slightly more flexible one.

    +

    The scane of the Group container.

    @@ -1468,6 +2666,11 @@ So if you want to make a game in which the world itself will rotate you should a +
    Inherited From:
    +
    + @@ -1482,7 +2685,221 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    <readonly> total

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    total + + +number + + + +

    The total number of children in this Group who have a state of exists = true.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    <protected> type

    + + +
    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    type + + +number + + + +

    Internal Phaser Type value.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    @@ -1584,7 +3001,7 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    @@ -1686,7 +3103,231 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    + + + + + + + +
    + + + +
    + + + +
    +

    x

    + + +
    +
    + +
    +

    The x coordinate of the Group container. You can adjust the Group container itself by modifying its coordinates. +This will have no impact on the x/y coordinates of its children, but it will update their worldTransform and on-screen position.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    x + + +number + + + +

    The x coordinate of the Group container.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + +
    + + + +
    +

    y

    + + +
    +
    + +
    +

    The y coordinate of the Group container. You can adjust the Group container itself by modifying its coordinates. +This will have no impact on the x/y coordinates of its children, but it will update their worldTransform and on-screen position.

    +
    + + + + + +
    + + +
    Properties:
    + +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    y + + +number + + + +

    The y coordinate of the Group container.

    +
    + + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    @@ -1709,6 +3350,526 @@ So if you want to make a game in which the world itself will rotate you should a
    +
    +

    add(child) → {*}

    + + +
    +
    + + +
    +

    Adds an existing object to this Group. The object can be an instance of Phaser.Sprite, Phaser.Button or any other display object. +The child is automatically added to the top of the Group, so renders on-top of everything else within the Group. If you need to control +that then see the addAt method.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    child + + +* + + + +

    An instance of Phaser.Sprite, Phaser.Button or any other display object..

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + +
    See:
    +
    + +
    + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The child that was added to the Group.

    +
    + + + +
    +
    + Type +
    +
    + +* + + +
    +
    + + + + + +
    + + + +
    +

    addAll(property, amount, checkAlive, checkVisible)

    + + +
    +
    + + +
    +

    Adds the amount to the given property on all children in this Group. +Group.addAll('x', 10) will add 10 to the child.x value.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    property + + +string + + + +

    The property to increment, for example 'body.velocity.x' or 'angle'.

    amount + + +number + + + +

    The amount to increment the property by. If child.x = 10 then addAll('x', 40) would make child.x = 50.

    checkAlive + + +boolean + + + +

    If true the property will only be changed if the child is alive.

    checkVisible + + +boolean + + + +

    If true the property will only be changed if the child is visible.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    addAt(child, index) → {*}

    + + +
    +
    + + +
    +

    Adds an existing object to this Group. The object can be an instance of Phaser.Sprite, Phaser.Button or any other display object. +The child is added to the Group at the location specified by the index value, this allows you to control child ordering.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    child + + +* + + + +

    An instance of Phaser.Sprite, Phaser.Button or any other display object..

    index + + +number + + + +

    The index within the Group to insert the child to.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The child that was added to the Group.

    +
    + + + +
    +
    + Type +
    +
    + +* + + +
    +
    + + + + + +
    + + +

    <protected> boot()

    @@ -1751,7 +3912,1571 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    bringToTop(child) → {*}

    + + +
    +
    + + +
    +

    Brings the given child to the top of this Group so it renders above all other children.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    child + + +* + + + +

    The child to bring to the top of this Group.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The child that was moved.

    +
    + + + +
    +
    + Type +
    +
    + +* + + +
    +
    + + + + + +
    + + + +
    +

    callAll(method, context, parameter)

    + + +
    +
    + + +
    +

    Calls a function on all of the children regardless if they are dead or alive (see callAllExists if you need control over that) +After the method parameter and context you can add as many extra parameters as you like, which will all be passed to the child.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    method + + +string + + + + + + + + + + + +

    A string containing the name of the function that will be called. The function must exist on the child.

    context + + +string + + + + + + <optional>
    + + + + + +
    + + null + +

    A string containing the context under which the method will be executed. Set to null to default to the child.

    parameter + + +* + + + + + + + + + + <repeatable>
    + +
    + +

    Additional parameters that will be passed to the method.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    callAllExists(callback, existsValue, parameter)

    + + +
    +
    + + +
    +

    Calls a function on all of the children that have exists=true in this Group. +After the existsValue parameter you can add as many parameters as you like, which will all be passed to the child callback.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDescription
    callback + + +function + + + + + + + + + +

    The function that exists on the children that will be called.

    existsValue + + +boolean + + + + + + + + + +

    Only children with exists=existsValue will be called.

    parameter + + +* + + + + + + + + + + <repeatable>
    + +

    Additional parameters that will be passed to the callback.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    <protected> callbackFromArray(child, callback, length)

    + + +
    +
    + + +
    +

    Returns a reference to a function that exists on a child of the Group based on the given callback array.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    child + + +object + + + +

    The object to inspect.

    callback + + +array + + + +

    The array of function names.

    length + + +number + + + +

    The size of the array (pre-calculated in callAll).

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    childTest()

    + + +
    +
    + + +
    +

    Internal test.

    +
    + + + + + + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    countDead() → {number}

    + + +
    +
    + + +
    +

    Call this function to find out how many members of the group are dead.

    +
    + + + + + + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The number of children flagged as dead.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    countLiving() → {number}

    + + +
    +
    + + +
    +

    Call this function to find out how many members of the group are alive.

    +
    + + + + + + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The number of children flagged as alive.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    create(x, y, key, frame, exists) → {Phaser.Sprite}

    + + +
    +
    + + +
    +

    Automatically creates a new Phaser.Sprite object and adds it to the top of this Group. +Useful if you don't need to create the Sprite instances before-hand.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    x + + +number + + + + + + + + + + + +

    The x coordinate to display the newly created Sprite at. The value is in relation to the Group.x point.

    y + + +number + + + + + + + + + + + +

    The y coordinate to display the newly created Sprite at. The value is in relation to the Group.y point.

    key + + +string + + + + + + + + + + + +

    The Game.cache key of the image that this Sprite will use.

    frame + + +number +| + +string + + + + + + <optional>
    + + + + + +
    + +

    If the Sprite image contains multiple frames you can specify which one to use here.

    exists + + +boolean + + + + + + <optional>
    + + + + + +
    + + true + +

    The default exists state of the Sprite.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The child that was created.

    +
    + + + +
    +
    + Type +
    +
    + +Phaser.Sprite + + +
    +
    + + + + + +
    + + + +
    +

    createMultiple(quantity, key, frame, exists)

    + + +
    +
    + + +
    +

    Automatically creates multiple Phaser.Sprite objects and adds them to the top of this Group. +Useful if you need to quickly generate a pool of identical sprites, such as bullets. By default the sprites will be set to not exist +and will be positioned at 0, 0 (relative to the Group.x/y)

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    quantity + + +number + + + + + + + + + + + +

    The number of Sprites to create.

    key + + +string + + + + + + + + + + + +

    The Game.cache key of the image that this Sprite will use.

    frame + + +number +| + +string + + + + + + <optional>
    + + + + + +
    + +

    If the Sprite image contains multiple frames you can specify which one to use here.

    exists + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    The default exists state of the Sprite.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    @@ -1820,7 +5545,2196 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    divideAll(property, amount, checkAlive, checkVisible)

    + + +
    +
    + + +
    +

    Divides the given property by the amount on all children in this Group. +Group.divideAll('x', 2) will half the child.x value.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    property + + +string + + + +

    The property to divide, for example 'body.velocity.x' or 'angle'.

    amount + + +number + + + +

    The amount to divide the property by. If child.x = 100 then divideAll('x', 2) would make child.x = 50.

    checkAlive + + +boolean + + + +

    If true the property will only be changed if the child is alive.

    checkVisible + + +boolean + + + +

    If true the property will only be changed if the child is visible.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    forEach(callback, callbackContext, checkExists)

    + + +
    +
    + + +
    +

    Allows you to call your own function on each member of this Group. You must pass the callback and context in which it will run. +After the checkExists parameter you can add as many parameters as you like, which will all be passed to the callback along with the child. +For example: Group.forEach(awardBonusGold, this, true, 100, 500) +Note: Currently this will skip any children which are Groups themselves.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    callback + + +function + + + +

    The function that will be called. Each child of the Group will be passed to it as its first parameter.

    callbackContext + + +Object + + + +

    The context in which the function should be called (usually 'this').

    checkExists + + +boolean + + + +

    If set only children with exists=true will be passed to the callback, otherwise all children will be passed.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    forEachAlive(callback, callbackContext)

    + + +
    +
    + + +
    +

    Allows you to call your own function on each alive member of this Group (where child.alive=true). You must pass the callback and context in which it will run. +You can add as many parameters as you like, which will all be passed to the callback along with the child. +For example: Group.forEachAlive(causeDamage, this, 500)

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    callback + + +function + + + +

    The function that will be called. Each child of the Group will be passed to it as its first parameter.

    callbackContext + + +Object + + + +

    The context in which the function should be called (usually 'this').

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    forEachAlive(callback, callbackContext)

    + + +
    +
    + + +
    +

    Allows you to call your own function on each alive member of this Group (where child.alive=true). You must pass the callback and context in which it will run. +You can add as many parameters as you like, which will all be passed to the callback along with the child. +For example: Group.forEachAlive(causeDamage, this, 500)

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    callback + + +function + + + +

    The function that will be called. Each child of the Group will be passed to it as its first parameter.

    callbackContext + + +Object + + + +

    The context in which the function should be called (usually 'this').

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    forEachDead(callback, callbackContext)

    + + +
    +
    + + +
    +

    Allows you to call your own function on each dead member of this Group (where alive=false). You must pass the callback and context in which it will run. +You can add as many parameters as you like, which will all be passed to the callback along with the child. +For example: Group.forEachDead(bringToLife, this)

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    callback + + +function + + + +

    The function that will be called. Each child of the Group will be passed to it as its first parameter.

    callbackContext + + +Object + + + +

    The context in which the function should be called (usually 'this').

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    getAt(index) → {*}

    + + +
    +
    + + +
    +

    Returns the child found at the given index within this Group.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    index + + +number + + + +

    The index to return the child from.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The child that was found at the given index.

    +
    + + + +
    +
    + Type +
    +
    + +* + + +
    +
    + + + + + +
    + + + +
    +

    getFirstAlive() → {Any}

    + + +
    +
    + + +
    +

    Call this function to retrieve the first object with alive === true in the group. +This is handy for checking if everything has been wiped out, or choosing a squad leader, etc.

    +
    + + + + + + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The first alive child, or null if none found.

    +
    + + + +
    +
    + Type +
    +
    + +Any + + +
    +
    + + + + + +
    + + + +
    +

    getFirstDead() → {Any}

    + + +
    +
    + + +
    +

    Call this function to retrieve the first object with alive === false in the group. +This is handy for checking if everything has been wiped out, or choosing a squad leader, etc.

    +
    + + + + + + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The first dead child, or null if none found.

    +
    + + + +
    +
    + Type +
    +
    + +Any + + +
    +
    + + + + + +
    + + + +
    +

    getFirstExists(state) → {Any}

    + + +
    +
    + + +
    +

    Call this function to retrieve the first object with exists == (the given state) in the Group.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    state + + +boolean + + + +

    True or false.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The first child, or null if none found.

    +
    + + + +
    +
    + Type +
    +
    + +Any + + +
    +
    + + + + + +
    + + + +
    +

    getIndex(child) → {number}

    + + +
    +
    + + +
    +

    Get the index position of the given child in this Group.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    child + + +* + + + +

    The child to get the index for.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    The index of the child or -1 if it's not a member of this Group.

    +
    + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    getRandom(startIndex, length) → {Any}

    + + +
    +
    + + +
    +

    Returns a member at random from the group.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    startIndex + + +number + + + +

    Optional offset off the front of the array. Default value is 0, or the beginning of the array.

    length + + +number + + + +

    Optional restriction on the number of values you want to randomly select from.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    A random child of this Group.

    +
    + + + +
    +
    + Type +
    +
    + +Any + + +
    +
    + + + + + +
    + + + +
    +

    iterate(key, value, returnType, callback, callbackContext) → {any}

    + + +
    +
    + + +
    +

    Iterates over the children of the Group. When a child has a property matching key that equals the given value, it is considered as a match. +Matched children can be sent to the optional callback, or simply returned or counted. +You can add as many callback parameters as you like, which will all be passed to the callback along with the child, after the callbackContext parameter.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    key + + +string + + + + + + + + + + + +

    The child property to check, i.e. 'exists', 'alive', 'health'

    value + + +any + + + + + + + + + + + +

    If child.key === this value it will be considered a match. Note that a strict comparison is used.

    returnType + + +number + + + + + + + + + + + +

    How to return the data from this method. Either Phaser.Group.RETURN_NONE, Phaser.Group.RETURN_TOTAL or Phaser.Group.RETURN_CHILD.

    callback + + +function + + + + + + <optional>
    + + + + + +
    + + null + +

    Optional function that will be called on each matching child. Each child of the Group will be passed to it as its first parameter.

    callbackContext + + +Object + + + + + + <optional>
    + + + + + +
    + +

    The context in which the function should be called (usually 'this').

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    Returns either a numeric total (if RETURN_TOTAL was specified) or the child object.

    +
    + + + +
    +
    + Type +
    +
    + +any + + +
    +
    + + + + + +
    + + + +
    +

    multiplyAll(property, amount, checkAlive, checkVisible)

    + + +
    +
    + + +
    +

    Multiplies the given property by the amount on all children in this Group. +Group.multiplyAll('x', 2) will x2 the child.x value.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    property + + +string + + + +

    The property to multiply, for example 'body.velocity.x' or 'angle'.

    amount + + +number + + + +

    The amount to multiply the property by. If child.x = 10 then multiplyAll('x', 2) would make child.x = 20.

    checkAlive + + +boolean + + + +

    If true the property will only be changed if the child is alive.

    checkVisible + + +boolean + + + +

    If true the property will only be changed if the child is visible.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    next()

    + + +
    +
    + + +
    +

    Advances the Group cursor to the next object in the Group. If it's at the end of the Group it wraps around to the first object.

    +
    + + + + + + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    @@ -1856,7 +7770,10 @@ So if you want to make a game in which the world itself will rotate you should a
    -

    This is called automatically every frame, and is where main logic happens.

    +

    This is called automatically before the renderer runs and after the plugins have updated. +In postUpdate this is where all the final physics calculatations and object positioning happens. +The objects are processed in the order of the display list. +The only exception to this is if the camera is following an object, in which case that is updated first.

    @@ -1889,7 +7806,1213 @@ So if you want to make a game in which the world itself will rotate you should a
    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    previous()

    + + +
    +
    + + +
    +

    Moves the Group cursor to the previous object in the Group. If it's at the start of the Group it wraps around to the last object.

    +
    + + + + + + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    remove(child) → {boolean}

    + + +
    +
    + + +
    +

    Removes the given child from this Group and sets its group property to null.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    child + + +Any + + + +

    The child to remove.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    true if the child was removed from this Group, otherwise false.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    removeAll()

    + + +
    +
    + + +
    +

    Removes all children from this Group, setting all group properties to null. +The Group container remains on the display list.

    +
    + + + + + + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    removeBetween(startIndex, endIndex)

    + + +
    +
    + + +
    +

    Removes all children from this Group whos index falls beteen the given startIndex and endIndex values.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    startIndex + + +number + + + +

    The index to start removing children from.

    endIndex + + +number + + + +

    The index to stop removing children from. Must be higher than startIndex and less than the length of the Group.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    replace(oldChild, newChild)

    + + +
    +
    + + +
    +

    Replaces a child of this Group with the given newChild. The newChild cannot be a member of this Group.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    oldChild + + +* + + + +

    The child in this Group that will be replaced.

    newChild + + +* + + + +

    The child to be inserted into this group.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    set(child, key, value, checkAlive, checkVisible, operation)

    + + +
    +
    + + +
    +

    This function allows you to quickly set a property on a single child of this Group to a new value. +The operation parameter controls how the new value is assigned to the property, from simple replacement to addition and multiplication.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    child + + +Phaser.Sprite + + + + + + + + + + + +

    The child to set the property on.

    key + + +string + + + + + + + + + + + +

    The property, as a string, to be set. For example: 'body.velocity.x'

    value + + +* + + + + + + + + + + + +

    The value that will be set.

    checkAlive + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    If set then the child will only be updated if alive=true.

    checkVisible + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    If set then the child will only be updated if visible=true.

    operation + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    Controls how the value is assigned. A value of 0 replaces the value with the new one. A value of 1 adds it, 2 subtracts it, 3 multiplies it and 4 divides it.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    setAll(key, value, checkAlive, checkVisible, operation)

    + + +
    +
    + + +
    +

    This function allows you to quickly set the same property across all children of this Group to a new value. +The operation parameter controls how the new value is assigned to the property, from simple replacement to addition and multiplication.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    key + + +string + + + + + + + + + + + +

    The property, as a string, to be set. For example: 'body.velocity.x'

    value + + +* + + + + + + + + + + + +

    The value that will be set.

    checkAlive + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    If set then only children with alive=true will be updated.

    checkVisible + + +boolean + + + + + + <optional>
    + + + + + +
    + + false + +

    If set then only children with visible=true will be updated.

    operation + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    Controls how the value is assigned. A value of 0 replaces the value with the new one. A value of 1 adds it, 2 subtracts it, 3 multiplies it and 4 divides it.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    @@ -1925,8 +9048,7 @@ So if you want to make a game in which the world itself will rotate you should a
    -

    Updates the size of this world. Note that this doesn't modify the world x/y coordinates, just the width and height. -If you need to adjust the bounds of the world

    +

    Updates the size of this world. Note that this doesn't modify the world x/y coordinates, just the width and height.

    @@ -2022,7 +9144,7 @@ If you need to adjust the bounds of the world

    -

    New width of the world.

    +

    New width of the world. Can never be smaller than the Game.width.

    @@ -2045,7 +9167,7 @@ If you need to adjust the bounds of the world

    -

    New height of the world.

    +

    New height of the world. Can never be smaller than the Game.height.

    @@ -2077,7 +9199,875 @@ If you need to adjust the bounds of the world

    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    setProperty(child, key, value, operation)

    + + +
    +
    + + +
    +

    Sets the given property to the given value on the child. The operation controls the assignment of the value.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    child + + +* + + + + + + + + + + + +

    The child to set the property value on.

    key + + +array + + + + + + + + + + + +

    An array of strings that make up the property that will be set.

    value + + +* + + + + + + + + + + + +

    The value that will be set.

    operation + + +number + + + + + + <optional>
    + + + + + +
    + + 0 + +

    Controls how the value is assigned. A value of 0 replaces the value with the new one. A value of 1 adds it, 2 subtracts it, 3 multiplies it and 4 divides it.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    sort(index, order)

    + + +
    +
    + + +
    +

    Call this function to sort the group according to a particular value and order. +For example to depth sort Sprites for Zelda-style game you might call group.sort('y', Phaser.Group.SORT_ASCENDING) at the bottom of your State.update().

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeArgumentDefaultDescription
    index + + +string + + + + + + <optional>
    + + + + + +
    + + 'y' + +

    The string name of the property you want to sort on.

    order + + +number + + + + + + <optional>
    + + + + + +
    + + Phaser.Group.SORT_ASCENDING + +

    The Group constant that defines the sort order. Possible values are Phaser.Group.SORT_ASCENDING and Phaser.Group.SORT_DESCENDING.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    subAll(property, amount, checkAlive, checkVisible)

    + + +
    +
    + + +
    +

    Subtracts the amount from the given property on all children in this Group. +Group.subAll('x', 10) will minus 10 from the child.x value.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    property + + +string + + + +

    The property to decrement, for example 'body.velocity.x' or 'angle'.

    amount + + +number + + + +

    The amount to subtract from the property. If child.x = 50 then subAll('x', 40) would make child.x = 10.

    checkAlive + + +boolean + + + +

    If true the property will only be changed if the child is alive.

    checkVisible + + +boolean + + + +

    If true the property will only be changed if the child is visible.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    swap(child1, child2) → {boolean}

    + + +
    +
    + + +
    +

    Swaps the position of two children in this Group. Both children must be in this Group. +You cannot swap a child with itself, or swap un-parented children, doing so will return false.

    +
    + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    child1 + + +* + + + +

    The first child to swap.

    child2 + + +* + + + +

    The second child to swap.

    + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + +
    +

    True if the swap was successful, otherwise false.

    +
    + + + +
    +
    + Type +
    +
    + +boolean + + +
    +
    + + + + + +
    + + + +
    +

    swapIndex()

    + + +
    +
    + + +
    +

    Internal test.

    +
    + + + + + + + + + +
    + + + + + + + +
    Inherited From:
    +
    + + + + + + + + + + + + + +
    Source:
    +
    @@ -2113,7 +10103,8 @@ If you need to adjust the bounds of the world

    -

    This is called automatically every frame, and is where main logic happens.

    +

    This is called automatically after the plugins preUpdate and before the State.update. +Most objects have preUpdate methods and it's where initial movement, drawing and calculations are done.

    @@ -2146,7 +10137,77 @@ If you need to adjust the bounds of the world

    Source:
    + + + + + + + +
    + + + + + + + + + + + + + +
    + + + +
    +

    update()

    + + +
    +
    + + +
    +

    This is called automatically after the State.update, but before particles or plugins update. +Most objects won't have an update method set unless explicitly given one.

    +
    + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -2191,13 +10252,13 @@ If you need to adjust the bounds of the world

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:36 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:37 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.html b/docs/Phaser.html index 59718ca0..ecf95de5 100644 --- a/docs/Phaser.html +++ b/docs/Phaser.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -519,6 +513,9 @@
    Device
    +
    DOMSprite
    +
    +
    Easing
    @@ -540,6 +537,12 @@
    GameObjectFactory
    +
    Gamepad
    +
    + +
    GamepadButton
    +
    +
    Graphics
    @@ -558,6 +561,9 @@
    Keyboard
    +
    Line
    +
    +
    LinkedList
    @@ -618,6 +624,9 @@
    Signal
    +
    SinglePad
    +
    +
    Sound
    @@ -666,6 +675,9 @@
    Timer
    +
    TimerEvent
    +
    +
    Touch
    @@ -706,13 +718,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:26 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:25 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Phaser.js.html b/docs/Phaser.js.html index 6736abc8..0c5ebf0e 100644 --- a/docs/Phaser.js.html +++ b/docs/Phaser.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -433,7 +427,7 @@
     var Phaser = Phaser || {
     
     	VERSION: '<%= version %>',
    -	DEV_VERSION: '1.1.3',
    +	DEV_VERSION: '1.1.4',
     	GAMES: [],
     
     	AUTO: 0,
    @@ -462,7 +456,10 @@ var Phaser = Phaser || {
     	LEFT: 1,
     	RIGHT: 2,
     	UP: 3,
    -	DOWN: 4
    +	DOWN: 4,
    +
    +	CANVAS_PX_ROUND: false,
    +	CANVAS_CLEAR_RECT: true
     
      };
     
    @@ -485,13 +482,13 @@ PIXI.InteractionManager = function (dummy) {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Plugin.js.html b/docs/Plugin.js.html index 9b26cad5..8302d705 100644 --- a/docs/Plugin.js.html +++ b/docs/Plugin.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -542,6 +536,8 @@ Phaser.Plugin.prototype = {
         }
     
     };
    +
    +Phaser.Plugin.prototype.constructor = Phaser.Plugin;
     
    @@ -557,13 +553,13 @@ Phaser.Plugin.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/PluginManager.js.html b/docs/PluginManager.js.html index 5fad2dfe..b2bd4a46 100644 --- a/docs/PluginManager.js.html +++ b/docs/PluginManager.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -425,7 +419,7 @@ /** * @author Richard Davey <rich@photonstorm.com> -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -718,6 +712,8 @@ Phaser.PluginManager.prototype = { } }; + +Phaser.PluginManager.prototype.constructor = Phaser.PluginManager;
    @@ -733,13 +729,13 @@ Phaser.PluginManager.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Point.js.html b/docs/Point.js.html index 41c1972f..34a3fe53 100644 --- a/docs/Point.js.html +++ b/docs/Point.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -711,6 +705,8 @@ Phaser.Point.prototype = {
     
     };
     
    +Phaser.Point.prototype.constructor = Phaser.Point;
    +
     /**
     * Adds the coordinates of two points together to create a new point.
     * @method Phaser.Point.add
    @@ -866,13 +862,13 @@ Phaser.Point.rotate = function (a, x, y, angle, asDegrees, distance) {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Pointer.js.html b/docs/Pointer.js.html index 769805ec..12357a84 100644 --- a/docs/Pointer.js.html +++ b/docs/Pointer.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -630,7 +624,7 @@ Phaser.Pointer.prototype = {
             }
     
             //  Fix to stop rogue browser plugins from blocking the visibility state event
    -        if (this.game.paused === true && this.game.stage.scale.incorrectOrientation === false)
    +        if (this.game.stage.disableVisibilityChange === false && this.game.paused && this.game.stage.scale.incorrectOrientation === false)
             {
                 this.game.paused = false;
                 return this;
    @@ -680,7 +674,7 @@ Phaser.Pointer.prototype = {
         },
     
         /**
    -    * Called internall by the Input Manager.
    +    * Called by the Input Manager.
         * @method Phaser.Pointer#update
         */
         update: function () {
    @@ -759,12 +753,17 @@ Phaser.Pointer.prototype = {
                 this.game.input.circle.y = this.game.input.y;
             }
     
    -        //  If the game is paused we don't process any target objects
    +        //  If the game is paused we don't process any target objects or callbacks
             if (this.game.paused)
             {
                 return this;
             }
     
    +        if (this.game.input.moveCallback)
    +        {
    +            this.game.input.moveCallback.call(this.game.input.moveCallbackContext, this, this.x, this.y);
    +        }
    +
             //  Easy out if we're dragging something and it still exists
             if (this.targetObject !== null && this.targetObject.isDragged === true)
             {
    @@ -1006,6 +1005,8 @@ Phaser.Pointer.prototype = {
     
     };
     
    +Phaser.Pointer.prototype.constructor = Phaser.Pointer;
    +
     /**
     * How long the Pointer has been depressed on the touchscreen. If not currently down it returns -1.
     * @name Phaser.Pointer#duration
    @@ -1073,13 +1074,13 @@ Object.defineProperty(Phaser.Pointer.prototype, "worldY", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Polygon.js.html b/docs/Polygon.js.html index f6b45bb7..2a9440c0 100644 --- a/docs/Polygon.js.html +++ b/docs/Polygon.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -465,13 +459,13 @@ Phaser.Polygon.prototype.constructor = Phaser.Polygon;
    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/QuadTree.js.html b/docs/QuadTree.js.html index c1774604..856ca076 100644 --- a/docs/QuadTree.js.html +++ b/docs/QuadTree.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,23 +417,23 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
     /**
    - * Javascript QuadTree 
    - * @version 1.0
    - * @author Timo Hausmann
    - *
    - * @version 1.2, September 4th 2013
    - * @author Richard Davey
    - * The original code was a conversion of the Java code posted to GameDevTuts. However I've tweaked
    - * it massively to add node indexing, removed lots of temp. var creation and significantly
    - * increased performance as a result.
    - *
    - * Original version at https://github.com/timohausmann/quadtree-js/
    - */
    +* Javascript QuadTree 
    +* @version 1.0
    +* @author Timo Hausmann
    +*
    +* @version 1.2, September 4th 2013
    +* @author Richard Davey
    +* The original code was a conversion of the Java code posted to GameDevTuts. However I've tweaked
    +* it massively to add node indexing, removed lots of temp. var creation and significantly
    +* increased performance as a result.
    +*
    +* Original version at https://github.com/timohausmann/quadtree-js/
    +*/
      
     /**
     * @copyright © 2012 Timo Hausmann
    @@ -465,27 +459,23 @@
     */
     
     /**
    - * QuadTree Constructor
    - * 
    - * @class Phaser.QuadTree
    - * @classdesc A QuadTree implementation. The original code was a conversion of the Java code posted to GameDevTuts. However I've tweaked
    - * it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result. Original version at https://github.com/timohausmann/quadtree-js/
    - * @constructor
    - * @param {Description} physicsManager - Description.
    - * @param {Description} x - Description.
    - * @param {Description} y - Description.
    - * @param {number} width - The width of your game in game pixels.
    - * @param {number} height - The height of your game in game pixels.
    - * @param {number} maxObjects - Description.
    - * @param {number} maxLevels - Description.
    - * @param {number} level - Description.
    - */
    -Phaser.QuadTree = function (physicsManager, x, y, width, height, maxObjects, maxLevels, level) {
    +* QuadTree Constructor
    +* 
    +* @class Phaser.QuadTree
    +* @classdesc A QuadTree implementation. The original code was a conversion of the Java code posted to GameDevTuts. 
    +* However I've tweaked it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result. 
    +* Original version at https://github.com/timohausmann/quadtree-js/
    +* @constructor
    +* @param {number} x - The top left coordinate of the quadtree.
    +* @param {number} y - The top left coordinate of the quadtree.
    +* @param {number} width - The width of the quadtree in pixels.
    +* @param {number} height - The height of the quadtree in pixels.
    +* @param {number} [maxObjects=10] - The maximum number of objects per node.
    +* @param {number} [maxLevels=4] - The maximum number of levels to iterate to.
    +* @param {number} [level=0] - Which level is this?
    +*/
    +Phaser.QuadTree = function (x, y, width, height, maxObjects, maxLevels, level) {
             
    -    this.physicsManager = physicsManager;
    -    this.ID = physicsManager.quadTreeID;
    -    physicsManager.quadTreeID++;
    -
         this.maxObjects = maxObjects || 10;
         this.maxLevels = maxLevels || 4;
         this.level = level || 0;
    @@ -509,35 +499,60 @@ Phaser.QuadTree = function (physicsManager, x, y, width, height, maxObjects, max
     Phaser.QuadTree.prototype = {
     
         /*
    -    * Split the node into 4 subnodes
    +    * Populates this quadtree with the members of the given Group.
         * 
    -    * @method Phaser.QuadTree#split
    +    * @method Phaser.QuadTree#populate
    +    * @param {Phaser.Group} group - The Group to add to the quadtree.
         */
    -    split: function() {
    +    populate: function (group) {
     
    -        this.level++;
    -        
    -        //  top right node
    -        this.nodes[0] = new Phaser.QuadTree(this.physicsManager, this.bounds.right, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
    -        
    -        //  top left node
    -        this.nodes[1] = new Phaser.QuadTree(this.physicsManager, this.bounds.x, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
    -        
    -        //  bottom left node
    -        this.nodes[2] = new Phaser.QuadTree(this.physicsManager, this.bounds.x, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
    -        
    -        //  bottom right node
    -        this.nodes[3] = new Phaser.QuadTree(this.physicsManager, this.bounds.right, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
    +        group.forEach(this.populateHandler, this, true);
     
         },
     
         /*
    -    * Insert the object into the node. If the node
    -    * exceeds the capacity, it will split and add all
    -    * objects to their corresponding subnodes.
    +    * Handler for the populate method.
    +    * 
    +    * @method Phaser.QuadTree#populateHandler
    +    * @param {Phaser.Sprite} sprite - The Sprite to check.
    +    */
    +    populateHandler: function (sprite) {
    +
    +        if (sprite.body && sprite.body.checkCollision.none === false && sprite.alive)
    +        {
    +            this.insert(sprite.body);
    +        }
    +
    +    },
    +
    +    /*
    +    * Split the node into 4 subnodes
    +    * 
    +    * @method Phaser.QuadTree#split
    +    */
    +    split: function () {
    +
    +        this.level++;
    +        
    +        //  top right node
    +        this.nodes[0] = new Phaser.QuadTree(this.bounds.right, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
    +        
    +        //  top left node
    +        this.nodes[1] = new Phaser.QuadTree(this.bounds.x, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
    +        
    +        //  bottom left node
    +        this.nodes[2] = new Phaser.QuadTree(this.bounds.x, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
    +        
    +        //  bottom right node
    +        this.nodes[3] = new Phaser.QuadTree(this.bounds.right, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level);
    +
    +    },
    +
    +    /*
    +    * Insert the object into the node. If the node exceeds the capacity, it will split and add all objects to their corresponding subnodes.
         * 
         * @method Phaser.QuadTree#insert
    -    * @param {object} body - Description.
    +    * @param {Phaser.Physics.Arcade.Body|object} body - The Body object to insert into the quadtree.
         */
         insert: function (body) {
             
    @@ -589,7 +604,7 @@ Phaser.QuadTree.prototype = {
         * Determine which node the object belongs to.
         * 
         * @method Phaser.QuadTree#getIndex
    -    * @param {object} rect - Description.
    +    * @param {Phaser.Rectangle|object} rect - The bounds in which to check.
         * @return {number} index - Index of the subnode (0-3), or -1 if rect cannot completely fit within a subnode and is part of the parent node.
         */
         getIndex: function (rect) {
    @@ -629,12 +644,12 @@ Phaser.QuadTree.prototype = {
     
         },
     
    -     /*
    -    * Return all objects that could collide with the given object.
    +    /*
    +    * Return all objects that could collide with the given Sprite.
         * 
         * @method Phaser.QuadTree#retrieve
    -    * @param {object} rect - Description.
    -    * @Return {array} - Array with all detected objects.
    +    * @param {Phaser.Sprite} sprite - The sprite to check against.
    +    * @return {array} - Array with all detected objects.
         */
         retrieve: function (sprite) {
             
    @@ -643,7 +658,7 @@ Phaser.QuadTree.prototype = {
             sprite.body.quadTreeIndex = this.getIndex(sprite.body);
     
             //  Temp store for the node IDs this sprite is in, we can use this for fast elimination later
    -        sprite.body.quadTreeIDs.push(this.ID);
    +        // sprite.body.quadTreeIDs.push(this.ID);
     
             if (this.nodes[0])
             {
    @@ -676,7 +691,6 @@ Phaser.QuadTree.prototype = {
          
             for (var i = 0, len = this.nodes.length; i < len; i++)
             {
    -            // if (typeof this.nodes[i] !== 'undefined')
                 if (this.nodes[i])
                 {
                     this.nodes[i].clear();
    @@ -686,6 +700,8 @@ Phaser.QuadTree.prototype = {
         }
     
     };
    +
    +Phaser.QuadTree.prototype.constructor = Phaser.QuadTree;
     
    @@ -701,13 +717,13 @@ Phaser.QuadTree.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/RandomDataGenerator.js.html b/docs/RandomDataGenerator.js.html index 5e49be91..20d38246 100644 --- a/docs/RandomDataGenerator.js.html +++ b/docs/RandomDataGenerator.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -425,7 +419,7 @@ /** * @author Richard Davey <rich@photonstorm.com> -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -668,6 +662,8 @@ Phaser.RandomDataGenerator.prototype = { } }; + +Phaser.RandomDataGenerator.prototype.constructor = Phaser.RandomDataGenerator;
    @@ -683,13 +679,13 @@ Phaser.RandomDataGenerator.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Rectangle.js.html b/docs/Rectangle.js.html index f9559709..4b5a9635 100644 --- a/docs/Rectangle.js.html +++ b/docs/Rectangle.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -689,6 +683,8 @@ Phaser.Rectangle.prototype = {
     
     };
     
    +Phaser.Rectangle.prototype.constructor = Phaser.Rectangle;
    +
     /**
     * @name Phaser.Rectangle#halfWidth
     * @property {number} halfWidth - Half of the width of the Rectangle.
    @@ -1067,12 +1063,12 @@ Phaser.Rectangle.intersection = function (a, b, out) {
     */
     Phaser.Rectangle.intersects = function (a, b) {
     
    -    return (a.x < b.right && b.x < a.right && a.y < b.bottom && b.y < a.bottom);
    +    if (a.width <= 0 || a.height <= 0 || b.width <= 0 || b.height <= 0)
    +    {
    +        return false;
    +    }
     
    -    // return (a.x <= b.right && b.x <= a.right && a.y <= b.bottom && b.y <= a.bottom);
    -
    -    // return (a.left <= b.right && b.left <= a.right && a.top <= b.bottom && b.top <= a.bottom);
    -    // return !(a.x > b.right + tolerance || a.right < b.x - tolerance || a.y > b.bottom + tolerance || a.bottom < b.y - tolerance);
    +    return !(a.right < b.x || a.bottom < b.y || a.x > b.right || a.y > b.bottom);
     
     };
     
    @@ -1124,13 +1120,13 @@ Phaser.Rectangle.union = function (a, b, out) {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/RenderTexture.js.html b/docs/RenderTexture.js.html index ef4b643d..b85fcadd 100644 --- a/docs/RenderTexture.js.html +++ b/docs/RenderTexture.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -494,16 +488,19 @@ Phaser.RenderTexture.prototype.constructor = PIXI.RenderTexture;
     /**
     * This function will draw the display object to the texture. If the display object is a Group or has children it will
     * draw all children as well.
    -*
    -* @method render
    +* 
    +* @method Phaser.RenderTexture#render
    +* @memberof Phaser.RenderTexture
     * @param {DisplayObject} displayObject - The display object to render this texture on.
     * @param {Phaser.Point} [position] - Where to draw the display object.
     * @param {boolean} [clear=false] - If true the texture will be cleared before the displayObject is drawn.
    +* @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered.
     */
    -Phaser.RenderTexture.prototype.render = function(displayObject, position, clear) {
    +Phaser.RenderTexture.prototype.render = function(displayObject, position, clear, renderHidden) {
     
         if (typeof position === 'undefined') { position = false; }
         if (typeof clear === 'undefined') { clear = false; }
    +    if (typeof renderHidden === 'undefined') { renderHidden = false; }
     
         if (displayObject instanceof Phaser.Group)
         {
    @@ -512,11 +509,11 @@ Phaser.RenderTexture.prototype.render = function(displayObject, position, clear)
     
         if (PIXI.gl)
         {
    -        this.renderWebGL(displayObject, position, clear);
    +        this.renderWebGL(displayObject, position, clear, renderHidden);
         }
         else
         {
    -        this.renderCanvas(displayObject, position, clear);
    +        this.renderCanvas(displayObject, position, clear, renderHidden);
         }
     
     }
    @@ -525,29 +522,32 @@ Phaser.RenderTexture.prototype.render = function(displayObject, position, clear)
     * This function will draw the display object to the texture at the given x/y coordinates.
     * If the display object is a Group or has children it will draw all children as well.
     *
    -* @method renderXY
    +* @method Phaser.RenderTexture#renderXY
    +* @memberof Phaser.RenderTexture
     * @param {DisplayObject} displayObject - The display object to render this texture on.
     * @param {number} x - The x coordinate to draw the display object at.
     * @param {number} y - The y coordinate to draw the display object at.
     * @param {boolean} [clear=false] - If true the texture will be cleared before the displayObject is drawn.
    +* @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered.
     */
    -Phaser.RenderTexture.prototype.renderXY = function(displayObject, x, y, clear) {
    +Phaser.RenderTexture.prototype.renderXY = function(displayObject, x, y, clear, renderHidden) {
     
         this._tempPoint.x = x;
         this._tempPoint.y = y;
     
    -    this.render(displayObject, this._tempPoint, clear);
    +    this.render(displayObject, this._tempPoint, clear, renderHidden);
     
     }
     
     /**
    - * Initializes the webgl data for this texture
    - *
    - * @method initWebGL
    - * @private
    - */
    -Phaser.RenderTexture.prototype.initWebGL = function()
    -{
    +* Initializes the webgl data for this texture
    +*
    +* @method Phaser.RenderTexture#initWebGL
    +* @memberof Phaser.RenderTexture
    +* @private
    +*/
    +Phaser.RenderTexture.prototype.initWebGL = function() {
    +
         var gl = PIXI.gl;
         this.glFramebuffer = gl.createFramebuffer();
     
    @@ -583,7 +583,12 @@ Phaser.RenderTexture.prototype.initWebGL = function()
         // this.render = this.renderWebGL;
     }
     
    -
    +/**
    +* Resizes the RenderTexture.
    +*
    +* @method Phaser.RenderTexture#resize
    +* @memberof Phaser.RenderTexture
    +*/
     Phaser.RenderTexture.prototype.resize = function(width, height)
     {
     
    @@ -609,11 +614,12 @@ Phaser.RenderTexture.prototype.resize = function(width, height)
     }
     
     /**
    - * Initializes the canvas data for this texture
    - *
    - * @method initCanvas
    - * @private
    - */
    +* Initializes the canvas data for this texture
    +*
    +* @method Phaser.RenderTexture#initCanvas
    +* @memberof Phaser.RenderTexture
    +* @private
    +*/
     Phaser.RenderTexture.prototype.initCanvas = function()
     {
         this.renderer = new PIXI.CanvasRenderer(this.width, this.height, null, 0);
    @@ -625,14 +631,17 @@ Phaser.RenderTexture.prototype.initCanvas = function()
     }
     
     /**
    - * This function will draw the display object to the texture.
    - *
    - * @method renderWebGL
    - * @param displayObject {DisplayObject} The display object to render this texture on
    - * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn
    - * @private
    - */
    -Phaser.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear)
    +* This function will draw the display object to the texture.
    +*
    +* @method Phaser.RenderTexture#renderWebGL
    +* @memberof Phaser.RenderTexture
    +* @private
    +* @param {DisplayObject} displayObject - The display object to render this texture on.
    +* @param {Phaser.Point} [position] - Where to draw the display object.
    +* @param {boolean} [clear=false] - If true the texture will be cleared before the displayObject is drawn.
    +* @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered.
    +*/
    +Phaser.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear, renderHidden)
     {
         var gl = PIXI.gl;
     
    @@ -703,12 +712,15 @@ Phaser.RenderTexture.prototype.renderWebGL = function(displayObject, position, c
     /**
      * This function will draw the display object to the texture.
      *
    - * @method renderCanvas
    - * @param displayObject {DisplayObject} The display object to render this texture on
    - * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn
    - * @private
    - */
    -Phaser.RenderTexture.prototype.renderCanvas = function(displayObject, position, clear)
    +* @method Phaser.RenderTexture#renderCanvas
    +* @memberof Phaser.RenderTexture
    +* @private
    +* @param {DisplayObject} displayObject - The display object to render this texture on.
    +* @param {Phaser.Point} [position] - Where to draw the display object.
    +* @param {boolean} [clear=false] - If true the texture will be cleared before the displayObject is drawn.
    +* @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered.
    +*/
    +Phaser.RenderTexture.prototype.renderCanvas = function(displayObject, position, clear, renderHidden)
     {
         var children = displayObject.children;
     
    @@ -729,12 +741,11 @@ Phaser.RenderTexture.prototype.renderCanvas = function(displayObject, position,
         {
             this.renderer.context.clearRect(0, 0, this.width, this.height);
         }
    -    
    -    this.renderer.renderDisplayObject(displayObject);
    +
    +    this.renderer.renderDisplayObject(displayObject, renderHidden);
         
         this.renderer.context.setTransform(1, 0, 0, 1, 0, 0);
     
    -  //  PIXI.texturesToUpdate.push(this.baseTexture);
     }
     
    @@ -751,13 +762,13 @@ Phaser.RenderTexture.prototype.renderCanvas = function(displayObject, position, - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/RequestAnimationFrame.js.html b/docs/RequestAnimationFrame.js.html index f78cb6cf..c47f23db 100644 --- a/docs/RequestAnimationFrame.js.html +++ b/docs/RequestAnimationFrame.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -483,7 +477,7 @@ Phaser.RequestAnimationFrame = function(game) {
     Phaser.RequestAnimationFrame.prototype = {
     
         /**
    -    * Starts the requestAnimatioFrame running or setTimeout if unavailable in browser
    +    * Starts the requestAnimationFrame running or setTimeout if unavailable in browser
         * @method Phaser.RequestAnimationFrame#start
         */
         start: function () {
    @@ -577,7 +571,10 @@ Phaser.RequestAnimationFrame.prototype = {
             return (this._isSetTimeOut === false);
         }
     
    -};
    +}; + +Phaser.RequestAnimationFrame.prototype.constructor = Phaser.RequestAnimationFrame; +
    @@ -592,13 +589,13 @@ Phaser.RequestAnimationFrame.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/SAT.js.html b/docs/SAT.js.html new file mode 100644 index 00000000..daffcd9a --- /dev/null +++ b/docs/SAT.js.html @@ -0,0 +1,1340 @@ + + + + + + Phaser Source: physics/arcade/SAT.js + + + + + + + + + + +
    + + +
    + + +
    + +
    + + + +

    Source: physics/arcade/SAT.js

    + +
    +
    +
    // Version 0.2 - Copyright 2013 -  Jim Riecken <jimr@jimr.ca>
    +//
    +// Released under the MIT License - https://github.com/jriecken/sat-js
    +//
    +// A simple library for determining intersections of circles and
    +// polygons using the Separating Axis Theorem.
    +/** @preserve SAT.js - Version 0.2 - Copyright 2013 - Jim Riecken <jimr@jimr.ca> - released under the MIT License. https://github.com/jriecken/sat-js */
    +
    +/*global define: false, module: false*/
    +/*jshint shadow:true, sub:true, forin:true, noarg:true, noempty:true, 
    +  eqeqeq:true, bitwise:true, strict:true, undef:true, 
    +  curly:true, browser:true */
    +
    +// Create a UMD wrapper for SAT. Works in:
    +//
    +//  - Plain browser via global SAT variable
    +//  - AMD loader (like require.js)
    +//  - Node.js
    +//
    +// The quoted properties all over the place are used so that the Closure Compiler
    +// does not mangle the exposed API in advanced mode.
    +/**
    + * @param {*} root - The global scope
    + * @param {Function} factory - Factory that creates SAT module
    + */
    +(function (root, factory) {
    +  "use strict";
    +  if (typeof define === 'function' && define['amd']) {
    +    define(factory);
    +  } else if (typeof exports === 'object') {
    +    module['exports'] = factory();
    +  } else {
    +    root['SAT'] = factory();
    +  }
    +}(this, function () {
    +  "use strict";
    +
    +  var SAT = {};
    +
    +  //
    +  // ## Vector
    +  //
    +  // Represents a vector in two dimensions with `x` and `y` properties.
    +
    +
    +  // Create a new Vector, optionally passing in the `x` and `y` coordinates. If
    +  // a coordinate is not specified, it will be set to `0`
    +  /** 
    +   * @param {?number=} x The x position.
    +   * @param {?number=} y The y position.
    +   * @constructor
    +   */
    +  function Vector(x, y) {
    +    this['x'] = x || 0;
    +    this['y'] = y || 0;
    +  }
    +  SAT['Vector'] = Vector;
    +  // Alias `Vector` as `V`
    +  SAT['V'] = Vector;
    +
    +
    +  // Copy the values of another Vector into this one.
    +  /**
    +   * @param {Vector} other The other Vector.
    +   * @return {Vector} This for chaining.
    +   */
    +  Vector.prototype['copy'] = Vector.prototype.copy = function(other) {
    +    this['x'] = other['x'];
    +    this['y'] = other['y'];
    +    return this;
    +  };
    +
    +  // Change this vector to be perpendicular to what it was before. (Effectively
    +  // roatates it 90 degrees in a clockwise direction)
    +  /**
    +   * @return {Vector} This for chaining.
    +   */
    +  Vector.prototype['perp'] = Vector.prototype.perp = function() {
    +    var x = this['x'];
    +    this['x'] = this['y'];
    +    this['y'] = -x;
    +    return this;
    +  };
    +
    +  // Rotate this vector (counter-clockwise) by the specified angle (in radians).
    +  /**
    +   * @param {number} angle The angle to rotate (in radians)
    +   * @return {Vector} This for chaining.
    +   */
    +  Vector.prototype['rotate'] = Vector.prototype.rotate = function (angle) {
    +    var x = this['x'];
    +    var y = this['y'];
    +    this['x'] = x * Math.cos(angle) - y * Math.sin(angle);
    +    this['y'] = x * Math.sin(angle) + y * Math.cos(angle);
    +    return this;
    +  };
    +
    +  // Rotate this vector (counter-clockwise) by the specified angle (in radians) which has already been calculated into sin and cos.
    +  /**
    +   * @param {number} sin - The Math.sin(angle)
    +   * @param {number} cos - The Math.cos(angle)
    +   * @return {Vector} This for chaining.
    +   */
    +  Vector.prototype['rotatePrecalc'] = Vector.prototype.rotatePrecalc = function (sin, cos) {
    +    var x = this['x'];
    +    var y = this['y'];
    +    this['x'] = x * cos - y * sin;
    +    this['y'] = x * sin + y * cos;
    +    return this;
    +  };
    +
    +  // Reverse this vector.
    +  /**
    +   * @return {Vector} This for chaining.
    +   */
    +  Vector.prototype['reverse'] = Vector.prototype.reverse = function() {
    +    this['x'] = -this['x'];
    +    this['y'] = -this['y'];
    +    return this;
    +  };
    +  
    +
    +  // Normalize this vector.  (make it have length of `1`)
    +  /**
    +   * @return {Vector} This for chaining.
    +   */
    +  Vector.prototype['normalize'] = Vector.prototype.normalize = function() {
    +    var d = this.len();
    +    if(d > 0) {
    +      this['x'] = this['x'] / d;
    +      this['y'] = this['y'] / d;
    +    }
    +    return this;
    +  };
    +  
    +  // Add another vector to this one.
    +  /**
    +   * @param {Vector} other The other Vector.
    +   * @return {Vector} This for chaining.
    +   */
    +  Vector.prototype['add'] = Vector.prototype.add = function(other) {
    +    this['x'] += other['x'];
    +    this['y'] += other['y'];
    +    return this;
    +  };
    +  
    +  // Subtract another vector from this one.
    +  /**
    +   * @param {Vector} other The other Vector.
    +   * @return {Vector} This for chaiing.
    +   */
    +  Vector.prototype['sub'] = Vector.prototype.sub = function(other) {
    +    this['x'] -= other['x'];
    +    this['y'] -= other['y'];
    +    return this;
    +  };
    +  
    +  // Scale this vector. An independant scaling factor can be provided
    +  // for each axis, or a single scaling factor that will scale both `x` and `y`.
    +  /**
    +   * @param {number} x The scaling factor in the x direction.
    +   * @param {?number=} y The scaling factor in the y direction.  If this
    +   *   is not specified, the x scaling factor will be used.
    +   * @return {Vector} This for chaining.
    +   */
    +  Vector.prototype['scale'] = Vector.prototype.scale = function(x,y) {
    +    this['x'] *= x;
    +    this['y'] *= y || x;
    +    return this; 
    +  };
    +  
    +  // Project this vector on to another vector.
    +  /**
    +   * @param {Vector} other The vector to project onto.
    +   * @return {Vector} This for chaining.
    +   */
    +  Vector.prototype['project'] = Vector.prototype.project = function(other) {
    +    var amt = this.dot(other) / other.len2();
    +    this['x'] = amt * other['x'];
    +    this['y'] = amt * other['y'];
    +    return this;
    +  };
    +  
    +  // Project this vector onto a vector of unit length. This is slightly more efficient
    +  // than `project` when dealing with unit vectors.
    +  /**
    +   * @param {Vector} other The unit vector to project onto.
    +   * @return {Vector} This for chaining.
    +   */
    +  Vector.prototype['projectN'] = Vector.prototype.projectN = function(other) {
    +    var amt = this.dot(other);
    +    this['x'] = amt * other['x'];
    +    this['y'] = amt * other['y'];
    +    return this;
    +  };
    +  
    +  // Reflect this vector on an arbitrary axis.
    +  /**
    +   * @param {Vector} axis The vector representing the axis.
    +   * @return {Vector} This for chaining.
    +   */
    +  Vector.prototype['reflect'] = Vector.prototype.reflect = function(axis) {
    +    var x = this['x'];
    +    var y = this['y'];
    +    this.project(axis).scale(2);
    +    this['x'] -= x;
    +    this['y'] -= y;
    +    return this;
    +  };
    +  
    +  // Reflect this vector on an arbitrary axis (represented by a unit vector). This is
    +  // slightly more efficient than `reflect` when dealing with an axis that is a unit vector.
    +  /**
    +   * @param {Vector} axis The unit vector representing the axis.
    +   * @return {Vector} This for chaining.
    +   */
    +  Vector.prototype['reflectN'] = Vector.prototype.reflectN = function(axis) {
    +    var x = this['x'];
    +    var y = this['y'];
    +    this.projectN(axis).scale(2);
    +    this['x'] -= x;
    +    this['y'] -= y;
    +    return this;
    +  };
    +  
    +  // Get the dot product of this vector and another.
    +  /**
    +   * @param {Vector}  other The vector to dot this one against.
    +   * @return {number} The dot product.
    +   */
    +  Vector.prototype['dot'] = Vector.prototype.dot = function(other) {
    +    return this['x'] * other['x'] + this['y'] * other['y'];
    +  };
    +  
    +  // Get the squared length of this vector.
    +  /**
    +   * @return {number} The length^2 of this vector.
    +   */
    +  Vector.prototype['len2'] = Vector.prototype.len2 = function() {
    +    return this.dot(this);
    +  };
    +  
    +  // Get the length of this vector.
    +  /**
    +   * @return {number} The length of this vector.
    +   */
    +  Vector.prototype['len'] = Vector.prototype.len = function() {
    +    return Math.sqrt(this.len2());
    +  };
    +  
    +  // ## Circle
    +  //
    +  // Represents a circle with a position and a radius.
    +
    +  // Create a new circle, optionally passing in a position and/or radius. If no position
    +  // is given, the circle will be at `(0,0)`. If no radius is provided, the circle will
    +  // have a radius of `0`.
    +  /**
    +   * @param {Vector=} pos A vector representing the position of the center of the circle
    +   * @param {?number=} r The radius of the circle
    +   * @constructor
    +   */
    +  function Circle(pos, r) {
    +    this['pos'] = pos || new Vector();
    +    this['r'] = r || 0;
    +  }
    +  SAT['Circle'] = Circle;
    +
    +  // ## Polygon
    +  //
    +  // Represents a *convex* polygon with any number of points (specified in counter-clockwise order)
    +  //
    +  // The edges/normals of the polygon will be calculated on creation and stored in the
    +  // `edges` and `normals` properties. If you change the polygon's points, you will need
    +  // to call `recalc` to recalculate the edges/normals.
    +
    +  // Create a new polygon, passing in a position vector, and an array of points (represented
    +  // by vectors relative to the position vector). If no position is passed in, the position
    +  // of the polygon will be `(0,0)`.
    +  /**
    +   * @param {Vector=} pos A vector representing the origin of the polygon. (all other
    +   *   points are relative to this one)
    +   * @param {Array.<Vector>=} points An array of vectors representing the points in the polygon,
    +   *   in counter-clockwise order.
    +   * @constructor
    +   */
    +  function Polygon(pos, points) {
    +    this['pos'] = pos || new Vector();
    +    this['points'] = points || [];
    +    this.recalc();
    +  }
    +  SAT['Polygon'] = Polygon;
    +  
    +  // Recalculates the edges and normals of the polygon. This **must** be called
    +  // if the `points` array is modified at all and the edges or normals are to be
    +  // accessed.
    +  /**
    +   * @return {Polygon} This for chaining.
    +   */
    +  Polygon.prototype['recalc'] = Polygon.prototype.recalc = function() {
    +    // The edges here are the direction of the `n`th edge of the polygon, relative to
    +    // the `n`th point. If you want to draw a given edge from the edge value, you must
    +    // first translate to the position of the starting point.
    +    this['edges'] = [];
    +    // The normals here are the direction of the normal for the `n`th edge of the polygon, relative
    +    // to the position of the `n`th point. If you want to draw an edge normal, you must first
    +    // translate to the position of the starting point.
    +    this['normals'] = [];
    +    var points = this['points'];
    +    var len = points.length;
    +    for (var i = 0; i < len; i++) {
    +      var p1 = points[i]; 
    +      var p2 = i < len - 1 ? points[i + 1] : points[0];
    +      var e = new Vector().copy(p2).sub(p1);
    +      var n = new Vector().copy(e).perp().normalize();
    +      this['edges'].push(e);
    +      this['normals'].push(n);
    +    }
    +    return this;
    +  };
    +
    +  // Rotates this polygon counter-clockwise around the origin of *its local coordinate system* (i.e. `pos`).
    +  //
    +  // Note: You do **not** need to call `recalc` after rotation.
    +  /**
    +   * @param {number} angle The angle to rotate (in radians)
    +   * @return {Polygon} This for chaining.
    +   */
    +  Polygon.prototype['rotate'] = Polygon.prototype.rotate = function(angle) {
    +    var i;
    +    var points = this['points'];
    +    var edges = this['edges'];
    +    var normals = this['normals'];
    +    var len = points.length;
    +
    +    //  Calc it just the once, rather than 4 times per array element
    +    var cos = Math.cos(angle);
    +    var sin = Math.sin(angle);
    +
    +    for (i = 0; i < len; i++) {
    +      points[i].rotatePrecalc(sin, cos);
    +      edges[i].rotatePrecalc(sin, cos);
    +      normals[i].rotatePrecalc(sin, cos);
    +    }
    +    return this;
    +  };
    +
    +  // Rotates this polygon counter-clockwise around the origin of *its local coordinate system* (i.e. `pos`).
    +  //
    +  // Note: You do **not** need to call `recalc` after rotation.
    +  /**
    +   * @param {number} angle The angle to rotate (in radians)
    +   * @return {Polygon} This for chaining.
    +   */
    +  Polygon.prototype['scale'] = Polygon.prototype.scale = function(x, y) {
    +    var i;
    +    var points = this['points'];
    +    var edges = this['edges'];
    +    var normals = this['normals'];
    +    var len = points.length;
    +    for (i = 0; i < len; i++) {
    +      points[i].scale(x,y);
    +      edges[i].scale(x,y);
    +      normals[i].scale(x,y);
    +    }
    +    return this;
    +  };
    +
    +  // Translates the points of this polygon by a specified amount relative to the origin of *its own coordinate
    +  // system* (i.e. `pos`).
    +  //
    +  // This is most useful to change the "center point" of a polygon.
    +  //
    +  // Note: You do **not** need to call `recalc` after translation.
    +  /**
    +   * @param {number} x The horizontal amount to translate.
    +   * @param {number} y The vertical amount to translate.
    +   * @return {Polygon} This for chaining.
    +   */
    +  Polygon.prototype['translate'] = Polygon.prototype.translate = function (x, y) {
    +    var i;
    +    var points = this['points'];
    +    var len = points.length;
    +    for (i = 0; i < len; i++) {
    +      points[i].x += x;
    +      points[i].y += y;
    +    }
    +    return this;
    +  };
    +
    +  // ## Box
    +  //
    +  // Represents an axis-aligned box, with a width and height.
    +
    +
    +  // Create a new box, with the specified position, width, and height. If no position
    +  // is given, the position will be `(0,0)`. If no width or height are given, they will
    +  // be set to `0`.
    +  /**
    +   * @param {Vector=} pos A vector representing the top-left of the box.
    +   * @param {?number=} w The width of the box.
    +   * @param {?number=} h The height of the box.
    +   * @constructor
    +   */
    +  function Box(pos, w, h) {
    +    this['pos'] = pos || new Vector();
    +    this['w'] = w || 0;
    +    this['h'] = h || 0;
    +  }
    +  SAT['Box'] = Box;
    +
    +  // Returns a polygon whose edges are the same as this box.
    +  /**
    +   * @return {Polygon} A new Polygon that represents this box.
    +   */
    +  Box.prototype['toPolygon'] = Box.prototype.toPolygon = function() {
    +    var pos = this['pos'];
    +    var w = this['w'];
    +    var h = this['h'];
    +    return new Polygon(new Vector(pos['x'], pos['y']), [
    +     new Vector(), new Vector(w, 0), 
    +     new Vector(w,h), new Vector(0,h)
    +    ]);
    +  };
    +  
    +  // ## Response
    +  //
    +  // An object representing the result of an intersection. Contains:
    +  //  - The two objects participating in the intersection
    +  //  - The vector representing the minimum change necessary to extract the first object
    +  //    from the second one (as well as a unit vector in that direction and the magnitude
    +  //    of the overlap)
    +  //  - Whether the first object is entirely inside the second, and vice versa.
    +  /**
    +   * @constructor
    +   */  
    +  function Response() {
    +    this['a'] = null;
    +    this['b'] = null;
    +    this['overlapN'] = new Vector();
    +    this['overlapV'] = new Vector();
    +    this.clear();
    +  }
    +  SAT['Response'] = Response;
    +
    +  // Set some values of the response back to their defaults.  Call this between tests if
    +  // you are going to reuse a single Response object for multiple intersection tests (recommented
    +  // as it will avoid allcating extra memory)
    +  /**
    +   * @return {Response} This for chaining
    +   */
    +  Response.prototype['clear'] = Response.prototype.clear = function() {
    +    this['aInB'] = true;
    +    this['bInA'] = true;
    +    this['overlap'] = Number.MAX_VALUE;
    +    return this;
    +  };
    +
    +  // ## Object Pools
    +
    +  // A pool of `Vector` objects that are used in calculations to avoid
    +  // allocating memory.
    +  /**
    +   * @type {Array.<Vector>}
    +   */
    +  var T_VECTORS = [];
    +  for (var i = 0; i < 10; i++) { T_VECTORS.push(new Vector()); }
    +  
    +  // A pool of arrays of numbers used in calculations to avoid allocating
    +  // memory.
    +  /**
    +   * @type {Array.<Array.<number>>}
    +   */
    +  var T_ARRAYS = [];
    +  for (var i = 0; i < 5; i++) { T_ARRAYS.push([]); }
    +
    +  // ## Helper Functions
    +
    +  // Flattens the specified array of points onto a unit vector axis,
    +  // resulting in a one dimensional range of the minimum and
    +  // maximum value on that axis.
    +  /**
    +   * @param {Array.<Vector>} points The points to flatten.
    +   * @param {Vector} normal The unit vector axis to flatten on.
    +   * @param {Array.<number>} result An array.  After calling this function,
    +   *   result[0] will be the minimum value,
    +   *   result[1] will be the maximum value.
    +   */
    +  function flattenPointsOn(points, normal, result) {
    +    var min = Number.MAX_VALUE;
    +    var max = -Number.MAX_VALUE;
    +    var len = points.length;
    +    for (var i = 0; i < len; i++ ) {
    +      // The magnitude of the projection of the point onto the normal
    +      var dot = points[i].dot(normal);
    +      if (dot < min) { min = dot; }
    +      if (dot > max) { max = dot; }
    +    }
    +    result[0] = min; result[1] = max;
    +  }
    +  
    +  // Check whether two convex polygons are separated by the specified
    +  // axis (must be a unit vector).
    +  /**
    +   * @param {Vector} aPos The position of the first polygon.
    +   * @param {Vector} bPos The position of the second polygon.
    +   * @param {Array.<Vector>} aPoints The points in the first polygon.
    +   * @param {Array.<Vector>} bPoints The points in the second polygon.
    +   * @param {Vector} axis The axis (unit sized) to test against.  The points of both polygons
    +   *   will be projected onto this axis.
    +   * @param {Response=} response A Response object (optional) which will be populated
    +   *   if the axis is not a separating axis.
    +   * @return {boolean} true if it is a separating axis, false otherwise.  If false,
    +   *   and a response is passed in, information about how much overlap and
    +   *   the direction of the overlap will be populated.
    +   */
    +  function isSeparatingAxis(aPos, bPos, aPoints, bPoints, axis, response) {
    +    var rangeA = T_ARRAYS.pop();
    +    var rangeB = T_ARRAYS.pop();
    +    // The magnitude of the offset between the two polygons
    +    var offsetV = T_VECTORS.pop().copy(bPos).sub(aPos);
    +    var projectedOffset = offsetV.dot(axis);
    +    // Project the polygons onto the axis.
    +    flattenPointsOn(aPoints, axis, rangeA);
    +    flattenPointsOn(bPoints, axis, rangeB);
    +    // Move B's range to its position relative to A.
    +    rangeB[0] += projectedOffset;
    +    rangeB[1] += projectedOffset;
    +    // Check if there is a gap. If there is, this is a separating axis and we can stop
    +    if (rangeA[0] > rangeB[1] || rangeB[0] > rangeA[1]) {
    +      T_VECTORS.push(offsetV); 
    +      T_ARRAYS.push(rangeA); 
    +      T_ARRAYS.push(rangeB);
    +      return true;
    +    }
    +    // This is not a separating axis. If we're calculating a response, calculate the overlap.
    +    if (response) {
    +      var overlap = 0;
    +      // A starts further left than B
    +      if (rangeA[0] < rangeB[0]) {
    +        response['aInB'] = false;
    +        // A ends before B does. We have to pull A out of B
    +        if (rangeA[1] < rangeB[1]) { 
    +          overlap = rangeA[1] - rangeB[0];
    +          response['bInA'] = false;
    +        // B is fully inside A.  Pick the shortest way out.
    +        } else {
    +          var option1 = rangeA[1] - rangeB[0];
    +          var option2 = rangeB[1] - rangeA[0];
    +          overlap = option1 < option2 ? option1 : -option2;
    +        }
    +      // B starts further left than A
    +      } else {
    +        response['bInA'] = false;
    +        // B ends before A ends. We have to push A out of B
    +        if (rangeA[1] > rangeB[1]) { 
    +          overlap = rangeA[0] - rangeB[1];
    +          response['aInB'] = false;
    +        // A is fully inside B.  Pick the shortest way out.
    +        } else {
    +          var option1 = rangeA[1] - rangeB[0];
    +          var option2 = rangeB[1] - rangeA[0];
    +          overlap = option1 < option2 ? option1 : -option2;
    +        }
    +      }
    +      // If this is the smallest amount of overlap we've seen so far, set it as the minimum overlap.
    +      var absOverlap = Math.abs(overlap);
    +      if (absOverlap < response['overlap']) {
    +        response['overlap'] = absOverlap;
    +        response['overlapN'].copy(axis);
    +        if (overlap < 0) {
    +          response['overlapN'].reverse();
    +        }
    +      }      
    +    }
    +    T_VECTORS.push(offsetV); 
    +    T_ARRAYS.push(rangeA); 
    +    T_ARRAYS.push(rangeB);
    +    return false;
    +  }
    +  
    +  // Calculates which Vornoi region a point is on a line segment.
    +  // It is assumed that both the line and the point are relative to `(0,0)`
    +  //
    +  //            |       (0)      |
    +  //     (-1)  [S]--------------[E]  (1)
    +  //            |       (0)      |
    +  /**
    +   * @param {Vector} line The line segment.
    +   * @param {Vector} point The point.
    +   * @return  {number} LEFT_VORNOI_REGION (-1) if it is the left region, 
    +   *          MIDDLE_VORNOI_REGION (0) if it is the middle region, 
    +   *          RIGHT_VORNOI_REGION (1) if it is the right region.
    +   */
    +  function vornoiRegion(line, point) {
    +    var len2 = line.len2();
    +    var dp = point.dot(line);
    +    // If the point is beyond the start of the line, it is in the
    +    // left vornoi region.
    +    if (dp < 0) { return LEFT_VORNOI_REGION; }
    +    // If the point is beyond the end of the line, it is in the
    +    // right vornoi region.
    +    else if (dp > len2) { return RIGHT_VORNOI_REGION; }
    +    // Otherwise, it's in the middle one.
    +    else { return MIDDLE_VORNOI_REGION; }
    +  }
    +  // Constants for Vornoi regions
    +  /**
    +   * @const
    +   */
    +  var LEFT_VORNOI_REGION = -1;
    +  /**
    +   * @const
    +   */
    +  var MIDDLE_VORNOI_REGION = 0;
    +  /**
    +   * @const
    +   */
    +  var RIGHT_VORNOI_REGION = 1;
    +  
    +  // ## Collision Tests
    +
    +  // Check if two circles collide.
    +  /**
    +   * @param {Circle} a The first circle.
    +   * @param {Circle} b The second circle.
    +   * @param {Response=} response Response object (optional) that will be populated if
    +   *   the circles intersect.
    +   * @return {boolean} true if the circles intersect, false if they don't. 
    +   */
    +  function testCircleCircle(a, b, response) {
    +    // Check if the distance between the centers of the two
    +    // circles is greater than their combined radius.
    +    var differenceV = T_VECTORS.pop().copy(b['pos']).sub(a['pos']);
    +    var totalRadius = a['r'] + b['r'];
    +    var totalRadiusSq = totalRadius * totalRadius;
    +    var distanceSq = differenceV.len2();
    +    // If the distance is bigger than the combined radius, they don't intersect.
    +    if (distanceSq > totalRadiusSq) {
    +      T_VECTORS.push(differenceV);
    +      return false;
    +    }
    +    // They intersect.  If we're calculating a response, calculate the overlap.
    +    if (response) { 
    +      var dist = Math.sqrt(distanceSq);
    +      response['a'] = a;
    +      response['b'] = b;
    +      response['overlap'] = totalRadius - dist;
    +      response['overlapN'].copy(differenceV.normalize());
    +      response['overlapV'].copy(differenceV).scale(response['overlap']);
    +      response['aInB']= a['r'] <= b['r'] && dist <= b['r'] - a['r'];
    +      response['bInA'] = b['r'] <= a['r'] && dist <= a['r'] - b['r'];
    +    }
    +    T_VECTORS.push(differenceV);
    +    return true;
    +  }
    +  SAT['testCircleCircle'] = testCircleCircle;
    +  
    +  // Check if a polygon and a circle collide.
    +  /**
    +   * @param {Polygon} polygon The polygon.
    +   * @param {Circle} circle The circle.
    +   * @param {Response=} response Response object (optional) that will be populated if
    +   *   they interset.
    +   * @return {boolean} true if they intersect, false if they don't.
    +   */
    +  function testPolygonCircle(polygon, circle, response) {
    +    // Get the position of the circle relative to the polygon.
    +    var circlePos = T_VECTORS.pop().copy(circle['pos']).sub(polygon['pos']);
    +    var radius = circle['r'];
    +    var radius2 = radius * radius;
    +    var points = polygon['points'];
    +    var len = points.length;
    +    var edge = T_VECTORS.pop();
    +    var point = T_VECTORS.pop();
    +    
    +    // For each edge in the polygon:
    +    for (var i = 0; i < len; i++) {
    +      var next = i === len - 1 ? 0 : i + 1;
    +      var prev = i === 0 ? len - 1 : i - 1;
    +      var overlap = 0;
    +      var overlapN = null;
    +      
    +      // Get the edge.
    +      edge.copy(polygon['edges'][i]);
    +      // Calculate the center of the circle relative to the starting point of the edge.
    +      point.copy(circlePos).sub(points[i]);
    +      
    +      // If the distance between the center of the circle and the point
    +      // is bigger than the radius, the polygon is definitely not fully in
    +      // the circle.
    +      if (response && point.len2() > radius2) {
    +        response['aInB'] = false;
    +      }
    +      
    +      // Calculate which Vornoi region the center of the circle is in.
    +      var region = vornoiRegion(edge, point);
    +      // If it's the left region:
    +      if (region === LEFT_VORNOI_REGION) { 
    +        // We need to make sure we're in the RIGHT_VORNOI_REGION of the previous edge.
    +        edge.copy(polygon['edges'][prev]);
    +        // Calculate the center of the circle relative the starting point of the previous edge
    +        var point2 = T_VECTORS.pop().copy(circlePos).sub(points[prev]);
    +        region = vornoiRegion(edge, point2);
    +        if (region === RIGHT_VORNOI_REGION) {
    +          // It's in the region we want.  Check if the circle intersects the point.
    +          var dist = point.len();
    +          if (dist > radius) {
    +            // No intersection
    +            T_VECTORS.push(circlePos); 
    +            T_VECTORS.push(edge);
    +            T_VECTORS.push(point); 
    +            T_VECTORS.push(point2);
    +            return false;
    +          } else if (response) {
    +            // It intersects, calculate the overlap.
    +            response['bInA'] = false;
    +            overlapN = point.normalize();
    +            overlap = radius - dist;
    +          }
    +        }
    +        T_VECTORS.push(point2);
    +      // If it's the right region:
    +      } else if (region === RIGHT_VORNOI_REGION) {
    +        // We need to make sure we're in the left region on the next edge
    +        edge.copy(polygon['edges'][next]);
    +        // Calculate the center of the circle relative to the starting point of the next edge.
    +        point.copy(circlePos).sub(points[next]);
    +        region = vornoiRegion(edge, point);
    +        if (region === LEFT_VORNOI_REGION) {
    +          // It's in the region we want.  Check if the circle intersects the point.
    +          var dist = point.len();
    +          if (dist > radius) {
    +            // No intersection
    +            T_VECTORS.push(circlePos); 
    +            T_VECTORS.push(edge); 
    +            T_VECTORS.push(point);
    +            return false;              
    +          } else if (response) {
    +            // It intersects, calculate the overlap.
    +            response['bInA'] = false;
    +            overlapN = point.normalize();
    +            overlap = radius - dist;
    +          }
    +        }
    +      // Otherwise, it's the middle region:
    +      } else {
    +        // Need to check if the circle is intersecting the edge,
    +        // Change the edge into its "edge normal".
    +        var normal = edge.perp().normalize();
    +        // Find the perpendicular distance between the center of the 
    +        // circle and the edge.
    +        var dist = point.dot(normal);
    +        var distAbs = Math.abs(dist);
    +        // If the circle is on the outside of the edge, there is no intersection.
    +        if (dist > 0 && distAbs > radius) {
    +          // No intersection
    +          T_VECTORS.push(circlePos); 
    +          T_VECTORS.push(normal); 
    +          T_VECTORS.push(point);
    +          return false;
    +        } else if (response) {
    +          // It intersects, calculate the overlap.
    +          overlapN = normal;
    +          overlap = radius - dist;
    +          // If the center of the circle is on the outside of the edge, or part of the
    +          // circle is on the outside, the circle is not fully inside the polygon.
    +          if (dist >= 0 || overlap < 2 * radius) {
    +            response['bInA'] = false;
    +          }
    +        }
    +      }
    +      
    +      // If this is the smallest overlap we've seen, keep it. 
    +      // (overlapN may be null if the circle was in the wrong Vornoi region).
    +      if (overlapN && response && Math.abs(overlap) < Math.abs(response['overlap'])) {
    +        response['overlap'] = overlap;
    +        response['overlapN'].copy(overlapN);
    +      }
    +    }
    +    
    +    // Calculate the final overlap vector - based on the smallest overlap.
    +    if (response) {
    +      response['a'] = polygon;
    +      response['b'] = circle;
    +      response['overlapV'].copy(response['overlapN']).scale(response['overlap']);
    +    }
    +    T_VECTORS.push(circlePos); 
    +    T_VECTORS.push(edge); 
    +    T_VECTORS.push(point);
    +    return true;
    +  }
    +  SAT['testPolygonCircle'] = testPolygonCircle;
    +  
    +  // Check if a circle and a polygon collide.
    +  //
    +  // **NOTE:** This is slightly less efficient than polygonCircle as it just
    +  // runs polygonCircle and reverses everything at the end.
    +  /**
    +   * @param {Circle} circle The circle.
    +   * @param {Polygon} polygon The polygon.
    +   * @param {Response=} response Response object (optional) that will be populated if
    +   *   they interset.
    +   * @return {boolean} true if they intersect, false if they don't.
    +   */
    +  function testCirclePolygon(circle, polygon, response) {
    +    // Test the polygon against the circle.
    +    var result = testPolygonCircle(polygon, circle, response);
    +    if (result && response) {
    +      // Swap A and B in the response.
    +      var a = response['a'];
    +      var aInB = response['aInB'];
    +      response['overlapN'].reverse();
    +      response['overlapV'].reverse();
    +      response['a'] = response['b'];
    +      response['b'] = a;
    +      response['aInB'] = response['bInA'];
    +      response['bInA'] = aInB;
    +    }
    +    return result;
    +  }
    +  SAT['testCirclePolygon'] = testCirclePolygon;
    +  
    +  // Checks whether polygons collide.
    +  /**
    +   * @param {Polygon} a The first polygon.
    +   * @param {Polygon} b The second polygon.
    +   * @param {Response=} response Response object (optional) that will be populated if
    +   *   they interset.
    +   * @return {boolean} true if they intersect, false if they don't.
    +   */
    +  function testPolygonPolygon(a, b, response) {
    +    var aPoints = a['points'];
    +    var aLen = aPoints.length;
    +    var bPoints = b['points'];
    +    var bLen = bPoints.length;
    +    // If any of the edge normals of A is a separating axis, no intersection.
    +    for (var i = 0; i < aLen; i++) {
    +      if (isSeparatingAxis(a['pos'], b['pos'], aPoints, bPoints, a['normals'][i], response)) {
    +        return false;
    +      }
    +    }
    +    // If any of the edge normals of B is a separating axis, no intersection.
    +    for (var i = 0;i < bLen; i++) {
    +      if (isSeparatingAxis(a['pos'], b['pos'], aPoints, bPoints, b['normals'][i], response)) {
    +        return false;
    +      }
    +    }
    +    // Since none of the edge normals of A or B are a separating axis, there is an intersection
    +    // and we've already calculated the smallest overlap (in isSeparatingAxis).  Calculate the
    +    // final overlap vector.
    +    if (response) {
    +      response['a'] = a;
    +      response['b'] = b;
    +      response['overlapV'].copy(response['overlapN']).scale(response['overlap']);
    +    }
    +    return true;
    +  }
    +  SAT['testPolygonPolygon'] = testPolygonPolygon;
    +
    +  return SAT;
    +}));
    +
    +
    + + + + + +
    + +
    +
    + + + + Phaser Copyright © 2012-2014 Photon Storm Ltd. + +
    + + + Documentation generated by JSDoc 3.3.0-dev + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + diff --git a/docs/Signal.js.html b/docs/Signal.js.html index da14fe14..02fe379b 100644 --- a/docs/Signal.js.html +++ b/docs/Signal.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -723,6 +717,8 @@ Phaser.Signal.prototype = {
         }
     
     };
    +
    +Phaser.Signal.prototype.constructor = Phaser.Signal;
     
    @@ -738,13 +734,13 @@ Phaser.Signal.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/SignalBinding.html b/docs/SignalBinding.html index 08019875..b3c0f540 100644 --- a/docs/SignalBinding.html +++ b/docs/SignalBinding.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -733,13 +727,13 @@ Inspired by Joa Ebert AS3 SignalBinding and Robert Penner's Slot classes.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:36 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:37 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/SignalBinding.js.html b/docs/SignalBinding.js.html index 795bcae8..8bc0854f 100644 --- a/docs/SignalBinding.js.html +++ b/docs/SignalBinding.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -583,6 +577,8 @@ Phaser.SignalBinding.prototype = {
         }
     
     };
    +
    +Phaser.SignalBinding.prototype.constructor = Phaser.SignalBinding;
     
    @@ -598,13 +594,13 @@ Phaser.SignalBinding.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/SinglePad.js.html b/docs/SinglePad.js.html new file mode 100644 index 00000000..af2fdfca --- /dev/null +++ b/docs/SinglePad.js.html @@ -0,0 +1,1048 @@ + + + + + + Phaser Source: input/SinglePad.js + + + + + + + + + + +
    + + +
    + + +
    + +
    + + + +

    Source: input/SinglePad.js

    + +
    +
    +
    /**
    +* @author       @karlmacklin <tacklemcclean@gmail.com>
    +* @copyright    2014 Photon Storm Ltd.
    +* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
    +*/
    +
    +/**
    +* @class Phaser.SinglePad
    +* @classdesc A single Phaser Gamepad
    +* @constructor
    +* @param {Phaser.Game} game - Current game instance.
    +* @param {Object} padParent - The parent Phaser.Gamepad object (all gamepads reside under this)
    +*/
    +Phaser.SinglePad = function (game, padParent) {
    +
    +    /**
    +    * @property {Phaser.Game} game - Local reference to game.
    +    */
    +    this.game = game;
    +
    +    /**
    +    * @property {Phaser.Gamepad} padParent - Main Phaser Gamepad object
    +    */
    +    this._padParent = padParent;
    +
    +    /**
    +    * @property {number} index - The gamepad index as per browsers data
    +    * @default
    +    */
    +    this._index = null;
    +
    +    /**
    +    * @property {Object} _rawPad - The 'raw' gamepad data.
    +    * @private
    +    */
    +    this._rawPad = null;
    +
    +    /**
    +    * @property {boolean} _connected - Is this pad connected or not.
    +    * @private
    +    */
    +    this._connected = false;
    +
    +    /**
    +    * @property {number} _prevTimestamp - Used to check for differences between earlier polls and current state of gamepads.
    +    * @private
    +    */
    +    this._prevTimestamp = null;
    +
    +    /**
    +    * @property {Array} _rawButtons - The 'raw' button state.
    +    * @private
    +    */
    +    this._rawButtons = [];
    +
    +    /**
    +    * @property {Array} _buttons - Current Phaser state of the buttons.
    +    * @private
    +    */
    +    this._buttons = [];
    +
    +    /**
    +    * @property {Array} _axes - Current axes state.
    +    * @private
    +    */
    +    this._axes = [];
    +
    +    /**
    +    * @property {Array} _hotkeys - Hotkey buttons.
    +    * @private
    +    */
    +    this._hotkeys = [];
    +
    +    /**
    +    * @property {Object} callbackContext - The context under which the callbacks are run.
    +    */
    +    this.callbackContext = this;
    +
    +    /**
    +    * @property {function} onConnectCallback - This callback is invoked every time this gamepad is connected
    +    */
    +    this.onConnectCallback = null;
    +
    +    /**
    +    * @property {function} onDisconnectCallback - This callback is invoked every time this gamepad is disconnected
    +    */
    +    this.onDisconnectCallback = null;
    +
    +    /**
    +    * @property {function} onDownCallback - This callback is invoked every time a button is pressed down.
    +    */
    +    this.onDownCallback = null;
    +
    +    /**
    +    * @property {function} onUpCallback - This callback is invoked every time a gamepad button is released.
    +    */
    +    this.onUpCallback = null;
    +
    +    /**
    +    * @property {function} onAxisCallback - This callback is invoked every time an axis is changed.
    +    */
    +    this.onAxisCallback = null;
    +
    +    /**
    +    * @property {function} onFloatCallback - This callback is invoked every time a button is changed to a value where value > 0 and value < 1.
    +    */
    +    this.onFloatCallback = null;
    +
    +    /**
    +    * @property {number} deadZone - Dead zone for axis feedback - within this value you won't trigger updates.
    +    */
    +    this.deadZone = 0.26;
    +
    +};
    +
    +Phaser.SinglePad.prototype = {
    +
    +    /**
    +    * Add callbacks to the this Gamepad to handle connect/disconnect/button down/button up/axis change/float value buttons
    +    * @method Phaser.Gamepad#addCallbacks
    +    * @param {Object} context - The context under which the callbacks are run.
    +    * @param {Object} callbacks - Object that takes six different callbak methods:
    +    * onConnectCallback, onDisconnectCallback, onDownCallback, onUpCallback, onAxisCallback, onFloatCallback
    +    */
    +    addCallbacks: function (context, callbacks) {
    +
    +        if (typeof callbacks !== 'undefined')
    +        {
    +            this.onConnectCallback = (typeof callbacks.onConnect === 'function') ? callbacks.onConnect : this.onConnectCallback;
    +            this.onDisconnectCallback = (typeof callbacks.onDisconnect === 'function') ? callbacks.onDisconnect : this.onDisconnectCallback;
    +            this.onDownCallback = (typeof callbacks.onDown === 'function') ? callbacks.onDown : this.onDownCallback;
    +            this.onUpCallback = (typeof callbacks.onUp === 'function') ? callbacks.onUp : this.onUpCallback;
    +            this.onAxisCallback = (typeof callbacks.onAxis === 'function') ? callbacks.onAxis : this.onAxisCallback;
    +            this.onFloatCallback = (typeof callbacks.onFloat === 'function') ? callbacks.onFloat : this.onFloatCallback;
    +        }
    +
    +    },
    +
    +    /**
    +    * If you need more fine-grained control over a Key you can create a new Phaser.Key object via this method.
    +    * The Key object can then be polled, have events attached to it, etc.
    +    *
    +    * @method Phaser.SinglePad#addButton
    +    * @param {number} buttonCode - The buttonCode of the button, i.e. Phaser.Gamepad.BUTTON_0 or Phaser.Gamepad.BUTTON_1
    +    * @return {Phaser.GamepadButton} The GamepadButton object which you can store locally and reference directly.
    +    */
    +    addButton: function (buttonCode) {
    +
    +        this._hotkeys[buttonCode] = new Phaser.GamepadButton(this.game, buttonCode);
    +        return this._hotkeys[buttonCode];
    +
    +    },
    +
    +    /**
    +    * Main update function, should be called by Phaser.Gamepad
    +    * @method Phaser.SinglePad#pollStatus
    +    */
    +    pollStatus: function () {
    +
    +        if (this._rawPad.timestamp && (this._rawPad.timestamp == this._prevTimestamp))
    +        {
    +            return;
    +        }
    +
    +        for (var i = 0; i < this._rawPad.buttons.length; i += 1)
    +        {
    +            var buttonValue = this._rawPad.buttons[i];
    +
    +            if (this._rawButtons[i] !== buttonValue)
    +            {
    +                if (buttonValue === 1)
    +                {
    +                    this.processButtonDown(i, buttonValue);
    +                }
    +                else if (buttonValue === 0)
    +                {
    +                    this.processButtonUp(i, buttonValue);
    +                }
    +                else
    +                {
    +                    this.processButtonFloat(i, buttonValue);
    +                }
    +
    +                this._rawButtons[i] = buttonValue;
    +            }
    +        }
    +
    +        var axes = this._rawPad.axes;
    +
    +        for (var j = 0; j < axes.length; j += 1)
    +        {
    +            var axis = axes[j];
    +
    +            if (axis > 0 && axis > this.deadZone || axis < 0 && axis < -this.deadZone)
    +            {
    +                this.processAxisChange({axis: j, value: axis});
    +            }
    +            else
    +            {
    +                this.processAxisChange({axis: j, value: 0});
    +            }
    +        }
    +
    +        this._prevTimestamp = this._rawPad.timestamp;
    +
    +    },
    +
    +    /**
    +    * Gamepad connect function, should be called by Phaser.Gamepad
    +    * @param {Object} rawPad - The raw gamepad object
    +    * @method Phaser.SinglePad#connect
    +    */
    +    connect: function (rawPad) {
    +
    +        var triggerCallback = !this._connected;
    +
    +        this._index = rawPad.index;
    +        this._connected = true;
    +        this._rawPad = rawPad;
    +        this._rawButtons = rawPad.buttons;
    +        this._axes = rawPad.axes;
    +
    +        if (triggerCallback && this._padParent.onConnectCallback)
    +        {
    +            this._padParent.onConnectCallback.call(this._padParent.callbackContext, this._index);
    +        }
    +
    +        if (triggerCallback && this.onConnectCallback)
    +        {
    +            this.onConnectCallback.call(this.callbackContext);
    +        }
    +
    +    },
    +
    +    /**
    +    * Gamepad disconnect function, should be called by Phaser.Gamepad
    +    * @method Phaser.SinglePad#disconnect
    +    */
    +    disconnect: function () {
    +
    +        var triggerCallback = this._connected;
    +        this._connected = false;
    +        this._rawPad = undefined;
    +        this._rawButtons = [];
    +        this._buttons = [];
    +        var disconnectingIndex = this._index;
    +        this._index = null;
    +
    +        if (triggerCallback && this._padParent.onDisconnectCallback)
    +        {
    +            this._padParent.onDisconnectCallback.call(this._padParent.callbackContext, disconnectingIndex);
    +        }
    +
    +        if (triggerCallback && this.onDisconnectCallback)
    +        {
    +            this.onDisconnectCallback.call(this.callbackContext);
    +        }
    +
    +    },
    +
    +    /**
    +    * Handles changes in axis
    +    * @param {Object} axisState - State of the relevant axis
    +    * @method Phaser.SinglePad#processAxisChange
    +    */
    +    processAxisChange: function (axisState) {
    +
    +        if (this.game.input.disabled || this.game.input.gamepad.disabled)
    +        {
    +            return;
    +        }
    +
    +        if (this._axes[axisState.axis] === axisState.value)
    +        {
    +            return;
    +        }
    +
    +        this._axes[axisState.axis] = axisState.value;
    +        
    +        if (this._padParent.onAxisCallback)
    +        {
    +            this._padParent.onAxisCallback.call(this._padParent.callbackContext, axisState, this._index);
    +        }
    +
    +        if (this.onAxisCallback)
    +        {
    +            this.onAxisCallback.call(this.callbackContext, axisState);
    +        }
    +
    +    },
    +
    +    /**
    +    * Handles button down press
    +    * @param {number} buttonCode - Which buttonCode of this button
    +    * @param {Object} value - Button value
    +    * @method Phaser.SinglePad#processButtonDown
    +    */
    +    processButtonDown: function (buttonCode, value) {
    +
    +        if (this.game.input.disabled || this.game.input.gamepad.disabled)
    +        {
    +            return;
    +        }
    +
    +        if (this._padParent.onDownCallback)
    +        {
    +            this._padParent.onDownCallback.call(this._padParent.callbackContext, buttonCode, value, this._index);
    +        }
    +
    +        if (this.onDownCallback)
    +        {
    +            this.onDownCallback.call(this.callbackContext, buttonCode, value);
    +        }
    +
    +        if (this._buttons[buttonCode] && this._buttons[buttonCode].isDown)
    +        {
    +            //  Key already down and still down, so update
    +            this._buttons[buttonCode].duration = this.game.time.now - this._buttons[buttonCode].timeDown;
    +        }
    +        else
    +        {
    +            if (!this._buttons[buttonCode])
    +            {
    +                //  Not used this button before, so register it
    +                this._buttons[buttonCode] = {
    +                    isDown: true,
    +                    timeDown: this.game.time.now,
    +                    timeUp: 0,
    +                    duration: 0,
    +                    value: value
    +                };
    +            }
    +            else
    +            {
    +                //  Button used before but freshly down
    +                this._buttons[buttonCode].isDown = true;
    +                this._buttons[buttonCode].timeDown = this.game.time.now;
    +                this._buttons[buttonCode].duration = 0;
    +                this._buttons[buttonCode].value = value;
    +            }
    +        }
    +
    +        if (this._hotkeys[buttonCode])
    +        {
    +            this._hotkeys[buttonCode].processButtonDown(value);
    +        }
    +
    +    },
    +
    +    /**
    +    * Handles button release
    +    * @param {number} buttonCode - Which buttonCode of this button
    +    * @param {Object} value - Button value
    +    * @method Phaser.SinglePad#processButtonUp
    +    */
    +    processButtonUp: function (buttonCode, value) {
    +
    +        if (this.game.input.disabled || this.game.input.gamepad.disabled)
    +        {
    +            return;
    +        }
    +
    +        if (this._padParent.onUpCallback)
    +        {
    +            this._padParent.onUpCallback.call(this._padParent.callbackContext, buttonCode, value, this._index);
    +        }
    +
    +        if (this.onUpCallback)
    +        {
    +            this.onUpCallback.call(this.callbackContext, buttonCode, value);
    +        }
    +
    +        if (this._hotkeys[buttonCode])
    +        {
    +            this._hotkeys[buttonCode].processButtonUp(value);
    +        }
    +
    +        if (this._buttons[buttonCode])
    +        {
    +            this._buttons[buttonCode].isDown = false;
    +            this._buttons[buttonCode].timeUp = this.game.time.now;
    +            this._buttons[buttonCode].value = value;
    +        }
    +        else
    +        {
    +            //  Not used this button before, so register it
    +            this._buttons[buttonCode] = {
    +                isDown: false,
    +                timeDown: this.game.time.now,
    +                timeUp: this.game.time.now,
    +                duration: 0,
    +                value: value
    +            };
    +        }
    +
    +    },
    +
    +    /**
    +    * Handles buttons with floating values (like analog buttons that acts almost like an axis but still registers like a button)
    +    * @param {number} buttonCode - Which buttonCode of this button
    +    * @param {Object} value - Button value (will range somewhere between 0 and 1, but not specifically 0 or 1.
    +    * @method Phaser.SinglePad#processButtonFloat
    +    */
    +    processButtonFloat: function (buttonCode, value) {
    +
    +        if (this.game.input.disabled || this.game.input.gamepad.disabled)
    +        {
    +            return;
    +        }
    +
    +        if (this._padParent.onFloatCallback)
    +        {
    +            this._padParent.onFloatCallback.call(this._padParent.callbackContext, buttonCode, value, this._index);
    +        }
    +
    +        if (this.onFloatCallback)
    +        {
    +            this.onFloatCallback.call(this.callbackContext, buttonCode, value);
    +        }
    +
    +        if (!this._buttons[buttonCode])
    +        {
    +            //  Not used this button before, so register it
    +            this._buttons[buttonCode] = { value: value };
    +        }
    +        else
    +        {
    +            //  Button used before but freshly down
    +            this._buttons[buttonCode].value = value;
    +        }
    +
    +        if (this._hotkeys[buttonCode])
    +        {
    +            this._hotkeys[buttonCode].processButtonFloat(value);
    +        }
    +
    +    },
    +
    +    /**
    +    * Returns value of requested axis
    +    * @method Phaser.SinglePad#isDown
    +    * @param {number} axisCode - The index of the axis to check
    +    * @return {number} Axis value if available otherwise false
    +    */
    +    axis: function (axisCode) {
    +
    +        if (this._axes[axisCode])
    +        {
    +            return this._axes[axisCode];
    +        }
    +
    +        return false;
    +
    +    },
    +
    +    /**
    +    * Returns true if the button is currently pressed down.
    +    * @method Phaser.SinglePad#isDown
    +    * @param {number} buttonCode - The buttonCode of the key to check.
    +    * @return {boolean} True if the key is currently down.
    +    */
    +    isDown: function (buttonCode) {
    +
    +        if (this._buttons[buttonCode])
    +        {
    +            return this._buttons[buttonCode].isDown;
    +        }
    +
    +        return false;
    +
    +    },
    +
    +    /**
    +    * Returns the "just released" state of a button from this gamepad. Just released is considered as being true if the button was released within the duration given (default 250ms).
    +    * @method Phaser.SinglePad#justPressed
    +    * @param {number} buttonCode - The buttonCode of the button to check for.
    +    * @param {number} [duration=250] - The duration below which the button is considered as being just released.
    +    * @return {boolean} True if the button is just released otherwise false.
    +    */
    +    justReleased: function (buttonCode, duration) {
    +
    +        if (typeof duration === "undefined") { duration = 250; }
    +
    +        return (this._buttons[buttonCode] && this._buttons[buttonCode].isDown === false && (this.game.time.now - this._buttons[buttonCode].timeUp < duration));
    +
    +    },
    +
    +    /**
    +    * Returns the "just pressed" state of a button from this gamepad. Just pressed is considered true if the button was pressed down within the duration given (default 250ms).
    +    * @method Phaser.SinglePad#justPressed
    +    * @param {number} buttonCode - The buttonCode of the button to check for.
    +    * @param {number} [duration=250] - The duration below which the button is considered as being just pressed.
    +    * @return {boolean} True if the button is just pressed otherwise false.
    +    */
    +    justPressed: function (buttonCode, duration) {
    +
    +        if (typeof duration === "undefined") { duration = 250; }
    +
    +        return (this._buttons[buttonCode] && this._buttons[buttonCode].isDown && this._buttons[buttonCode].duration < duration);
    +
    +    },
    +
    +    /**
    +    * Returns the value of a gamepad button. Intended mainly for cases when you have floating button values, for example
    +    * analog trigger buttons on the XBOX 360 controller
    +    * @method Phaser.SinglePad#buttonValue
    +    * @param {number} buttonCode - The buttonCode of the button to check.
    +    * @return {boolean} Button value if available otherwise false.
    +    */
    +    buttonValue: function (buttonCode) {
    +
    +        if (this._buttons[buttonCode])
    +        {
    +            return this._buttons[buttonCode].value;
    +        }
    +
    +        return false;
    +
    +    },
    +
    +    /**
    +    * Reset all buttons/axes of this gamepad
    +    * @method Phaser.SinglePad#reset
    +    */
    +    reset: function () {
    +
    +        for (var i = 0; i < this._buttons.length; i++)
    +        {
    +            this._buttons[i] = 0;
    +        }
    +
    +        for (var j = 0; j < this._axes.length; j++)
    +        {
    +            this._axes[j] = 0;
    +        }
    +
    +    }
    +
    +};
    +
    +Phaser.SinglePad.prototype.constructor = Phaser.SinglePad;
    +
    +/**
    + * Whether or not this particular gamepad is connected or not.
    + * @name Phaser.SinglePad#connected
    + * @property {boolean} connected - Whether or not this particular gamepad is connected or not.
    + * @readonly
    + */
    +Object.defineProperty(Phaser.SinglePad.prototype, "connected", {
    +
    +    get: function () {
    +        return this._connected;
    +    }
    +
    +});
    +
    +/**
    + * Gamepad index as per browser data
    + * @name Phaser.SinglePad#index
    + * @property {number} index - The gamepad index, used to identify specific gamepads in the browser
    + * @readonly
    + */
    +Object.defineProperty(Phaser.SinglePad.prototype, "index", {
    +
    +    get: function () {
    +        return this._index;
    +    }
    +
    +});
    +
    +
    +
    + + + + + +
    + +
    +
    + + + + Phaser Copyright © 2012-2014 Photon Storm Ltd. + +
    + + + Documentation generated by JSDoc 3.3.0-dev + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + diff --git a/docs/Sound.js.html b/docs/Sound.js.html index 7db91a13..03167d6d 100644 --- a/docs/Sound.js.html +++ b/docs/Sound.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -769,25 +763,25 @@ Phaser.Sound.prototype = {
                     {
                         if (this.loop)
                         {
    -                        //console.log('loop1');
    +                        // console.log('loop1');
                             //  won't work with markers, needs to reset the position
                             this.onLoop.dispatch(this);
     
                             if (this.currentMarker === '')
                             {
    -                            //console.log('loop2');
    +                            // console.log('loop2');
                                 this.currentTime = 0;
                                 this.startTime = this.game.time.now;
                             }
                             else
                             {
    -                            //console.log('loop3');
    +                            // console.log('loop3');
                                 this.play(this.currentMarker, 0, this.volume, true, true);
                             }
                         }
                         else
                         {
    -                        //console.log('stopping, no loop for marker');
    +                        // console.log('stopping, no loop for marker');
                             this.stop();
                         }
                     }
    @@ -975,7 +969,7 @@ Phaser.Sound.prototype = {
                 else
                 {
                     // console.log('sound not locked, state?', this._sound.readyState);
    -                if (this._sound && this._sound.readyState == 4)
    +                if (this._sound && (this.game.device.cocoonJS || this._sound.readyState === 4))
                     {
                         this._sound.play();
                         //  This doesn't become available until you call play(), wonderful ...
    @@ -1065,7 +1059,20 @@ Phaser.Sound.prototype = {
     
                     this._sound = this.context.createBufferSource();
                     this._sound.buffer = this._buffer;
    -                this._sound.connect(this.gainNode);
    +
    +                if (this.externalNode)
    +                {
    +                    this._sound.connect(this.externalNode.input);
    +                }
    +                else
    +                {
    +                    this._sound.connect(this.gainNode);
    +                }
    +
    +                if (this.loop)
    +                {
    +                    this._sound.loop = true;
    +                }
     
                     if (typeof this._sound.start === 'undefined')
                     {
    @@ -1126,6 +1133,8 @@ Phaser.Sound.prototype = {
     
     };
     
    +Phaser.Sound.prototype.constructor = Phaser.Sound;
    +
     /**
     * @name Phaser.Sound#isDecoding
     * @property {boolean} isDecoding - Returns true if the sound file is still decoding.
    @@ -1246,13 +1255,13 @@ Object.defineProperty(Phaser.Sound.prototype, "volume", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/SoundManager.js.html b/docs/SoundManager.js.html index ef9762a0..6fa385c5 100644 --- a/docs/SoundManager.js.html +++ b/docs/SoundManager.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -711,7 +705,7 @@ Phaser.SoundManager.prototype = {
                         that.game.cache.decodedSound(key, buffer);
                         if (sound)
                         {
    -                        that.onSoundDecode.dispatch(sound);
    +                        that.onSoundDecode.dispatch(key, sound);
                         }
                     });
                 }
    @@ -792,6 +786,8 @@ Phaser.SoundManager.prototype = {
     
     };
     
    +Phaser.SoundManager.prototype.constructor = Phaser.SoundManager;
    +
     /**
     * @name Phaser.SoundManager#mute
     * @property {boolean} mute - Gets or sets the muted state of the SoundManager. This effects all sounds in the game.
    @@ -916,13 +912,13 @@ Object.defineProperty(Phaser.SoundManager.prototype, "volume", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Sprite.js.html b/docs/Sprite.js.html index 41ff5ec3..cce3609a 100644 --- a/docs/Sprite.js.html +++ b/docs/Sprite.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -632,6 +626,7 @@ Phaser.Sprite = function (game, x, y, key, frame) {
         */
         this._cache = {
     
    +        fresh: true,
             dirty: false,
     
             //  Transform cache
    @@ -777,7 +772,7 @@ Phaser.Sprite = function (game, x, y, key, frame) {
         /**
         * @property {Phaser.Point} cameraOffset - If this Sprite is fixed to the camera then use this Point to specify how far away from the Camera x/y it's rendered.
         */
    -    this.cameraOffset = new Phaser.Point();
    +    this.cameraOffset = new Phaser.Point(x, y);
     
         /**
         * You can crop the Sprites texture by modifying the crop properties. For example crop.width = 50 would set the Sprite to only render 50px wide.
    @@ -793,9 +788,19 @@ Phaser.Sprite = function (game, x, y, key, frame) {
         */
         this.cropEnabled = false;
     
    +    /**
    +    * @property {boolean} debug - Handy flag to use with Game.enableStep
    +    * @default
    +    */
    +    this.debug = false;
    +
         this.updateCache();
         this.updateBounds();
     
    +    /**
    +    * @property {PIXI.Point} pivot - The pivot point of the displayObject that it rotates around.
    +    */
    +
     };
     
     //  Needed to keep the PIXI.Sprite constructor in the prototype chain (as the core pixi renderer uses an instanceof check sadly)
    @@ -810,6 +815,24 @@ Phaser.Sprite.prototype.constructor = Phaser.Sprite;
     */
     Phaser.Sprite.prototype.preUpdate = function() {
     
    +    if (this._cache.fresh)
    +    {
    +        this.world.setTo(this.parent.position.x + this.x, this.parent.position.y + this.y);
    +        this.worldTransform[2] = this.world.x;
    +        this.worldTransform[5] = this.world.y;
    +        this._cache.fresh = false;
    +
    +        if (this.body)
    +        {
    +            this.body.x = (this.world.x - (this.anchor.x * this.width)) + this.body.offset.x;
    +            this.body.y = (this.world.y - (this.anchor.y * this.height)) + this.body.offset.y;
    +            this.body.preX = this.body.x;
    +            this.body.preY = this.body.y;
    +        }
    +
    +        return;
    +    }
    +
         if (!this.exists || (this.group && !this.group.exists))
         {
             this.renderOrderID = -1;
    @@ -925,7 +948,6 @@ Phaser.Sprite.prototype.updateAnimation = function() {
             this._cache.halfHeight = Math.floor(this._cache.height / 2);
     
             this._cache.dirty = true;
    -
         }
     
     };
    @@ -1020,12 +1042,6 @@ Phaser.Sprite.prototype.updateBounds = function() {
             this.renderable = this._cache.cameraVisible;
         }
     
    -    //  Update our physics bounds
    -    if (this.body)
    -    {
    -        this.body.updateBounds(this.center.x, this.center.y, this._cache.scaleX, this._cache.scaleY);
    -    }
    -
     };
     
     /**
    @@ -1036,9 +1052,7 @@ Phaser.Sprite.prototype.updateBounds = function() {
     * @memberof Phaser.Sprite
     * @param {Phaser.Point} p - The Point object to store the results in.
     * @param {number} x - x coordinate within the Sprite to translate.
    -* @param {number} y - x coordinate within the Sprite to translate.
    -* @param {number} sx - Scale factor to be applied.
    -* @param {number} sy - Scale factor to be applied.
    +* @param {number} y - y coordinate within the Sprite to translate.
     * @return {Phaser.Point} The translated point.
     */
     Phaser.Sprite.prototype.getLocalPosition = function(p, x, y) {
    @@ -1057,8 +1071,8 @@ Phaser.Sprite.prototype.getLocalPosition = function(p, x, y) {
     * @method Phaser.Sprite#getLocalUnmodifiedPosition
     * @memberof Phaser.Sprite
     * @param {Phaser.Point} p - The Point object to store the results in.
    -* @param {number} x - x coordinate within the Sprite to translate.
    -* @param {number} y - x coordinate within the Sprite to translate.
    +* @param {number} gx - x coordinate within the Sprite to translate.
    +* @param {number} gy - y coordinate within the Sprite to translate.
     * @return {Phaser.Point} The translated point.
     */
     Phaser.Sprite.prototype.getLocalUnmodifiedPosition = function(p, gx, gy) {
    @@ -1099,7 +1113,6 @@ Phaser.Sprite.prototype.postUpdate = function() {
     
         if (this.exists)
         {
    -        //  The sprite is positioned in this call, after taking into consideration motion updates and collision
             if (this.body)
             {
                 this.body.postUpdate();
    @@ -1116,8 +1129,6 @@ Phaser.Sprite.prototype.postUpdate = function() {
                 this._cache.y = this.y;
             }
     
    -        this.world.setTo(this.game.camera.x + this.worldTransform[2], this.game.camera.y + this.worldTransform[5]);
    -
             this.position.x = this._cache.x;
             this.position.y = this._cache.y;
         }
    @@ -1195,8 +1206,17 @@ Phaser.Sprite.prototype.loadTexture = function (key, frame) {
     */
     Phaser.Sprite.prototype.centerOn = function(x, y) {
     
    -    this.x = x + (this.x - this.center.x);
    -    this.y = y + (this.y - this.center.y);
    +    if (this.fixedToCamera)
    +    {
    +        this.cameraOffset.x = x + (this.cameraOffset.x - this.center.x);
    +        this.cameraOffset.y = y + (this.cameraOffset.y - this.center.y);
    +    }
    +    else
    +    {
    +        this.x = x + (this.x - this.center.x);
    +        this.y = y + (this.y - this.center.y);
    +    }
    +
         return this;
     
     };
    @@ -1263,6 +1283,11 @@ Phaser.Sprite.prototype.kill = function() {
     */
     Phaser.Sprite.prototype.destroy = function() {
     
    +    if (this.filters)
    +    {
    +        this.filters = null;
    +    }
    +
         if (this.group)
         {
             this.group.remove(this);
    @@ -1283,6 +1308,11 @@ Phaser.Sprite.prototype.destroy = function() {
             this.animations.destroy();
         }
     
    +    if (this.body)
    +    {
    +        this.body.destroy();
    +    }
    +
         this.alive = false;
         this.exists = false;
         this.visible = false;
    @@ -1334,6 +1364,7 @@ Phaser.Sprite.prototype.reset = function(x, y, health) {
     
         this.x = x;
         this.y = y;
    +    this.world.setTo(x, y);
         this.position.x = this.x;
         this.position.y = this.y;
         this.alive = true;
    @@ -1346,7 +1377,7 @@ Phaser.Sprite.prototype.reset = function(x, y, health) {
     
         if (this.body)
         {
    -        this.body.reset();
    +        this.body.reset(false);
         }
     
         return this;
    @@ -1397,6 +1428,34 @@ Phaser.Sprite.prototype.play = function (name, frameRate, loop, killOnComplete)
     
     };
     
    +/**
    +* Returns the delta x value. The difference between Sprite.x now and in the previous step.
    +* @name Phaser.Sprite#deltaX
    +* @property {number} deltaX - The delta value. Positive if the motion was to the right, negative if to the left.
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Sprite.prototype, 'deltaX', {
    +
    +    get: function() {
    +        return this.world.x - this._cache.prevX;
    +    }
    +
    +});
    +
    +/**
    +* Returns the delta x value. The difference between Sprite.y now and in the previous step.
    +* @name Phaser.Sprite#deltaY
    +* @property {number} deltaY - The delta value. Positive if the motion was downwards, negative if upwards.
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Sprite.prototype, 'deltaY', {
    +
    +    get: function() {
    +        return this.world.y - this._cache.prevY;
    +    }
    +
    +});
    +
     /**
     * Indicates the rotation of the Sprite, in degrees, from its original orientation. Values from 0 to 180 represent clockwise rotation; values from 0 to -180 represent counterclockwise rotation.
     * Values outside this range are added to or subtracted from 360 to obtain a value within the range. For example, the statement player.angle = 450 is the same as player.angle = 90.
    @@ -1461,6 +1520,32 @@ Object.defineProperty(Phaser.Sprite.prototype, "inCamera", {
     
     });
     
    +/**
    +* @name Phaser.Sprite#worldCenterX
    +* @property {number} worldCenterX - The center of the Sprite in world coordinates.
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Sprite.prototype, "worldCenterX", {
    +    
    +    get: function () {
    +        return this.game.camera.x + this.center.x;
    +    }
    +
    +});
    +
    +/**
    +* @name Phaser.Sprite#worldCenterY
    +* @property {number} worldCenterY - The center of the Sprite in world coordinates.
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Sprite.prototype, "worldCenterY", {
    +    
    +    get: function () {
    +        return this.game.camera.y + this.center.y;
    +    }
    +
    +});
    +
     /**
     * The width of the sprite in pixels, setting this will actually modify the scale to acheive the value desired.
     * If you wish to crop the Sprite instead see the Sprite.crop value.
    @@ -1524,8 +1609,6 @@ Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", {
     
         set: function (value) {
     
    -        console.log('inputEnabled', value, this.input);
    -
             if (value)
             {
                 if (this.input.enabled === false)
    @@ -1559,13 +1642,13 @@ Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Stage.js.html b/docs/Stage.js.html index ea337d27..61e45c67 100644 --- a/docs/Stage.js.html +++ b/docs/Stage.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -447,7 +441,6 @@ Phaser.Stage = function (game, width, height) {
         /**
         * @property {string} game - Background color of the stage (defaults to black). Set via the public backgroundColor property.
         * @private
    -    * @default 'rgb(0,0,0)'
         */
         this._backgroundColor = 'rgb(0,0,0)';
     
    @@ -457,10 +450,9 @@ Phaser.Stage = function (game, width, height) {
         this.offset = new Phaser.Point();
         
         /**
    -    * @property {HTMLCanvasElement} canvas - Reference to the newly created <canvas> element.
    +    * @property {HTMLCanvasElement} canvas - Reference to the newly created `canvas` element.
         */
    -    this.canvas = Phaser.Canvas.create(width, height);
    -    this.canvas.style['-webkit-full-screen'] = 'width: 100%; height: 100%';
    +    this.canvas = null;
         
         /**
         * @property {PIXI.Stage} _stage - The Pixi Stage which is hooked to the renderer.
    @@ -470,11 +462,21 @@ Phaser.Stage = function (game, width, height) {
         this._stage.name = '_stage_root';
         this._stage.interactive = false;
     
    +    /**
    +    * @property {PIXI.Stage} display - The Pixi Stage which is hooked to the renderer.
    +    */
    +    this.display = this._stage;
    +
         /**
         * @property {number} scaleMode - The current scaleMode.
         */
         this.scaleMode = Phaser.StageScaleMode.NO_SCALE;
     
    +    /*
    +    * @property {number} fullScreenScaleMode - Scale mode to be used in fullScreen
    +     */
    +    this.fullScreenScaleMode = Phaser.StageScaleMode.NO_SCALE;
    +
         /**
         * @property {Phaser.StageScaleMode} scale - The scale of the current running game.
         */
    @@ -485,6 +487,12 @@ Phaser.Stage = function (game, width, height) {
         */
         this.aspectRatio = width / height;
     
    +    /**
    +    * @property {boolean} disableVisibilityChange - By default if the browser tab loses focus the game will pause. You can stop that behaviour by setting this property to true.
    +    * @default
    +    */
    +    this.disableVisibilityChange = false;
    +
         /**
         * @property {number} _nextOffsetCheck - The time to run the next offset check.
         * @private
    @@ -497,10 +505,73 @@ Phaser.Stage = function (game, width, height) {
         */
         this.checkOffsetInterval = 2500;
     
    +    if (game.config)
    +    {
    +        this.parseConfig(game.config);
    +    }
    +    else
    +    {
    +        this.canvas = Phaser.Canvas.create(width, height);
    +        this.canvas.style['-webkit-full-screen'] = 'width: 100%; height: 100%';
    +    }
    +
     };
     
     Phaser.Stage.prototype = {
     
    +    /**
    +    * Parses a Game configuration object.
    +    *
    +    * @method Phaser.Stage#parseConfig
    +    * @protected
    +    */
    +    parseConfig: function (config) {
    +
    +        if (config['canvasID'])
    +        {
    +            this.canvas = Phaser.Canvas.create(this.game.width, this.game.height, config['canvasID']);
    +        }
    +        else
    +        {
    +            this.canvas = Phaser.Canvas.create(this.game.width, this.game.height);
    +        }
    +
    +        if (config['canvasStyle'])
    +        {
    +            this.canvas.stlye = config['canvasStyle'];
    +        }
    +        else
    +        {
    +            this.canvas.style['-webkit-full-screen'] = 'width: 100%; height: 100%';
    +        }
    +
    +        if (config['checkOffsetInterval'])
    +        {
    +            this.checkOffsetInterval = config['checkOffsetInterval'];
    +        }
    +
    +        if (config['disableVisibilityChange'])
    +        {
    +            this.disableVisibilityChange = config['disableVisibilityChange'];
    +        }
    +
    +        if (config['fullScreenScaleMode'])
    +        {
    +            this.fullScreenScaleMode = config['fullScreenScaleMode'];
    +        }
    +
    +        if (config['scaleMode'])
    +        {
    +            this.scaleMode = config['scaleMode'];
    +        }
    +
    +        if (config['backgroundColor'])
    +        {
    +            this.backgroundColor = config['backgroundColor'];
    +        }
    +
    +    },
    +
         /**
         * Initialises the stage and adds the event listeners.
         * @method Phaser.Stage#boot
    @@ -563,7 +634,7 @@ Phaser.Stage.prototype = {
                 return;
             }
     
    -        if (event.type == 'pagehide' || event.type == 'blur' || document['hidden'] === true || document['webkitHidden'] === true)
    +        if (this.game.paused === false && (event.type == 'pagehide' || event.type == 'blur' || document['hidden'] === true || document['webkitHidden'] === true))
             {
                 this.game.paused = true;
             }
    @@ -576,6 +647,8 @@ Phaser.Stage.prototype = {
     
     };
     
    +Phaser.Stage.prototype.constructor = Phaser.Stage;
    +
     /**
     * @name Phaser.Stage#backgroundColor
     * @property {number|string} backgroundColor - Gets and sets the background color of the stage. The color can be given as a number: 0xff0000 or a hex string: '#ff0000'
    @@ -627,13 +700,13 @@ Object.defineProperty(Phaser.Stage.prototype, "backgroundColor", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/StageScaleMode.js.html b/docs/StageScaleMode.js.html index 93f2d900..156a13d6 100644 --- a/docs/StageScaleMode.js.html +++ b/docs/StageScaleMode.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -683,7 +677,8 @@ Phaser.StageScaleMode.prototype = {
             this._width = this.width;
             this._height = this.height;
     
    -        console.log('startFullScreen', this._width, this._height);
    +        //  This needs updating to match the final spec:
    +        //  http://generatedcontent.org/post/70347573294/is-your-fullscreen-api-code-up-to-date-find-out-how-to
     
             if (element['requestFullScreen'])
             {
    @@ -691,7 +686,7 @@ Phaser.StageScaleMode.prototype = {
             }
             else if (element['mozRequestFullScreen'])
             {
    -            element['mozRequestFullScreen']();
    +            element.parentNode['mozRequestFullScreen']();
             }
             else if (element['webkitRequestFullScreen'])
             {
    @@ -733,16 +728,24 @@ Phaser.StageScaleMode.prototype = {
     
             if (this.isFullScreen)
             {
    -            this.game.stage.canvas.style['width'] = '100%';
    -            this.game.stage.canvas.style['height'] = '100%';
    +            if (this.game.stage.fullScreenScaleMode === Phaser.StageScaleMode.EXACT_FIT)
    +            {
    +                this.game.stage.canvas.style['width'] = '100%';
    +                this.game.stage.canvas.style['height'] = '100%';
     
    -            this.setMaximum();
    +                this.setMaximum();
     
    -            this.game.input.scale.setTo(this.game.width / this.width, this.game.height / this.height);
    +                this.game.input.scale.setTo(this.game.width / this.width, this.game.height / this.height);
     
    -            this.aspectRatio = this.width / this.height;
    -            this.scaleFactor.x = this.game.width / this.width;
    -            this.scaleFactor.y = this.game.height / this.height;
    +                this.aspectRatio = this.width / this.height;
    +                this.scaleFactor.x = this.game.width / this.width;
    +                this.scaleFactor.y = this.game.height / this.height;
    +            }
    +            else if (this.game.stage.fullScreenScaleMode === Phaser.StageScaleMode.SHOW_ALL)
    +            {
    +                this.game.stage.scale.setShowAll();
    +                this.game.stage.scale.refresh();
    +            }
             }
             else
             {
    @@ -983,13 +986,27 @@ Phaser.StageScaleMode.prototype = {
                 {
                     this.setMaximum();
                 }
    -            else if (this.game.stage.scaleMode == Phaser.StageScaleMode.EXACT_FIT)
    +            else if (!this.isFullScreen)
                 {
    -                this.setExactFit();
    +                if (this.game.stage.scaleMode == Phaser.StageScaleMode.EXACT_FIT)
    +                {
    +                    this.setExactFit();
    +                }
    +                else if (this.game.stage.scaleMode == Phaser.StageScaleMode.SHOW_ALL)
    +                {
    +                    this.setShowAll();
    +                }
                 }
    -            else if (this.game.stage.scaleMode == Phaser.StageScaleMode.SHOW_ALL)
    +            else
                 {
    -                this.setShowAll();
    +                if (this.game.stage.fullScreenScaleMode == Phaser.StageScaleMode.EXACT_FIT)
    +                {
    +                    this.setExactFit();
    +                }
    +                else if (this.game.stage.fullScreenScaleMode == Phaser.StageScaleMode.SHOW_ALL)
    +                {
    +                    this.setShowAll();
    +                }
                 }
     
                 this.setSize();
    @@ -1110,8 +1127,6 @@ Phaser.StageScaleMode.prototype = {
             var availableWidth = window.innerWidth;
             var availableHeight = window.innerHeight;
     
    -        // console.log('available', availableWidth, availableHeight);
    -
             if (this.maxWidth && availableWidth > this.maxWidth)
             {
                 this.width = this.maxWidth;
    @@ -1134,6 +1149,8 @@ Phaser.StageScaleMode.prototype = {
     
     };
     
    +Phaser.StageScaleMode.prototype.constructor = Phaser.StageScaleMode;
    +
     /**
     * @name Phaser.StageScaleMode#isFullScreen
     * @property {boolean} isFullScreen - Returns true if the browser is in full screen mode, otherwise false.
    @@ -1189,13 +1206,13 @@ Object.defineProperty(Phaser.StageScaleMode.prototype, "isLandscape", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/State.js.html b/docs/State.js.html index db95688b..b20515cf 100644 --- a/docs/State.js.html +++ b/docs/State.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -590,6 +584,8 @@ Phaser.State.prototype = {
         }
     
     };
    +
    +Phaser.State.prototype.constructor = Phaser.State;
     
    @@ -605,13 +601,13 @@ Phaser.State.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/StateManager.js.html b/docs/StateManager.js.html index aa2184db..e3b8a73f 100644 --- a/docs/StateManager.js.html +++ b/docs/StateManager.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -425,7 +419,7 @@ /** * @author Richard Davey <rich@photonstorm.com> -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -455,7 +449,7 @@ Phaser.StateManager = function (game, pendingState) { */ this._pendingState = null; - if (pendingState !== null) + if (typeof pendingState !== 'undefined' && pendingState !== null) { this._pendingState = pendingState; } @@ -703,7 +697,8 @@ Phaser.StateManager.prototype = { }, /** - * Description. + * Checks i a given phaser state is valid. + * State must exist and have at least one callback function registered.. * @method Phaser.StateManager#checkState * @param {string} key - The key of the state you want to check. * @return {boolean} Description. @@ -770,7 +765,7 @@ Phaser.StateManager.prototype = { * Sets the current State. Should not be called directly (use StateManager.start) * @method Phaser.StateManager#setCurrentState * @param {string} key - State key. - * @protected + * @private */ setCurrentState: function (key) { @@ -800,6 +795,17 @@ Phaser.StateManager.prototype = { }, + /** + * Gets the current State. + * + * @method Phaser.StateManager#getCurrentState + * @return Phaser.State + * @public + */ + getCurrentState: function() { + return this.states[this.current]; + }, + /** * @method Phaser.StateManager#loadComplete * @protected @@ -935,6 +941,8 @@ Phaser.StateManager.prototype = { } }; + +Phaser.StateManager.prototype.constructor = Phaser.StateManager;
    @@ -950,13 +958,13 @@ Phaser.StateManager.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Text.js.html b/docs/Text.js.html index 84b4a4f7..9376f7f1 100644 --- a/docs/Text.js.html +++ b/docs/Text.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,12 +417,12 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
     /**
    -* Create a new <code>Text</code>.
    +* Create a new `Text` object.
     * @class Phaser.Text
     * @constructor
     * @param {Phaser.Game} game - Current game instance.
    @@ -513,6 +507,18 @@ Phaser.Text = function (game, x, y, text, style) {
         */
         this.scale = new Phaser.Point(1, 1);
     
    +    /**
    +    * An object that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera.
    +    * @property {boolean} fixedToCamera - Fixes this object to the Camera.
    +    * @default
    +    */
    +    this.fixedToCamera = false;
    +
    +    /**
    +    * @property {Phaser.Point} cameraOffset - If this object is fixed to the camera then use this Point to specify how far away from the Camera x/y it's rendered.
    +    */
    +    this.cameraOffset = new Phaser.Point(x, y);
    +
         /**
         * @property {object} _cache - A mini cache for storing all of the calculated values.
         * @private
    @@ -564,6 +570,12 @@ Phaser.Text.prototype.update = function() {
             return;
         }
     
    +    if (this.fixedToCamera)
    +    {
    +        this.x = this.game.camera.view.x + this.cameraOffset.x;
    +        this.y = this.game.camera.view.y + this.cameraOffset.y;
    +    }
    +
         this._cache.dirty = false;
     
         this._cache.x = this.x;
    @@ -719,13 +731,13 @@ Object.defineProperty(Phaser.Text.prototype, 'font', {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Tile.js.html b/docs/Tile.js.html index 548be967..0dc8af7a 100644 --- a/docs/Tile.js.html +++ b/docs/Tile.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,35 +417,45 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
     /**
    -* Create a new `Tile` object. Tiles live inside of Tilesets and are rendered via TilemapLayers.
    +* Create a new `Tile` object.
     *
     * @class Phaser.Tile
    -* @classdesc A Tile is a single representation of a tile within a Tilemap.
    +* @classdesc A Tile is a representation of a single tile within the Tilemap.
     * @constructor
    -* @param {Phaser.Tileset} tileset - The tileset this tile belongs to.
    +* @param {object} layer - The layer in the Tilemap data that this tile belongs to.
     * @param {number} index - The index of this tile type in the core map data.
     * @param {number} x - The x coordinate of this tile.
     * @param {number} y - The y coordinate of this tile.
     * @param {number} width - Width of the tile.
     * @param {number} height - Height of the tile.
     */
    -Phaser.Tile = function (tileset, index, x, y, width, height) {
    +Phaser.Tile = function (layer, index, x, y, width, height) {
     
         /**
    -    * @property {Phaser.Tileset} tileset - The tileset this tile belongs to.
    +    * @property {object} layer - The layer in the Tilemap data that this tile belongs to.
         */
    -    this.tileset = tileset;
    -    
    +    this.layer = layer;
    +
         /**
    -    * @property {number} index - The index of this tile within the tileset.
    +    * @property {number} index - The index of this tile within the map data corresponding to the tileset.
         */
         this.index = index;
         
    +    /**
    +    * @property {number} x - The x map coordinate of this tile.
    +    */
    +    this.x = x;
    +    
    +    /**
    +    * @property {number} y - The y map coordinate of this tile.
    +    */
    +    this.y = y;
    +
         /**
         * @property {number} width - The width of the tile in pixels.
         */
    @@ -463,22 +467,44 @@ Phaser.Tile = function (tileset, index, x, y, width, height) {
         this.height = height;
     
         /**
    -    * @property {number} x - The top-left corner of the tile within the tileset.
    +    * @property {number} alpha - The alpha value at which this tile is drawn to the canvas.
         */
    -    this.x = x;
    -    
    -    /**
    -    * @property {number} y - The top-left corner of the tile within the tileset.
    -    */
    -    this.y = y;
    -
    -    //  Any extra meta data info we need here
    +    this.alpha = 1;
     
         /**
    -    * @property {number} mass - The virtual mass of the tile.
    -    * @default
    +    * @property {object} properties - Tile specific properties.
         */
    -    this.mass = 1.0;
    +    this.properties = {};
    +
    +    /**
    +    * @property {boolean} scanned - Has this tile been walked / turned into a poly?
    +    */
    +    this.scanned = false;
    +
    +    /**
    +    * @property {boolean} faceTop - Is the top of this tile an interesting edge?
    +    */
    +    this.faceTop = false;
    +
    +    /**
    +    * @property {boolean} faceBottom - Is the bottom of this tile an interesting edge?
    +    */
    +    this.faceBottom = false;
    +
    +    /**
    +    * @property {boolean} faceLeft - Is the left of this tile an interesting edge?
    +    */
    +    this.faceLeft = false;
    +
    +    /**
    +    * @property {boolean} faceRight - Is the right of this tile an interesting edge?
    +    */
    +    this.faceRight = false;
    +
    +    /**
    +    * @property {boolean} collides - Does this tile collide at all?
    +    */
    +    this.collides = false;
     
         /**
         * @property {boolean} collideNone - Indicating this Tile doesn't collide at all.
    @@ -511,38 +537,27 @@ Phaser.Tile = function (tileset, index, x, y, width, height) {
         this.collideDown = false;
     
         /**
    -    * @property {boolean} separateX - Enable separation at x-axis. 
    +    * @property {function} callback - Tile collision callback.
         * @default
         */
    -    this.separateX = true;
    +    this.callback = null;
     
         /**
    -    * @property {boolean} separateY - Enable separation at y-axis. 
    +    * @property {object} callbackContext - The context in which the collision callback will be called.
         * @default
         */
    -    this.separateY = true;
    -
    -    /**
    -    * @property {boolean} collisionCallback - Tilemap collision callback.
    -    * @default
    -    */
    -    this.collisionCallback = null;
    -
    -    /**
    -    * @property {boolean} collisionCallback - Tilemap collision callback.
    -    * @default
    -    */
    -    this.collisionCallbackContext = this;
    +    this.callbackContext = this;
     
     };
     
     Phaser.Tile.prototype = {
     
         /**
    -    * Set callback to be called when this tilemap collides.
    +    * Set a callback to be called when this tile is hit by an object.
    +    * The callback must true true for collision processing to take place.
         * 
         * @method Phaser.Tile#setCollisionCallback
    -    * @param {Function} callback - Callback function.
    +    * @param {function} callback - Callback function.
         * @param {object} context - Callback will be called with this context.
         */
         setCollisionCallback: function (callback, context) {
    @@ -558,7 +573,9 @@ Phaser.Tile.prototype = {
         */
         destroy: function () {
     
    -        this.tileset = null;
    +        this.collisionCallback = null;
    +        this.collisionCallbackContext = null;
    +        this.properties = null;
             
         },
     
    @@ -600,19 +617,55 @@ Phaser.Tile.prototype = {
             this.collideUp = false;
             this.collideDown = false;
     
    +    },
    +
    +    /**
    +    * Copies the tile data and properties from the given tile to this tile.
    +    * @method Phaser.Tile#copy
    +    * @param {Phaser.Tile} tile - The tile to copy from.
    +    */
    +    copy: function (tile) {
    +
    +        this.index = tile.index;
    +        this.alpha = tile.alpha;
    +        this.properties = tile.properties;
    +        this.collides = tile.collides;
    +        this.collideNone = tile.collideNone;
    +        this.collideUp = tile.collideUp;
    +        this.collideDown = tile.collideDown;
    +        this.collideLeft = tile.collideLeft;
    +        this.collideRight = tile.collideRight;
    +        this.collisionCallback = tile.collisionCallback;
    +        this.collisionCallbackContext = tile.collisionCallbackContext;
    +
         }
     
     };
     
    +Phaser.Tile.prototype.constructor = Phaser.Tile;
    +
     /**
    -* @name Phaser.Tile#bottom
    -* @property {number} bottom - The sum of the y and height properties.
    +* @name Phaser.Tile#canCollide
    +* @property {boolean} canCollide - True if this tile can collide or has a collision callback.
     * @readonly
     */
    -Object.defineProperty(Phaser.Tile.prototype, "bottom", {
    +Object.defineProperty(Phaser.Tile.prototype, "canCollide", {
         
         get: function () {
    -        return this.y + this.height;
    +        return (this.collides || this.collisionCallback || this.layer.callbacks[this.index]);
    +    }
    +
    +});
    +
    +/**
    +* @name Phaser.Tile#left
    +* @property {number} left - The x value.
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Tile.prototype, "left", {
    +    
    +    get: function () {
    +        return this.x;
         }
     
     });
    @@ -628,6 +681,32 @@ Object.defineProperty(Phaser.Tile.prototype, "right", {
             return this.x + this.width;
         }
     
    +});
    +
    +/**
    +* @name Phaser.Tile#top
    +* @property {number} top - The y value.
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Tile.prototype, "top", {
    +    
    +    get: function () {
    +        return this.y;
    +    }
    +
    +});
    +
    +/**
    +* @name Phaser.Tile#bottom
    +* @property {number} bottom - The sum of the y and height properties.
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.Tile.prototype, "bottom", {
    +    
    +    get: function () {
    +        return this.y + this.height;
    +    }
    +
     });
     
    @@ -644,13 +723,13 @@ Object.defineProperty(Phaser.Tile.prototype, "right", { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/TileSprite.js.html b/docs/TileSprite.js.html index ac778ade..a9fdfd0d 100644 --- a/docs/TileSprite.js.html +++ b/docs/TileSprite.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -438,18 +432,16 @@
     * @param {number} width - the width of the tilesprite.
     * @param {number} height - the height of the tilesprite.
     * @param {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture.
    -* @param {string|number} frame - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index.
     */
    -Phaser.TileSprite = function (game, x, y, width, height, key, frame) {
    +Phaser.TileSprite = function (game, x, y, width, height, key) {
     
         x = x || 0;
         y = y || 0;
         width = width || 256;
         height = height || 256;
         key = key || null;
    -    frame = frame || null;
     
    -    Phaser.Sprite.call(this, game, x, y, key, frame);
    +    Phaser.Sprite.call(this, game, x, y, key);
     
         /**
         * @property {PIXI.Texture} texture - The texture that the sprite renders with.
    @@ -474,11 +466,113 @@ Phaser.TileSprite = function (game, x, y, width, height, key, frame) {
         */
         this.tilePosition = new Phaser.Point(0, 0);
     
    +    this.body.width = width;
    +    this.body.height = height;
    +
     };
     
     Phaser.TileSprite.prototype = Phaser.Utils.extend(true, PIXI.TilingSprite.prototype, Phaser.Sprite.prototype);
     Phaser.TileSprite.prototype.constructor = Phaser.TileSprite;
     
    +/**
    +* Indicates the rotation of the Sprite, in degrees, from its original orientation. Values from 0 to 180 represent clockwise rotation; values from 0 to -180 represent counterclockwise rotation.
    +* Values outside this range are added to or subtracted from 360 to obtain a value within the range. For example, the statement player.angle = 450 is the same as player.angle = 90.
    +* If you wish to work in radians instead of degrees use the property Sprite.rotation instead.
    +* @name Phaser.TileSprite#angle
    +* @property {number} angle - Gets or sets the Sprites angle of rotation in degrees.
    +*/
    +Object.defineProperty(Phaser.TileSprite.prototype, 'angle', {
    +
    +    get: function() {
    +        return Phaser.Math.wrapAngle(Phaser.Math.radToDeg(this.rotation));
    +    },
    +
    +    set: function(value) {
    +        this.rotation = Phaser.Math.degToRad(Phaser.Math.wrapAngle(value));
    +    }
    +
    +});
    +
    +/**
    +* @name Phaser.TileSprite#frame
    +* @property {number} frame - Gets or sets the current frame index and updates the Texture Cache for display.
    +*/
    +Object.defineProperty(Phaser.TileSprite.prototype, "frame", {
    +    
    +    get: function () {
    +        return this.animations.frame;
    +    },
    +
    +    set: function (value) {
    +        this.animations.frame = value;
    +    }
    +
    +});
    +
    +/**
    +* @name Phaser.TileSprite#frameName
    +* @property {string} frameName - Gets or sets the current frame name and updates the Texture Cache for display.
    +*/
    +Object.defineProperty(Phaser.TileSprite.prototype, "frameName", {
    +    
    +    get: function () {
    +        return this.animations.frameName;
    +    },
    +
    +    set: function (value) {
    +        this.animations.frameName = value;
    +    }
    +
    +});
    +
    +/**
    +* @name Phaser.TileSprite#inCamera
    +* @property {boolean} inCamera - Is this sprite visible to the camera or not?
    +* @readonly
    +*/
    +Object.defineProperty(Phaser.TileSprite.prototype, "inCamera", {
    +    
    +    get: function () {
    +        return this._cache.cameraVisible;
    +    }
    +
    +});
    +
    +/**
    +* By default a Sprite won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is
    +* activated for this Sprite instance and it will then start to process click/touch events and more.
    +*
    +* @name Phaser.TileSprite#inputEnabled
    +* @property {boolean} inputEnabled - Set to true to allow this Sprite to receive input events, otherwise false.
    +*/
    +Object.defineProperty(Phaser.TileSprite.prototype, "inputEnabled", {
    +    
    +    get: function () {
    +
    +        return (this.input.enabled);
    +
    +    },
    +
    +    set: function (value) {
    +
    +        if (value)
    +        {
    +            if (this.input.enabled === false)
    +            {
    +                this.input.start();
    +            }
    +        }
    +        else
    +        {
    +            if (this.input.enabled)
    +            {
    +                this.input.stop();
    +            }
    +        }
    +
    +    }
    +
    +});
     
    @@ -494,13 +588,13 @@ Phaser.TileSprite.prototype.constructor = Phaser.TileSprite; - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Tilemap.js.html b/docs/Tilemap.js.html index e82c2655..ed75f137 100644 --- a/docs/Tilemap.js.html +++ b/docs/Tilemap.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -444,22 +438,52 @@ Phaser.Tilemap = function (game, key) {
         this.game = game;
     
         /**
    -    * @property {array} layers - An array of Tilemap layers.
    +    * @property {string} key - The key of this map data in the Phaser.Cache.
         */
    -    this.layers = null;
    +    this.key = key;
     
    -    if (typeof key === 'string')
    -    {
    -        this.key = key;
    +    var data = Phaser.TilemapParser.parse(this.game, key);
     
    -        this.layers = game.cache.getTilemapData(key).layers;
    -        this.calculateIndexes();
    -    }
    -    else
    +    if (data === null)
         {
    -        this.layers = [];
    +        return;
         }
     
    +    this.width = data.width;
    +    this.height = data.height;
    +    this.tileWidth = data.tileWidth;
    +    this.tileHeight = data.tileHeight;
    +    this.orientation = data.orientation;
    +    this.version = data.version;
    +    this.properties = data.properties;
    +    this.widthInPixels = data.widthInPixels;
    +    this.heightInPixels = data.heightInPixels;
    +
    +    /**
    +    * @property {array} layers - An array of Tilemap layer data.
    +    */
    +    this.layers = data.layers;
    +
    +    /**
    +    * @property {array} tilesets - An array of Tilesets.
    +    */
    +    this.tilesets = data.tilesets;
    +
    +    /**
    +    * @property {array} tiles - The super array of Tiles.
    +    */
    +    this.tiles = data.tiles;
    +
    +    /**
    +    * @property {array} objects - An array of Tiled Object Layers.
    +    */
    +    this.objects = data.objects;
    +
    +    /**
    +    * @property {array} images - An array of Tiled Image Layers.
    +    */
    +    this.images = data.images;
    +
         /**
         * @property {number} currentLayer - The current layer.
         */
    @@ -468,14 +492,8 @@ Phaser.Tilemap = function (game, key) {
         /**
         * @property {array} debugMap - Map data used for debug values only.
         */
    -
         this.debugMap = [];
     
    -    /**
    -    * @property {boolean} dirty - Internal rendering related flag.
    -    */
    -    this.dirty = false;
    -
         /**
         * @property {array} _results - Internal var.
         * @private
    @@ -543,36 +561,500 @@ Phaser.Tilemap.prototype = {
                 tileSpacing: 0,
                 format: Phaser.Tilemap.CSV,
                 data: data,
    -            indexes: []
    +            indexes: [],
    +			dirty: true
     
             });
     
             this.currentLayer = this.layers.length - 1;
     
    -        this.dirty = true;
    +    },
    +
    +    /**
    +    * Adds an image to the map to be used as a tileset. A single map may use multiple tilesets.
    +    * Note that the tileset name can be found in the JSON file exported from Tiled, or in the Tiled editor.
    +    *
    +    * @method Phaser.Tilemap#addTilesetImage
    +    * @param {string} tileset - The name of the tileset as specified in the map data.
    +    * @param {string} [key] - The key of the Phaser.Cache image used for this tileset. If not specified it will look for an image with a key matching the tileset parameter.
    +    */
    +    addTilesetImage: function (tileset, key) {
    +
    +        if (typeof key === 'undefined')
    +        {
    +            if (typeof tileset === 'string')
    +            {
    +                key = tileset;
    +            }
    +            else
    +            {
    +                return false;
    +            }
    +        }
    +
    +        if (typeof tileset === 'string')
    +        {
    +            tileset = this.getTilesetIndex(tileset);
    +        }
    +
    +        if (this.tilesets[tileset])
    +        {
    +            this.tilesets[tileset].image = this.game.cache.getImage(key);
    +
    +            return true;
    +        }
    +
    +        return false;
    +
    +    },
    +
    +    //  Region? Remove tile from map data?
    +    createFromTiles: function (layer, tileIndex, key, frame, group) {
    +
    +        if (typeof group === 'undefined') { group = this.game.world; }
     
         },
     
         /**
    -    * Internal function that calculates the tile indexes for the map data.
    +    * Creates a Sprite for every object matching the given gid in the map data. You can optionally specify the group that the Sprite will be created in. If none is
    +    * given it will be created in the World. All properties from the map data objectgroup are copied across to the Sprite, so you can use this as an easy way to
    +    * configure Sprite properties from within the map editor. For example giving an object a property if alpha: 0.5 in the map editor will duplicate that when the
    +    * Sprite is created. You could also give it a value like: body.velocity.x: 100 to set it moving automatically.
         *
    -    * @method Phaser.Tilemap#calculateIndexes
    +    * @method Phaser.Tileset#createFromObjects
    +    * @param {string} name - The name of the Object Group to create Sprites from.
    +    * @param {number} gid - The layer array index value, or if a string is given the layer name, within the map data that this TilemapLayer represents.
    +    * @param {string} key - The Game.cache key of the image that this Sprite will use.
    +    * @param {number|string} [frame] - If the Sprite image contains multiple frames you can specify which one to use here.
    +    * @param {boolean} [exists=true] - The default exists state of the Sprite.
    +    * @param {boolean} [autoCull=true] - The default autoCull state of the Sprite. Sprites that are autoCulled are culled from the camera if out of its range.
    +    * @param {Phaser.Group} [group] - Optional Group to add the Sprite to. If not specified it will be added to the World group.
         */
    -    calculateIndexes: function () {
    +    createFromObjects: function (name, gid, key, frame, exists, autoCull, group) {
     
    -        for (var layer = 0; layer < this.layers.length; layer++)
    +        if (typeof exists === 'undefined') { exists = true; }
    +        if (typeof autoCull === 'undefined') { autoCull = true; }
    +        if (typeof group === 'undefined') { group = this.game.world; }
    +
    +        if (!this.objects[name])
             {
    -            this.layers[layer].indexes = [];
    +            console.warn('Tilemap.createFromObjects: Invalid objectgroup name given: ' + name);
    +            return;
    +        }
     
    -            for (var y = 0; y < this.layers[layer].height ; y++)
    +        var sprite;
    +
    +        for (var i = 0, len = this.objects[name].length; i < len; i++)
    +        {
    +            if (this.objects[name][i].gid === gid)
                 {
    -                for (var x = 0; x < this.layers[layer].width; x++)
    -                {
    -                    var idx = this.layers[layer].data[y][x];
    +                sprite = group.create(this.objects[name][i].x, this.objects[name][i].y, key, frame, exists);
     
    -                    if (this.layers[layer].indexes.indexOf(idx) === -1)
    +                sprite.anchor.setTo(0, 1);
    +                sprite.name = this.objects[name][i].name;
    +                sprite.visible = this.objects[name][i].visible;
    +                sprite.autoCull = autoCull;
    +
    +                for (property in this.objects[name][i].properties)
    +                {
    +                    group.set(sprite, property, this.objects[name][i].properties[property], false, false, 0);
    +                }
    +            }
    +        }
    +
    +    },
    +
    +    /**
    +    * Creates a new TilemapLayer object. By default TilemapLayers are fixed to the camera.
    +    *
    +    * @method Phaser.Tileset#createLayer
    +    * @param {number|string} layer - The layer array index value, or if a string is given the layer name, within the map data that this TilemapLayer represents.
    +    * @param {number} [width] - The rendered width of the layer, should never be wider than Game.width. If not given it will be set to Game.width.
    +    * @param {number} [height] - The rendered height of the layer, should never be wider than Game.height. If not given it will be set to Game.height.
    +    * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group.
    +    * @return {Phaser.TilemapLayer} The TilemapLayer object. This is an extension of Phaser.Sprite and can be moved around the display list accordingly.
    +    */
    +    createLayer: function (layer, width, height, group) {
    +
    +        //  Add Buffer support for the left of the canvas
    +
    +        if (typeof width === 'undefined') { width = this.game.width; }
    +        if (typeof height === 'undefined') { height = this.game.height; }
    +        if (typeof group === 'undefined') { group = this.game.world; }
    +
    +        var index = layer;
    +
    +        if (typeof layer === 'string')
    +        {
    +            index = this.getLayerIndex(layer);
    +        }
    +
    +        if (index === null || index > this.layers.length)
    +        {
    +            console.warn('Tilemap.createLayer: Invalid layer ID given: ' + index);
    +            return;
    +        }
    +
    +        return group.add(new Phaser.TilemapLayer(this.game, this, index, width, height));
    +
    +    },
    +
    +    /**
    +    * Gets the layer index based on the layers name.
    +    *
    +    * @method Phaser.Tileset#getIndex
    +    * @protected
    +    * @param {array} location - The local array to search.
    +    * @param {string} name - The name of the array element to get.
    +    * @return {number} The index of the element in the array, or null if not found.
    +    */
    +    getIndex: function (location, name) {
    +
    +        for (var i = 0; i < location.length; i++)
    +        {
    +            if (location[i].name === name)
    +            {
    +                return i;
    +            }
    +        }
    +
    +        return null;
    +
    +    },
    +
    +    /**
    +    * Gets the layer index based on its name.
    +    *
    +    * @method Phaser.Tileset#getLayerIndex
    +    * @param {string} name - The name of the layer to get.
    +    * @return {number} The index of the layer in this tilemap, or null if not found.
    +    */
    +    getLayerIndex: function (name) {
    +
    +        return this.getIndex(this.layers, name);
    +
    +    },
    +
    +    /**
    +    * Gets the tileset index based on its name.
    +    *
    +    * @method Phaser.Tileset#getTilesetIndex
    +    * @param {string} name - The name of the tileset to get.
    +    * @return {number} The index of the tileset in this tilemap, or null if not found.
    +    */
    +    getTilesetIndex: function (name) {
    +
    +        return this.getIndex(this.tilesets, name);
    +
    +    },
    +
    +    /**
    +    * Gets the image index based on its name.
    +    *
    +    * @method Phaser.Tileset#getImageIndex
    +    * @param {string} name - The name of the image to get.
    +    * @return {number} The index of the image in this tilemap, or null if not found.
    +    */
    +    getImageIndex: function (name) {
    +
    +        return this.getIndex(this.images, name);
    +
    +    },
    +
    +    /**
    +    * Gets the object index based on its name.
    +    *
    +    * @method Phaser.Tileset#getObjectIndex
    +    * @param {string} name - The name of the object to get.
    +    * @return {number} The index of the object in this tilemap, or null if not found.
    +    */
    +    getObjectIndex: function (name) {
    +
    +        return this.getIndex(this.objects, name);
    +
    +    },
    +
    +    /**
    +    * Sets a global collision callback for the given tile index within the layer. This will affect all tiles on this layer that have the same index.
    +    * If a callback is already set for the tile index it will be replaced. Set the callback to null to remove it.
    +    * If you want to set a callback for a tile at a specific location on the map then see setTileLocationCallback.
    +    *
    +    * @method Phaser.Tileset#setTileIndexCallback
    +    * @param {number|array} indexes - Either a single tile index, or an array of tile indexes to have a collision callback set for.
    +    * @param {function} callback - The callback that will be invoked when the tile is collided with.
    +    * @param {object} callbackContext - The context under which the callback is called.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer.
    +    */
    +    setTileIndexCallback: function (indexes, callback, callbackContext, layer) {
    +
    +        layer = this.getLayer(layer);
    +
    +        if (typeof indexes === 'number')
    +        {
    +            //  This may seem a bit wasteful, because it will cause empty array elements to be created, but the look-up cost is much
    +            //  less than having to iterate through the callbacks array hunting down tile indexes each time, so I'll take the small memory hit.
    +            this.layers[layer].callbacks[indexes] = { callback: callback, callbackContext: callbackContext };
    +        }
    +        else
    +        {
    +            for (var i = 0, len = indexes.length; i < len; i++)
    +            {
    +                this.layers[layer].callbacks[indexes[i]] = { callback: callback, callbackContext: callbackContext };
    +            }
    +        }
    +
    +    },
    +
    +    /**
    +    * Sets a global collision callback for the given tile index within the layer. This will affect all tiles on this layer that have the same index.
    +    * If a callback is already set for the tile index it will be replaced. Set the callback to null to remove it.
    +    * If you want to set a callback for a tile at a specific location on the map then see setTileLocationCallback.
    +    *
    +    * @method Phaser.Tileset#setTileLocationCallback
    +    * @param {number} x - X position of the top left of the area to copy (given in tiles, not pixels)
    +    * @param {number} y - Y position of the top left of the area to copy (given in tiles, not pixels)
    +    * @param {number} width - The width of the area to copy (given in tiles, not pixels)
    +    * @param {number} height - The height of the area to copy (given in tiles, not pixels)
    +    * @param {function} callback - The callback that will be invoked when the tile is collided with.
    +    * @param {object} callbackContext - The context under which the callback is called.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer.
    +    */
    +    setTileLocationCallback: function (x, y, width, height, callback, callbackContext, layer) {
    +
    +        layer = this.getLayer(layer);
    +
    +        this.copy(x, y, width, height, layer);
    +
    +        if (this._results.length < 2)
    +        {
    +            return;
    +        }
    +
    +        for (var i = 1; i < this._results.length; i++)
    +        {
    +            this._results[i].setCollisionCallback(callback, callbackContext);
    +        }
    +
    +    },
    +
    +    /**
    +    * Sets collision the given tile or tiles. You can pass in either a single numeric index or an array of indexes: [ 2, 3, 15, 20].
    +    * The `collides` parameter controls if collision will be enabled (true) or disabled (false).
    +    *
    +    * @method Phaser.Tileset#setCollision
    +    * @param {number|array} indexes - Either a single tile index, or an array of tile IDs to be checked for collision.
    +    * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer.
    +    */
    +    setCollision: function (indexes, collides, layer) {
    +
    +        if (typeof collides === 'undefined') { collides = true; }
    +
    +        layer = this.getLayer(layer);
    +
    +        if (typeof indexes === 'number')
    +        {
    +            return this.setCollisionByIndex(indexes, collides, layer, true);
    +        }
    +        else
    +        {
    +            //  Collide all of the IDs given in the indexes array
    +            for (var i = 0, len = indexes.length; i < len; i++)
    +            {
    +                this.setCollisionByIndex(indexes[i], collides, layer, false);
    +            }
    +
    +            //  Now re-calculate interesting faces
    +            this.calculateFaces(layer);
    +        }
    +
    +    },
    +
    +    /**
    +    * Sets collision on a range of tiles where the tile IDs increment sequentially.
    +    * Calling this with a start value of 10 and a stop value of 14 would set collision for tiles 10, 11, 12, 13 and 14.
    +    * The `collides` parameter controls if collision will be enabled (true) or disabled (false).
    +    *
    +    * @method Phaser.Tileset#setCollisionBetween
    +    * @param {number} start - The first index of the tile to be set for collision.
    +    * @param {number} stop - The last index of the tile to be set for collision.
    +    * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer.
    +    */
    +    setCollisionBetween: function (start, stop, collides, layer) {
    +
    +        if (typeof collides === 'undefined') { collides = true; }
    +
    +        layer = this.getLayer(layer);
    +
    +        if (start > stop)
    +        {
    +            return;
    +        }
    +
    +        for (var index = start; index <= stop; index++)
    +        {
    +            this.setCollisionByIndex(index, collides, layer, false);
    +        }
    +
    +        //  Now re-calculate interesting faces
    +        this.calculateFaces(layer);
    +
    +    },
    +
    +    /**
    +    * Sets collision on all tiles in the given layer, except for the IDs of those in the given array.
    +    * The `collides` parameter controls if collision will be enabled (true) or disabled (false).
    +    *
    +    * @method Phaser.Tileset#setCollisionByExclusion
    +    * @param {array} indexes - An array of the tile IDs to not be counted for collision.
    +    * @param {boolean} [collides=true] - If true it will enable collision. If false it will clear collision.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on. If not given will default to this.currentLayer.
    +    */
    +    setCollisionByExclusion: function (indexes, collides, layer) {
    +
    +        if (typeof collides === 'undefined') { collides = true; }
    +
    +        layer = this.getLayer(layer);
    +
    +        //  Collide everything, except the IDs given in the indexes array
    +        for (var i = 0, len = this.tiles.length; i < len; i++)
    +        {
    +            if (indexes.indexOf(i) === -1)
    +            {
    +                this.setCollisionByIndex(i, collides, layer, false);
    +            }
    +        }
    +
    +        //  Now re-calculate interesting faces
    +        this.calculateFaces(layer);
    +
    +    },
    +
    +    /**
    +    * Sets collision values on a tile in the set.
    +    * You shouldn't usually call this method directly, instead use setCollision, setCollisionBetween or setCollisionByExclusion.
    +    *
    +    * @method Phaser.Tileset#setCollisionByIndex
    +    * @protected
    +    * @param {number} index - The index of the tile on the layer.
    +    * @param {boolean} [collides=true] - If true it will enable collision on the tile. If false it will clear collision values from the tile.
    +    * @param {number} [layer] - The layer to operate on. If not given will default to this.currentLayer.
    +    * @param {boolean} [recalculate=true] - Recalculates the tile faces after the update.
    +    */
    +    setCollisionByIndex: function (index, collides, layer, recalculate) {
    +
    +        if (typeof collides === 'undefined') { collides = true; }
    +        if (typeof layer === 'undefined') { layer = this.currentLayer; }
    +        if (typeof recalculate === 'undefined') { recalculate = true; }
    +
    +        for (var y = 0; y < this.layers[layer].height ; y++)
    +        {
    +            for (var x = 0; x < this.layers[layer].width; x++)
    +            {
    +                var tile = this.layers[layer].data[y][x];
    +
    +                if (tile && tile.index === index)
    +                {
    +                    tile.collides = collides;
    +                    tile.faceTop = collides;
    +                    tile.faceBottom = collides;
    +                    tile.faceLeft = collides;
    +                    tile.faceRight = collides;
    +                }
    +            }
    +        }
    +
    +        if (recalculate)
    +        {
    +            //  Now re-calculate interesting faces
    +            this.calculateFaces(layer);
    +        }
    +
    +        return layer;
    +
    +    },
    +
    +    /**
    +    * Gets the TilemapLayer index as used in the setCollision calls.
    +    *
    +    * @method Phaser.Tileset#getLayer
    +    * @protected
    +    * @param {number|string|Phaser.TilemapLayer} layer - The layer to operate on. If not given will default to this.currentLayer.
    +    * @return {number} The TilemapLayer index.
    +    */
    +    getLayer: function (layer) {
    +
    +        if (typeof layer === 'undefined')
    +        {
    +            layer = this.currentLayer;
    +        }
    +        // else if (typeof layer === 'number')
    +        // {
    +        //     layer = layer;
    +        // }
    +        else if (typeof layer === 'string')
    +        {
    +            layer = this.getLayerIndex(layer);
    +        }
    +        else if (layer instanceof Phaser.TilemapLayer)
    +        {
    +            layer = layer.index;
    +        }
    +
    +        return layer;
    +
    +    },
    +
    +    /**
    +    * Internal function.
    +    *
    +    * @method Phaser.Tileset#calculateFaces
    +    * @protected
    +    * @param {number} layer - The index of the TilemapLayer to operate on.
    +    */
    +    calculateFaces: function (layer) {
    +
    +        var above = null;
    +        var below = null;
    +        var left = null;
    +        var right = null;
    +
    +        for (var y = 0, h = this.layers[layer].height; y < h; y++)
    +        {
    +            for (var x = 0, w = this.layers[layer].width; x < w; x++)
    +            {
    +                var tile = this.layers[layer].data[y][x];
    +
    +                if (tile)
    +                {
    +                    above = this.getTileAbove(layer, x, y);
    +                    below = this.getTileBelow(layer, x, y);
    +                    left = this.getTileLeft(layer, x, y);
    +                    right = this.getTileRight(layer, x, y);
    +
    +                    if (above && above.collides)
                         {
    -                        this.layers[layer].indexes.push(idx);
    +                        //  There is a tile above this one that also collides, so the top of this tile is no longer interesting
    +                        tile.faceTop = false;
    +                    }
    +
    +                    if (below && below.collides)
    +                    {
    +                        //  There is a tile below this one that also collides, so the bottom of this tile is no longer interesting
    +                        tile.faceBottom = false;
    +                    }
    +
    +                    if (left && left.collides)
    +                    {
    +                        //  There is a tile left this one that also collides, so the left of this tile is no longer interesting
    +                        tile.faceLeft = false;
    +                    }
    +
    +                    if (right && right.collides)
    +                    {
    +                        //  There is a tile right this one that also collides, so the right of this tile is no longer interesting
    +                        tile.faceRight = false;
                         }
                     }
                 }
    @@ -580,14 +1062,96 @@ Phaser.Tilemap.prototype = {
     
         },
     
    +    /**
    +    * Gets the tile above the tile coordinates given.
    +    * Mostly used as an internal function by calculateFaces.
    +    *
    +    * @method Phaser.Tileset#getTileAbove
    +    * @param {number} layer - The local layer index to get the tile from. Can be determined by Tilemap.getLayer().
    +    * @param {number} x - The x coordinate to get the tile from. In tiles, not pixels.
    +    * @param {number} y - The y coordinate to get the tile from. In tiles, not pixels.
    +    */
    +    getTileAbove: function (layer, x, y) {
    +
    +        if (y > 0)
    +        {
    +            return this.layers[layer].data[y - 1][x];
    +        }
    +
    +        return null;
    +
    +    },
    +
    +    /**
    +    * Gets the tile below the tile coordinates given.
    +    * Mostly used as an internal function by calculateFaces.
    +    *
    +    * @method Phaser.Tileset#getTileBelow
    +    * @param {number} layer - The local layer index to get the tile from. Can be determined by Tilemap.getLayer().
    +    * @param {number} x - The x coordinate to get the tile from. In tiles, not pixels.
    +    * @param {number} y - The y coordinate to get the tile from. In tiles, not pixels.
    +    */
    +    getTileBelow: function (layer, x, y) {
    +
    +        if (y < this.layers[layer].height - 1)
    +        {
    +            return this.layers[layer].data[y + 1][x];
    +        }
    +
    +        return null;
    +
    +    },
    +
    +    /**
    +    * Gets the tile to the left of the tile coordinates given.
    +    * Mostly used as an internal function by calculateFaces.
    +    *
    +    * @method Phaser.Tileset#getTileLeft
    +    * @param {number} layer - The local layer index to get the tile from. Can be determined by Tilemap.getLayer().
    +    * @param {number} x - The x coordinate to get the tile from. In tiles, not pixels.
    +    * @param {number} y - The y coordinate to get the tile from. In tiles, not pixels.
    +    */
    +    getTileLeft: function (layer, x, y) {
    +
    +        if (x > 0)
    +        {
    +            return this.layers[layer].data[y][x - 1];
    +        }
    +
    +        return null;
    +
    +    },
    +
    +    /**
    +    * Gets the tile to the right of the tile coordinates given.
    +    * Mostly used as an internal function by calculateFaces.
    +    *
    +    * @method Phaser.Tileset#getTileRight
    +    * @param {number} layer - The local layer index to get the tile from. Can be determined by Tilemap.getLayer().
    +    * @param {number} x - The x coordinate to get the tile from. In tiles, not pixels.
    +    * @param {number} y - The y coordinate to get the tile from. In tiles, not pixels.
    +    */
    +    getTileRight: function (layer, x, y) {
    +
    +        if (x < this.layers[layer].width - 1)
    +        {
    +            return this.layers[layer].data[y][x + 1];
    +        }
    +
    +        return null;
    +
    +    },
    +
         /**
         * Sets the current layer to the given index.
         *
         * @method Phaser.Tilemap#setLayer
    -    * @param {number} layer - Sets the current layer to the given index.
    +    * @param {number|string|Phaser.TilemapLayer} layer - The layer to set as current.
         */
         setLayer: function (layer) {
     
    +        layer = this.getLayer(layer);
    +
             if (this.layers[layer])
             {
                 this.currentLayer = layer;
    @@ -597,36 +1161,68 @@ Phaser.Tilemap.prototype = {
     
         /**
         * Puts a tile of the given index value at the coordinate specified.
    +    *
         * @method Phaser.Tilemap#putTile
    -    * @param {number} index - The index of this tile to set.
    +    * @param {Phaser.Tile|number} tile - The index of this tile to set or a Phaser.Tile object.
         * @param {number} x - X position to place the tile (given in tile units, not pixels)
         * @param {number} y - Y position to place the tile (given in tile units, not pixels)
    -    * @param {number} [layer] - The Tilemap Layer to operate on.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to modify.
         */
    -    putTile: function (index, x, y, layer) {
    +    putTile: function (tile, x, y, layer) {
     
    -        if (typeof layer === "undefined") { layer = this.currentLayer; }
    +        layer = this.getLayer(layer);
     
             if (x >= 0 && x < this.layers[layer].width && y >= 0 && y < this.layers[layer].height)
             {
    -            this.layers[layer].data[y][x] = index;
    +            if (tile instanceof Phaser.Tile)
    +            {
    +                this.layers[layer].data[y][x].copy(tile);
    +            }
    +            else
    +            {
    +                this.layers[layer].data[y][x].index = tile;
    +            }
    +
    +			this.layers[layer].dirty = true;
    +            this.calculateFaces(layer);
             }
     
    -        this.dirty = true;
    +    },
    +
    +    /**
    +    * Puts a tile into the Tilemap layer. The coordinates are given in pixel values.
    +    *
    +    * @method Phaser.Tilemap#putTileWorldXY
    +    * @param {Phaser.Tile|number} tile - The index of this tile to set or a Phaser.Tile object.
    +    * @param {number} x - X position to insert the tile (given in pixels)
    +    * @param {number} y - Y position to insert the tile (given in pixels)
    +    * @param {number} tileWidth - The width of the tile in pixels.
    +    * @param {number} tileHeight - The height of the tile in pixels.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to modify.
    +    */
    +    putTileWorldXY: function (tile, x, y, tileWidth, tileHeight, layer) {
    +
    +        layer = this.getLayer(layer);
    +
    +        x = this.game.math.snapToFloor(x, tileWidth) / tileWidth;
    +        y = this.game.math.snapToFloor(y, tileHeight) / tileHeight;
    +
    +        this.putTile(tile, x, y, layer);
     
         },
     
         /**
         * Gets a tile from the Tilemap Layer. The coordinates are given in tile values.
    +    *
         * @method Phaser.Tilemap#getTile
         * @param {number} x - X position to get the tile from (given in tile units, not pixels)
         * @param {number} y - Y position to get the tile from (given in tile units, not pixels)
    -    * @param {number} [layer] - The Tilemap Layer to operate on.
    -    * @return {number} The index of the tile at the given coordinates.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to get the tile from.
    +    * @return {Phaser.Tile} The tile at the given coordinates.
         */
         getTile: function (x, y, layer) {
     
    -        if (typeof layer === "undefined") { layer = this.currentLayer; }
    +        layer = this.getLayer(layer);
     
             if (x >= 0 && x < this.layers[layer].width && y >= 0 && y < this.layers[layer].height)
             {
    @@ -637,65 +1233,38 @@ Phaser.Tilemap.prototype = {
     
         /**
         * Gets a tile from the Tilemap layer. The coordinates are given in pixel values.
    +    *
         * @method Phaser.Tilemap#getTileWorldXY
         * @param {number} x - X position to get the tile from (given in pixels)
         * @param {number} y - Y position to get the tile from (given in pixels)
    -    * @param {number} [layer] - The Tilemap Layer to operate on.
    -    * @return {number} The index of the tile at the given coordinates.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to get the tile from.
    +    * @return {Phaser.Tile} The tile at the given coordinates.
         */
         getTileWorldXY: function (x, y, tileWidth, tileHeight, layer) {
     
    -        if (typeof layer === "undefined") { layer = this.currentLayer; }
    +        layer = this.getLayer(layer);
     
             x = this.game.math.snapToFloor(x, tileWidth) / tileWidth;
             y = this.game.math.snapToFloor(y, tileHeight) / tileHeight;
     
    -        if (x >= 0 && x < this.layers[layer].width && y >= 0 && y < this.layers[layer].height)
    -        {
    -            return this.layers[layer].data[y][x];
    -        }
    -
    -    },
    -
    -    /**
    -    * Puts a tile into the Tilemap layer. The coordinates are given in pixel values.
    -    * @method Phaser.Tilemap#putTileWorldXY
    -    * @param {number} index - The index of the tile to put into the layer.
    -    * @param {number} x - X position to insert the tile (given in pixels)
    -    * @param {number} y - Y position to insert the tile (given in pixels)
    -    * @param {number} tileWidth - The width of the tile in pixels.
    -    * @param {number} tileHeight - The height of the tile in pixels.
    -    * @param {number} [layer] - The Tilemap Layer to operate on.
    -    */
    -    putTileWorldXY: function (index, x, y, tileWidth, tileHeight, layer) {
    -
    -        if (typeof layer === "undefined") { layer = this.currentLayer; }
    -
    -        x = this.game.math.snapToFloor(x, tileWidth) / tileWidth;
    -        y = this.game.math.snapToFloor(y, tileHeight) / tileHeight;
    -
    -        if (x >= 0 && x < this.layers[layer].width && y >= 0 && y < this.layers[layer].height)
    -        {
    -            this.layers[layer].data[y][x] = index;
    -        }
    -
    -        this.dirty = true;
    +        return this.getTile(x, y, layer);
     
         },
     
         /**
         * Copies all of the tiles in the given rectangular block into the tilemap data buffer.
    +    *
         * @method Phaser.Tilemap#copy
         * @param {number} x - X position of the top left of the area to copy (given in tiles, not pixels)
         * @param {number} y - Y position of the top left of the area to copy (given in tiles, not pixels)
         * @param {number} width - The width of the area to copy (given in tiles, not pixels)
         * @param {number} height - The height of the area to copy (given in tiles, not pixels)
    -    * @param {number} [layer] - The Tilemap Layer to operate on.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to copy the tiles from.
         * @return {array} An array of the tiles that were copied.
         */
         copy: function (x, y, width, height, layer) {
     
    -        if (typeof layer === "undefined") { layer = this.currentLayer; }
    +        layer = this.getLayer(layer);
     
             if (!this.layers[layer])
             {
    @@ -736,7 +1305,7 @@ Phaser.Tilemap.prototype = {
             {
                 for (var tx = x; tx < x + width; tx++)
                 {
    -                this._results.push({ x: tx, y: ty, index: this.layers[layer].data[ty][tx] });
    +                this._results.push(this.layers[layer].data[ty][tx]);
                 }
             }
     
    @@ -746,17 +1315,19 @@ Phaser.Tilemap.prototype = {
     
         /**
         * Pastes a previously copied block of tile data into the given x/y coordinates. Data should have been prepared with Tilemap.copy.
    +    *
         * @method Phaser.Tilemap#paste
         * @param {number} x - X position of the top left of the area to paste to (given in tiles, not pixels)
         * @param {number} y - Y position of the top left of the area to paste to (given in tiles, not pixels)
         * @param {array} tileblock - The block of tiles to paste.
    -    * @param {number} layer - The Tilemap Layer to operate on.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to paste the tiles into.
         */
         paste: function (x, y, tileblock, layer) {
     
             if (typeof x === "undefined") { x = 0; }
             if (typeof y === "undefined") { y = 0; }
    -        if (typeof layer === "undefined") { layer = this.currentLayer; }
    +        
    +        layer = this.getLayer(layer);
     
             if (!tileblock || tileblock.length < 2)
             {
    @@ -769,15 +1340,17 @@ Phaser.Tilemap.prototype = {
     
             for (var i = 1; i < tileblock.length; i++)
             {
    -            this.layers[layer].data[ diffY + tileblock[i].y ][ diffX + tileblock[i].x ] = tileblock[i].index;
    +            this.layers[layer].data[ diffY + tileblock[i].y ][ diffX + tileblock[i].x ].copy(tileblock[i]);
             }
     
    -        this.dirty = true;
    +		this.layers[layer].dirty = true;
    +        this.calculateFaces(layer);
     
         },
     
         /**
    -    * Swap tiles with 2 kinds of indexes.
    +    * Scans the given area for tiles with an index matching tileA and swaps them with tileB.
    +    *
         * @method Phaser.Tilemap#swapTile
         * @param {number} tileA - First tile index.
         * @param {number} tileB - Second tile index.
    @@ -785,9 +1358,12 @@ Phaser.Tilemap.prototype = {
         * @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels.
         * @param {number} width - The width in tiles of the area to operate on.
         * @param {number} height - The height in tiles of the area to operate on.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on.
         */
         swap: function (tileA, tileB, x, y, width, height, layer) {
     
    +        layer = this.getLayer(layer);
    +
             this.copy(x, y, width, height, layer);
     
             if (this._results.length < 2)
    @@ -800,13 +1376,15 @@ Phaser.Tilemap.prototype = {
     
             this._results.forEach(this.swapHandler, this);
     
    -        this.paste(x, y, this._results);
    +        this.paste(x, y, this._results, layer);
     
         },
     
         /**
         * Internal function that handles the swapping of tiles.
    +    *
         * @method Phaser.Tilemap#swapHandler
    +    * @private
         * @param {number} value
         * @param {number} index
         */
    @@ -824,7 +1402,8 @@ Phaser.Tilemap.prototype = {
         },
     
         /**
    -    * For each tile in the given area (defined by x/y and width/height) run the given callback.
    +    * For each tile in the given area defined by x/y and width/height run the given callback.
    +    *
         * @method Phaser.Tilemap#forEach
         * @param {number} callback - The callback. Each tile in the given area will be passed to this callback as the first and only parameter.
         * @param {number} context - The context under which the callback should be run.
    @@ -832,10 +1411,12 @@ Phaser.Tilemap.prototype = {
         * @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels.
         * @param {number} width - The width in tiles of the area to operate on.
         * @param {number} height - The height in tiles of the area to operate on.
    -    * @param {number} [layer] - The Tilemap Layer to operate on.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on.
         */
         forEach: function (callback, context, x, y, width, height, layer) {
     
    +        layer = this.getLayer(layer);
    +
             this.copy(x, y, width, height, layer);
     
             if (this._results.length < 2)
    @@ -845,22 +1426,25 @@ Phaser.Tilemap.prototype = {
     
             this._results.forEach(callback, context);
     
    -        this.paste(x, y, this._results);
    +        this.paste(x, y, this._results, layer);
     
         },
     
         /**
    -    * Replaces one type of tile with another in the given area (defined by x/y and width/height).
    +    * Scans the given area for tiles with an index matching `source` and updates their index to match `dest`.
    +    *
         * @method Phaser.Tilemap#replace
    -    * @param {number} tileA - First tile index.
    -    * @param {number} tileB - Second tile index.
    +    * @param {number} source - The tile index value to scan for.
    +    * @param {number} dest - The tile index value to replace found tiles with.
         * @param {number} x - X position of the top left of the area to operate one, given in tiles, not pixels.
         * @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels.
         * @param {number} width - The width in tiles of the area to operate on.
         * @param {number} height - The height in tiles of the area to operate on.
    -    * @param {number} [layer] - The Tilemap Layer to operate on.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on.
         */
    -    replace: function (tileA, tileB, x, y, width, height, layer) {
    +    replace: function (source, dest, x, y, width, height, layer) {
    +
    +        layer = this.getLayer(layer);
     
             this.copy(x, y, width, height, layer);
     
    @@ -871,30 +1455,29 @@ Phaser.Tilemap.prototype = {
     
             for (var i = 1; i < this._results.length; i++)
             {
    -            if (this._results[i].index === tileA)
    +            if (this._results[i].index === source)
                 {
    -                this._results[i].index = tileB;
    +                this._results[i].index = dest;
                 }
             }
     
    -        this.paste(x, y, this._results);
    +        this.paste(x, y, this._results, layer);
     
         },
     
         /**
         * Randomises a set of tiles in a given area.
    +    *
         * @method Phaser.Tilemap#random
    -    * @param {number} tileA - First tile index.
    -    * @param {number} tileB - Second tile index.
         * @param {number} x - X position of the top left of the area to operate one, given in tiles, not pixels.
         * @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels.
         * @param {number} width - The width in tiles of the area to operate on.
         * @param {number} height - The height in tiles of the area to operate on.
    -    * @param {number} [layer] - The Tilemap Layer to operate on.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on.
         */
         random: function (x, y, width, height, layer) {
     
    -        if (typeof layer === "undefined") { layer = this.currentLayer; }
    +        layer = this.getLayer(layer);
     
             this.copy(x, y, width, height, layer);
     
    @@ -907,11 +1490,14 @@ Phaser.Tilemap.prototype = {
     
             for (var t = 1; t < this._results.length; t++)
             {
    -            var idx = this._results[t].index;
    -
    -            if (indexes.indexOf(idx) === -1)
    +            if (this._results[t].index)
                 {
    -                indexes.push(idx);
    +                var idx = this._results[t].index;
    +
    +                if (indexes.indexOf(idx) === -1)
    +                {
    +                    indexes.push(idx);
    +                }
                 }
             }
     
    @@ -920,24 +1506,23 @@ Phaser.Tilemap.prototype = {
                 this._results[i].index = this.game.rnd.pick(indexes);
             }
     
    -        this.paste(x, y, this._results);
    +        this.paste(x, y, this._results, layer);
     
         },
     
         /**
         * Shuffles a set of tiles in a given area. It will only randomise the tiles in that area, so if they're all the same nothing will appear to have changed!
    +    *
         * @method Phaser.Tilemap#shuffle
    -    * @param {number} tileA - First tile index.
    -    * @param {number} tileB - Second tile index.
         * @param {number} x - X position of the top left of the area to operate one, given in tiles, not pixels.
         * @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels.
         * @param {number} width - The width in tiles of the area to operate on.
         * @param {number} height - The height in tiles of the area to operate on.
    -    * @param {number} [layer] - The Tilemap Layer to operate on.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on.
         */
         shuffle: function (x, y, width, height, layer) {
     
    -        if (typeof layer === "undefined") { layer = this.currentLayer; }
    +        layer = this.getLayer(layer);
     
             this.copy(x, y, width, height, layer);
     
    @@ -946,28 +1531,42 @@ Phaser.Tilemap.prototype = {
                 return;
             }
     
    -        var header = this._results.shift();
    +        var indexes = [];
     
    -        Phaser.Utils.shuffle(this._results);
    +        for (var t = 1; t < this._results.length; t++)
    +        {
    +            if (this._results[t].index)
    +            {
    +                indexes.push(this._results[t].index);
    +            }
    +        }
     
    -        this._results.unshift(header);
    +        Phaser.Utils.shuffle(indexes);
     
    -        this.paste(x, y, this._results);
    +        for (var i = 1; i < this._results.length; i++)
    +        {
    +            this._results[i].index = indexes[i - 1];
    +        }
    +
    +        this.paste(x, y, this._results, layer);
     
         },
     
         /**
    -    * Fill a block with a specific tile index.
    +    * Fills the given area with the specified tile.
    +    *
         * @method Phaser.Tilemap#fill
    -    * @param {number} index - Index of tiles you want to fill with.
    +    * @param {number} index - The index of the tile that the area will be filled with.
         * @param {number} x - X position of the top left of the area to operate one, given in tiles, not pixels.
         * @param {number} y - Y position of the top left of the area to operate one, given in tiles, not pixels.
         * @param {number} width - The width in tiles of the area to operate on.
         * @param {number} height - The height in tiles of the area to operate on.
    -    * @param {number} [layer] - The Tilemap Layer to operate on.
    +    * @param {number|string|Phaser.TilemapLayer} [layer] - The layer to operate on.
         */
         fill: function (index, x, y, width, height, layer) {
     
    +        layer = this.getLayer(layer);
    +
             this.copy(x, y, width, height, layer);
     
             if (this._results.length < 2)
    @@ -980,12 +1579,13 @@ Phaser.Tilemap.prototype = {
                 this._results[i].index = index;
             }
     
    -        this.paste(x, y, this._results);
    +        this.paste(x, y, this._results, layer);
     
         },
     
         /**
         * Removes all layers from this tile map.
    +    *
         * @method Phaser.Tilemap#removeAllLayers
         */
         removeAllLayers: function () {
    @@ -997,6 +1597,7 @@ Phaser.Tilemap.prototype = {
     
         /**
         * Dumps the tilemap data out to the console.
    +    *
         * @method Phaser.Tilemap#dump
         */
         dump: function () {
    @@ -1037,16 +1638,20 @@ Phaser.Tilemap.prototype = {
     
         /**
         * Removes all layers from this tile map and nulls the game reference.
    +    *
         * @method Phaser.Tilemap#destroy
         */
         destroy: function () {
     
             this.removeAllLayers();
    +        this.data = [];
             this.game = null;
     
         }
     
     };
    +
    +Phaser.Tilemap.prototype.constructor = Phaser.Tilemap;
     
    @@ -1062,13 +1667,13 @@ Phaser.Tilemap.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/TilemapLayer.js.html b/docs/TilemapLayer.js.html index 88cf9a57..e92aa009 100644 --- a/docs/TilemapLayer.js.html +++ b/docs/TilemapLayer.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -433,25 +427,37 @@
     * @class Phaser.TilemapLayer
     * @constructor
     * @param {Phaser.Game} game - Game reference to the currently running game.
    -* @param {number} x - The x coordinate of this layer.
    -* @param {number} y - The y coordinate of this layer.
    -* @param {number} renderWidth - Width of the layer.
    -* @param {number} renderHeight - Height of the layer.
    -* @param {Phaser.Tileset|string} tileset - The tile set used for rendering.
     * @param {Phaser.Tilemap} tilemap - The tilemap to which this layer belongs.
    -* @param {number} layer - The layer index within the map.
    +* @param {number} index - The layer index within the map that this TilemapLayer represents.
    +* @param {number} width - Width of the renderable area of the layer.
    +* @param {number} height - Height of the renderable area of the layer.
     */
    -Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset, tilemap, layer) {
    +Phaser.TilemapLayer = function (game, tilemap, index, width, height) {
     
         /**
         * @property {Phaser.Game} game - A reference to the currently running Game.
         */
         this.game = game;
    -    
    +
         /**
    -    * @property {HTMLCanvasElement} canvas - The canvas to which this BitmapData draws.
    +    * @property {Phaser.Tilemap} map - The Tilemap to which this layer is bound.
         */
    -    this.canvas = Phaser.Canvas.create(renderWidth, renderHeight);
    +    this.map = tilemap;
    +
    +    /**
    +    * @property {number} index - The index of this layer within the Tilemap.
    +    */
    +    this.index = index;
    +
    +    /**
    +    * @property {object} layer - The layer object within the Tilemap that this layer represents.
    +    */
    +    this.layer = tilemap.layers[index];
    +
    +    /**
    +    * @property {HTMLCanvasElement} canvas - The canvas to which this TilemapLayer draws.
    +    */
    +    this.canvas = Phaser.Canvas.create(width, height);
         
         /**
         * @property {CanvasRenderingContext2D} context - The 2d context of the canvas.
    @@ -471,9 +477,14 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset,
         /**
         * @property {Phaser.Frame} textureFrame - Dimensions of the renderable area.
         */
    -    this.textureFrame = new Phaser.Frame(0, 0, 0, renderWidth, renderHeight, 'tilemaplayer', game.rnd.uuid());
    +    this.textureFrame = new Phaser.Frame(0, 0, 0, width, height, 'tilemapLayer', game.rnd.uuid());
     
    -    Phaser.Sprite.call(this, this.game, x, y, this.texture, this.textureFrame);
    +    Phaser.Sprite.call(this, this.game, 0, 0, this.texture, this.textureFrame);
    +
    +    /**
    +    * @property {string} name - The name of the layer.
    +    */
    +    this.name = '';
     
         /**
         * @property {number} type - The const type of this object.
    @@ -482,58 +493,91 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset,
         this.type = Phaser.TILEMAPLAYER;
     
         /**
    -    * A layer that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera.
    -    * @property {boolean} fixedToCamera - Fixes this layer to the Camera.
    +    * An object that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera.
    +    * @property {boolean} fixedToCamera - Fixes this object to the Camera.
         * @default
         */
         this.fixedToCamera = true;
     
         /**
    -    * @property {Phaser.Tileset} tileset - The tile set used for rendering.
    +    * @property {Phaser.Point} cameraOffset - If this object is fixed to the camera then use this Point to specify how far away from the Camera x/y it's rendered.
         */
    -    this.tileset = null;
    +    this.cameraOffset = new Phaser.Point(0, 0);
     
         /**
    -    * @property {number} tileWidth - The width of a single tile in pixels.
    +    * @property {string} tileColor - If no tileset is given the tiles will be rendered as rectangles in this color. Provide in hex or rgb/rgba string format.
    +    * @default
         */
    -    this.tileWidth = 0;
    +    this.tileColor = 'rgb(255, 255, 255)';
     
         /**
    -    * @property {number} tileHeight - The height of a single tile in pixels.
    +    * @property {boolean} debug - If set to true the collideable tile edges path will be rendered. Only works when game is running in Phaser.CANVAS mode.
    +    * @default
         */
    -    this.tileHeight = 0;
    +    this.debug = false;
     
         /**
    -    * @property {number} tileMargin - The margin around the tiles.
    +    * @property {number} debugAlpha - If debug is true then the tileset is rendered with this alpha level, to make the tile edges clearer.
    +    * @default
         */
    -    this.tileMargin = 0;
    +    this.debugAlpha = 0.5;
     
         /**
    -    * @property {number} tileSpacing - The spacing around the tiles.
    +    * @property {string} debugColor - If debug is true this is the color used to outline the edges of collidable tiles. Provide in hex or rgb/rgba string format.
    +    * @default
         */
    -    this.tileSpacing = 0;
    +    this.debugColor = 'rgba(0, 255, 0, 1)';
     
         /**
    -    * @property {number} widthInPixels - Do NOT recommend changing after the map is loaded!
    -    * @readonly
    +    * @property {boolean} debugFill - If true the debug tiles are filled with debugFillColor AND stroked around.
    +    * @default
         */
    -    this.widthInPixels = 0;
    +    this.debugFill = false;
     
         /**
    -    * @property {number} heightInPixels - Do NOT recommend changing after the map is loaded!
    -    * @readonly
    +    * @property {string} debugFillColor - If debugFill is true this is the color used to fill the tiles. Provide in hex or rgb/rgba string format.
    +    * @default
         */
    -    this.heightInPixels = 0;
    +    this.debugFillColor = 'rgba(0, 255, 0, 0.2)';
     
         /**
    -    * @property {number} renderWidth - The width of the area being rendered.
    +    * @property {string} debugCallbackColor - If debug is true this is the color used to outline the edges of tiles that have collision callbacks. Provide in hex or rgb/rgba string format.
    +    * @default
         */
    -    this.renderWidth = renderWidth;
    +    this.debugCallbackColor = 'rgba(255, 0, 0, 1)';
     
         /**
    -    * @property {number} renderHeight - The height of the area being rendered.
    +    * @property {number} scrollFactorX - speed at which this layer scrolls
    +    * horizontally, relative to the camera (e.g. scrollFactorX of 0.5 scrolls
    +    * half as quickly as the 'normal' camera-locked layers do)
    +    * @default 1
         */
    -    this.renderHeight = renderHeight;
    +    this.scrollFactorX = 1;
    +
    +    /**
    +    * @property {number} scrollFactorY - speed at which this layer scrolls
    +    * vertically, relative to the camera (e.g. scrollFactorY of 0.5 scrolls
    +    * half as quickly as the 'normal' camera-locked layers do)
    +    * @default 1
    +    */
    +    this.scrollFactorY = 1;
    +
    +    /**
    +    * @property {boolean} dirty - Flag controlling when to re-render the layer.
    +    */
    +    this.dirty = true;
    +
    +    /**
    +    * @property {number} _cw - Local collision var.
    +    * @private 
    +    */
    +    this._cw = tilemap.tileWidth;
    +
    +    /**
    +    * @property {number} _ch - Local collision var.
    +    * @private 
    +    */
    +    this._ch = tilemap.tileHeight;
     
         /**
         * @property {number} _ga - Local render loop var to help avoid gc spikes.
    @@ -649,51 +693,7 @@ Phaser.TilemapLayer = function (game, x, y, renderWidth, renderHeight, tileset,
         */
         this._prevY = 0;
     
    -    /**
    -    * @property {number} scrollFactorX - speed at which this layer scrolls
    -    * horizontally, relative to the camera (e.g. scrollFactorX of 0.5 scrolls
    -    * half as quickly as the 'normal' camera-locked layers do)
    -    * @default 1
    -    */
    -    this.scrollFactorX = 1;
    -
    -    /**
    -    * @property {number} scrollFactorY - speed at which this layer scrolls
    -    * vertically, relative to the camera (e.g. scrollFactorY of 0.5 scrolls
    -    * half as quickly as the 'normal' camera-locked layers do)
    -    * @default 1
    -    */
    -    this.scrollFactorY = 1;
    -
    -    /**
    -    * @property {Phaser.Tilemap} tilemap - The Tilemap to which this layer is bound.
    -    */
    -    this.tilemap = null;
    -
    -    /**
    -    * @property {number} layer - Tilemap layer index.
    -    */
    -    this.layer = null;
    -
    -    /**
    -    * @property {number} index
    -    */
    -    this.index = 0;
    -
    -    /**
    -    * @property {boolean} dirty - Flag controlling when to re-render the layer.
    -    */
    -    this.dirty = true;
    -
    -    if (tileset instanceof Phaser.Tileset || typeof tileset === 'string')
    -    {
    -        this.updateTileset(tileset);
    -    }
    -
    -    if (tilemap instanceof Phaser.Tilemap)
    -    {
    -        this.updateMapData(tilemap, layer);
    -    }
    +    this.updateMax();
     
     };
     
    @@ -702,13 +702,16 @@ Phaser.TilemapLayer.prototype = Phaser.Utils.extend(true, Phaser.TilemapLayer.pr
     Phaser.TilemapLayer.prototype.constructor = Phaser.TilemapLayer;
     
     /**
    -* Automatically called by World.preUpdate. Handles cache updates.
    +* Automatically called by World.postUpdate. Handles cache updates.
     *
    -* @method Phaser.TilemapLayer#update
    +* @method Phaser.TilemapLayer#postUpdate
     * @memberof Phaser.TilemapLayer
     */
    -Phaser.TilemapLayer.prototype.update = function () {
    +Phaser.TilemapLayer.prototype.postUpdate = function () {
     
    +	Phaser.Sprite.prototype.postUpdate.call(this);
    +	
    +    //  Stops you being able to auto-scroll the camera if it's not following a sprite
         this.scrollX = this.game.camera.x * this.scrollFactorX;
         this.scrollY = this.game.camera.y * this.scrollFactorY;
     
    @@ -724,69 +727,12 @@ Phaser.TilemapLayer.prototype.update = function () {
     */
     Phaser.TilemapLayer.prototype.resizeWorld = function () {
     
    -    this.game.world.setBounds(0, 0, this.widthInPixels, this.heightInPixels);
    +    this.game.world.setBounds(0, 0, this.layer.widthInPixels, this.layer.heightInPixels);
     
     }
     
     /**
    -* Updates the Tileset data.
    -*
    -* @method Phaser.TilemapLayer#updateTileset
    -* @memberof Phaser.TilemapLayer
    -* @param {Phaser.Tileset|string} tileset - The tileset to use for this layer.
    -*/
    -Phaser.TilemapLayer.prototype.updateTileset = function (tileset) {
    -
    -    if (tileset instanceof Phaser.Tileset)
    -    {
    -        this.tileset = tileset;
    -    }
    -    else if (typeof tileset === 'string')
    -    {
    -        this.tileset = this.game.cache.getTileset('tiles');
    -    }
    -    else
    -    {
    -        return;
    -    }
    -
    -    this.tileWidth = this.tileset.tileWidth;
    -    this.tileHeight = this.tileset.tileHeight;
    -    this.tileMargin = this.tileset.tileMargin;
    -    this.tileSpacing = this.tileset.tileSpacing;
    -
    -    this.updateMax();
    -
    -}
    -
    -/**
    -* Updates the Tilemap data.
    -*
    -* @method Phaser.TilemapLayer#updateMapData
    -* @memberof Phaser.TilemapLayer
    -* @param {Phaser.Tilemap} tilemap - The tilemap to which this layer belongs.
    -* @param {number} layer - The layer index within the map.
    -*/
    -Phaser.TilemapLayer.prototype.updateMapData = function (tilemap, layer) {
    -
    -    if (typeof layer === 'undefined')
    -    {
    -        layer = 0;
    -    }
    -
    -    if (tilemap instanceof Phaser.Tilemap)
    -    {
    -        this.tilemap = tilemap;
    -        this.layer = this.tilemap.layers[layer];
    -        this.index = layer;
    -        this.updateMax();
    -        this.tilemap.dirty = true;
    -    }
    -
    -}
    -
    -/**
    -* Take an x coordinate that doesn't account for scrollFactorY and 'fix' it 
    +* Take an x coordinate that doesn't account for scrollFactorX and 'fix' it 
     * into a scrolled local space. Used primarily internally
     * @method Phaser.TilemapLayer#_fixX
     * @memberof Phaser.TilemapLayer
    @@ -796,19 +742,22 @@ Phaser.TilemapLayer.prototype.updateMapData = function (tilemap, layer) {
     */
     Phaser.TilemapLayer.prototype._fixX = function(x) {
     
    +    if (x < 0)
    +    {
    +        x = 0;
    +    }
    +
         if (this.scrollFactorX === 1)
         {
             return x;
         }
     
    -    var leftEdge = x - (this._x / this.scrollFactorX);
    -
    -    return this._x + leftEdge;
    +    return this._x + (x - (this._x / this.scrollFactorX));
     
     }
     
     /**
    -* Take an x coordinate that _does_ account for scrollFactorY and 'unfix' it 
    +* Take an x coordinate that _does_ account for scrollFactorX and 'unfix' it 
     * back to camera space. Used primarily internally
     * @method Phaser.TilemapLayer#_unfixX
     * @memberof Phaser.TilemapLayer
    @@ -823,9 +772,7 @@ Phaser.TilemapLayer.prototype._unfixX = function(x) {
             return x;
         }
     
    -    var leftEdge = x - this._x;
    -
    -    return (this._x / this.scrollFactorX) + leftEdge;
    +    return (this._x / this.scrollFactorX) + (x - this._x);
     
     }
     
    @@ -840,14 +787,17 @@ Phaser.TilemapLayer.prototype._unfixX = function(x) {
     */
     Phaser.TilemapLayer.prototype._fixY = function(y) {
     
    +    if (y < 0)
    +    {
    +        y = 0;
    +    }
    +
         if (this.scrollFactorY === 1)
         {
             return y;
         }
     
    -    var topEdge = y - (this._y / this.scrollFactorY);
    -
    -    return this._y + topEdge;
    +    return this._y + (y - (this._y / this.scrollFactorY));
     
     }
     
    @@ -867,9 +817,7 @@ Phaser.TilemapLayer.prototype._unfixY = function(y) {
             return y;
         }
     
    -    var topEdge = y - this._y;
    -
    -    return (this._y / this.scrollFactorY) + topEdge;
    +    return (this._y / this.scrollFactorY) + (y - this._y);
     
     }
     
    @@ -882,9 +830,9 @@ Phaser.TilemapLayer.prototype._unfixY = function(y) {
     */
     Phaser.TilemapLayer.prototype.getTileX = function (x) {
     
    -    var tileWidth = this.tileWidth * this.scale.x;
    +    // var tileWidth = this.tileWidth * this.scale.x;
     
    -    return this.game.math.snapToFloor(this._fixX(x), tileWidth) / tileWidth;
    +    return this.game.math.snapToFloor(this._fixX(x), this.map.tileWidth) / this.map.tileWidth;
     
     }
     
    @@ -897,9 +845,9 @@ Phaser.TilemapLayer.prototype.getTileX = function (x) {
     */
     Phaser.TilemapLayer.prototype.getTileY = function (y) {
     
    -    var tileHeight = this.tileHeight * this.scale.y;
    +    // var tileHeight = this.tileHeight * this.scale.y;
     
    -    return this.game.math.snapToFloor(this._fixY(y), tileHeight) / tileHeight;
    +    return this.game.math.snapToFloor(this._fixY(y), this.map.tileHeight) / this.map.tileHeight;
     
     }
     
    @@ -909,7 +857,8 @@ Phaser.TilemapLayer.prototype.getTileY = function (y) {
     * @memberof Phaser.TilemapLayer
     * @param {number} x - X position of the point in target tile.
     * @param {number} y - Y position of the point in target tile.
    -* @return {Phaser.Tile} The tile with specific properties.
    +* @param {Phaser.Point|object} point - The Point object to set the x and y values on.
    +* @return {Phaser.Point|object} A Point object with its x and y properties set.
     */
     Phaser.TilemapLayer.prototype.getTileXY = function (x, y, point) {
     
    @@ -921,73 +870,43 @@ Phaser.TilemapLayer.prototype.getTileXY = function (x, y, point) {
     }
     
     /**
    -* Get the tiles within the given area.
    +* Get all tiles that exist within the given area, defined by the top-left corner, width and height. Values given are in pixels, not tiles.
     * @method Phaser.TilemapLayer#getTiles
     * @memberof Phaser.TilemapLayer
    -* @param {number} x - X position of the top left of the area to copy (given in tiles, not pixels)
    -* @param {number} y - Y position of the top left of the area to copy (given in tiles, not pixels)
    -* @param {number} width - The width of the area to copy (given in tiles, not pixels)
    -* @param {number} height - The height of the area to copy (given in tiles, not pixels)
    -* @param {boolean} collides - If true only return tiles that collide on one or more faces.
    +* @param {number} x - X position of the top left corner.
    +* @param {number} y - Y position of the top left corner.
    +* @param {number} width - Width of the area to get.
    +* @param {number} height - Height of the area to get.
    +* @param {boolean} [collides=false] - If true only return tiles that collide on one or more faces.
     * @return {array} Array with tiles informations (each contains x, y, and the tile).
     */
     Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides) {
     
    -    if (this.tilemap === null)
    -    {
    -        return;
    -    }
    -
         //  Should we only get tiles that have at least one of their collision flags set? (true = yes, false = no just get them all)
         if (typeof collides === 'undefined') { collides = false; }
     
    -    //  Cap the values
    -
    -    if (x < 0)
    -    {
    -        x = 0;
    -    }
    -
    -    if (y < 0)
    -    {
    -        y = 0;
    -    }
    -
         // adjust the x,y coordinates for scrollFactor
    -    x = this._fixX( x );
    -    y = this._fixY( y );
    +    x = this._fixX(x);
    +    y = this._fixY(y);
     
    -    if (width > this.widthInPixels)
    +    if (width > this.layer.widthInPixels)
         {
    -        width = this.widthInPixels;
    +        width = this.layer.widthInPixels;
         }
     
    -    if (height > this.heightInPixels)
    +    if (height > this.layer.heightInPixels)
         {
    -        height = this.heightInPixels;
    +        height = this.layer.heightInPixels;
         }
     
    -    var tileWidth = this.tileWidth * this.scale.x;
    -    var tileHeight = this.tileHeight * this.scale.y;
    -
         //  Convert the pixel values into tile coordinates
    -    this._tx = this.game.math.snapToFloor(x, tileWidth) / tileWidth;
    -    this._ty = this.game.math.snapToFloor(y, tileHeight) / tileHeight;
    -    this._tw = (this.game.math.snapToCeil(width, tileWidth) + tileWidth) / tileWidth;
    -    this._th = (this.game.math.snapToCeil(height, tileHeight) + tileHeight) / tileHeight;
    +    this._tx = this.game.math.snapToFloor(x, this._cw) / this._cw;
    +    this._ty = this.game.math.snapToFloor(y, this._ch) / this._ch;
    +    this._tw = (this.game.math.snapToCeil(width, this._cw) + this._cw) / this._cw;
    +    this._th = (this.game.math.snapToCeil(height, this._ch) + this._ch) / this._ch;
     
         //  This should apply the layer x/y here
    -
    -    // this._results.length = 0;
    -    this._results = [];
    -
    -    //  pretty sure we don't use this any more?
    -    // this._results.push( { x: x, y: y, width: width, height: height, tx: this._tx, ty: this._ty, tw: this._tw, th: this._th });
    -
    -    var _index = 0;
    -    var _tile = null;
    -    var sx = 0;
    -    var sy = 0;
    +    this._results.length = 0;
     
         for (var wy = this._ty; wy < this._ty + this._th; wy++)
         {
    @@ -995,19 +914,20 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides
             {
                 if (this.layer.data[wy] && this.layer.data[wy][wx])
                 {
    -                //  Could combine
    -                _index = this.layer.data[wy][wx] - 1;
    -                _tile = this.tileset.getTile(_index);
    -
    -                sx = _tile.width * this.scale.x;
    -                sy = _tile.height * this.scale.y;
    -
    -                if (collides === false || (collides && _tile.collideNone === false))
    +                if (collides === false || (collides && this.layer.data[wy][wx].canCollide))
                     {
    -                    // convert tile coordinates back to camera space for return
    -                    var _wx = this._unfixX( wx*sx ) / tileWidth;
    -                    var _wy = this._unfixY( wy*sy ) / tileHeight;
    -                    this._results.push({ x: _wx * sx, right: (_wx * sx) + sx, y: _wy * sy, bottom: (_wy * sy) + sy, width: sx, height: sy, tx: _wx, ty: _wy, tile: _tile });
    +                    //  Convert tile coordinates back to camera space for return
    +                    var _wx = this._unfixX(wx * this._cw) / this._cw;
    +                    var _wy = this._unfixY(wy * this._ch) / this._ch;
    +
    +                    this._results.push({ 
    +                        x: _wx * this._cw, 
    +                        y: _wy * this._ch, 
    +                        right: (_wx * this._cw) + this._cw, 
    +                        bottom: (_wy * this._ch) + this._ch, 
    +                        tile: this.layer.data[wy][wx],
    +                        layer: this.layer.data[wy][wx].layer
    +                    });
                     }
                 }
             }
    @@ -1024,8 +944,8 @@ Phaser.TilemapLayer.prototype.getTiles = function (x, y, width, height, collides
     */
     Phaser.TilemapLayer.prototype.updateMax = function () {
     
    -    this._maxX = this.game.math.ceil(this.canvas.width / this.tileWidth) + 1;
    -    this._maxY = this.game.math.ceil(this.canvas.height / this.tileHeight) + 1;
    +    this._maxX = this.game.math.ceil(this.canvas.width / this.map.tileWidth) + 1;
    +    this._maxY = this.game.math.ceil(this.canvas.height / this.map.tileHeight) + 1;
     
         if (this.layer)
         {
    @@ -1038,9 +958,6 @@ Phaser.TilemapLayer.prototype.updateMax = function () {
             {
                 this._maxY = this.layer.height;
             }
    -
    -        this.widthInPixels = this.layer.width * this.tileWidth;
    -        this.heightInPixels = this.layer.height * this.tileHeight;
         }
     
         this.dirty = true;
    @@ -1054,12 +971,12 @@ Phaser.TilemapLayer.prototype.updateMax = function () {
     */
     Phaser.TilemapLayer.prototype.render = function () {
     
    -    if (this.tilemap && this.tilemap.dirty)
    +	if (this.layer.dirty)
         {
             this.dirty = true;
         }
     
    -    if (!this.dirty || !this.tileset || !this.tilemap || !this.visible)
    +    if (!this.dirty || !this.visible)
         {
             return;
         }
    @@ -1067,101 +984,194 @@ Phaser.TilemapLayer.prototype.render = function () {
         this._prevX = this._dx;
         this._prevY = this._dy;
     
    -    this._dx = -(this._x - (this._startX * this.tileWidth));
    -    this._dy = -(this._y - (this._startY * this.tileHeight));
    +    this._dx = -(this._x - (this._startX * this.map.tileWidth));
    +    this._dy = -(this._y - (this._startY * this.map.tileHeight));
     
         this._tx = this._dx;
         this._ty = this._dy;
     
         this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
     
    -    for (var y = this._startY; y < this._startY + this._maxY; y++)
    +    this.context.fillStyle = this.tileColor;
    +
    +    var tile;
    +    var set;
    +    var ox = 0;
    +    var oy = 0;
    +
    +    if (this.debug)
    +    {
    +        this.context.globalAlpha = this.debugAlpha;
    +    }
    +
    +    for (var y = this._startY, lenY = this._startY + this._maxY; y < lenY; y++)
         {
             this._column = this.layer.data[y];
     
    -        for (var x = this._startX; x < this._startX + this._maxX; x++)
    +        for (var x = this._startX, lenX = this._startX + this._maxX; x < lenX; x++)
             {
    -            //  only -1 on TILED maps, not CSV
    -            var tile = this.tileset.tiles[this._column[x]-1];
    -
    -            if (tile)
    +            if (this._column[x])
                 {
    -                this.context.drawImage(
    -                    this.tileset.image,
    -                    tile.x,
    -                    tile.y,
    -                    this.tileWidth,
    -                    this.tileHeight,
    -                    Math.floor(this._tx),
    -                    Math.floor(this._ty),
    -                    this.tileWidth,
    -                    this.tileHeight
    -                );
    +                tile = this._column[x];
    +
    +                if (this.map.tiles[tile.index])
    +                {
    +                    set = this.map.tilesets[this.map.tiles[tile.index][2]]
    +
    +                    if (set.image)
    +                    {
    +                        if (this.debug === false && tile.alpha !== this.context.globalAlpha)
    +                        {
    +                            this.context.globalAlpha = tile.alpha;
    +                        }
    +
    +                        if (set.tileWidth !== this.map.tileWidth || set.tileHeight !== this.map.tileHeight)
    +                        {
    +                            //  TODO: Smaller sized tile check
    +                            this.context.drawImage(
    +                                this.map.tilesets[this.map.tiles[tile.index][2]].image,
    +                                this.map.tiles[tile.index][0],
    +                                this.map.tiles[tile.index][1],
    +                                set.tileWidth,
    +                                set.tileHeight,
    +                                Math.floor(this._tx),
    +                                Math.floor(this._ty) - (set.tileHeight - this.map.tileHeight),
    +                                set.tileWidth,
    +                                set.tileHeight
    +                            );
    +                        }
    +                        else
    +                        {
    +                            this.context.drawImage(
    +                                this.map.tilesets[this.map.tiles[tile.index][2]].image,
    +                                this.map.tiles[tile.index][0],
    +                                this.map.tiles[tile.index][1],
    +                                this.map.tileWidth,
    +                                this.map.tileHeight,
    +                                Math.floor(this._tx),
    +                                Math.floor(this._ty),
    +                                this.map.tileWidth,
    +                                this.map.tileHeight
    +                            );
    +                        }
    +
    +                        if (tile.debug)
    +                        {
    +                            this.context.fillStyle = 'rgba(0, 255, 0, 0.4)';
    +                            this.context.fillRect(Math.floor(this._tx), Math.floor(this._ty), this.map.tileWidth, this.map.tileHeight);
    +                        }
    +                    }
    +                    else
    +                    {
    +                        this.context.fillRect(Math.floor(this._tx), Math.floor(this._ty), this.map.tileWidth, this.map.tileHeight);
    +                    }
    +                }
                 }
     
    -            this._tx += this.tileWidth;
    +            this._tx += this.map.tileWidth;
     
             }
     
             this._tx = this._dx;
    -        this._ty += this.tileHeight;
    +        this._ty += this.map.tileHeight;
    +
    +    }
    +
    +    if (this.debug)
    +    {
    +        this.context.globalAlpha = 1;
    +        this.renderDebug();
         }
     
         //  Only needed if running in WebGL, otherwise this array will never get cleared down I don't think!
    -    if (this.game.renderType == Phaser.WEBGL)
    +    if (this.game.renderType === Phaser.WEBGL)
         {
             PIXI.texturesToUpdate.push(this.baseTexture);
         }
     
         this.dirty = false;
    -
    -    if (this.tilemap.dirty)
    -    {
    -        this.tilemap.dirty = false;
    -    }
    +    this.layer.dirty = false;
     
         return true;
     
     }
     
     /**
    -* Returns the absolute delta x value.
    -* @method Phaser.TilemapLayer#deltaAbsX
    +* Renders a collision debug overlay on-top of the canvas. Called automatically by render when debug = true.
    +* @method Phaser.TilemapLayer#renderDebug
     * @memberof Phaser.TilemapLayer
    -* @return {number} Absolute delta X value
     */
    -Phaser.TilemapLayer.prototype.deltaAbsX = function () {
    -    return (this.deltaX() > 0 ? this.deltaX() : -this.deltaX());
    -}
    +Phaser.TilemapLayer.prototype.renderDebug = function () {
     
    -/**
    -* Returns the absolute delta y value.
    -* @method Phaser.TilemapLayer#deltaAbsY
    -* @memberof Phaser.TilemapLayer
    -* @return {number} Absolute delta Y value
    -*/
    -Phaser.TilemapLayer.prototype.deltaAbsY = function () {
    -    return (this.deltaY() > 0 ? this.deltaY() : -this.deltaY());
    -}
    +    this._tx = this._dx;
    +    this._ty = this._dy;
     
    -/**
    -* Returns the delta x value.
    -* @method Phaser.TilemapLayer#deltaX
    -* @memberof Phaser.TilemapLayer
    -* @return {number} Delta X value
    -*/
    -Phaser.TilemapLayer.prototype.deltaX = function () {
    -    return this._dx - this._prevX;
    -}
    +    this.context.strokeStyle = this.debugColor;
    +    this.context.fillStyle = this.debugFillColor;
    +
    +    for (var y = this._startY, lenY = this._startY + this._maxY; y < lenY; y++)
    +    {
    +        this._column = this.layer.data[y];
    +
    +        for (var x = this._startX, lenX = this._startX + this._maxX; x < lenX; x++)
    +        {
    +            var tile = this._column[x];
    +
    +            if (tile && (tile.faceTop || tile.faceBottom || tile.faceLeft || tile.faceRight))
    +            {
    +                this._tx = Math.floor(this._tx);
    +
    +                if (this.debugFill)
    +                {
    +                    this.context.fillRect(this._tx, this._ty, this._cw, this._ch);
    +                }
    +
    +                this.context.beginPath();
    +
    +                if (tile.faceTop)
    +                {
    +                    this.context.moveTo(this._tx, this._ty);
    +                    this.context.lineTo(this._tx + this._cw, this._ty);
    +                }
    +
    +                if (tile.faceBottom)
    +                {
    +                    this.context.moveTo(this._tx, this._ty + this._ch);
    +                    this.context.lineTo(this._tx + this._cw, this._ty + this._ch);
    +                }
    +
    +                if (tile.faceLeft)
    +                {
    +                    this.context.moveTo(this._tx, this._ty);
    +                    this.context.lineTo(this._tx, this._ty + this._ch);
    +                }
    +
    +                if (tile.faceRight)
    +                {
    +                    this.context.moveTo(this._tx + this._cw, this._ty);
    +                    this.context.lineTo(this._tx + this._cw, this._ty + this._ch);
    +                }
    +
    +                this.context.stroke();
    +            }
    +
    +            //  Collision callback
    +            if (tile && (tile.collisionCallback || tile.layer.callbacks[tile.index]))
    +            {
    +                this.context.fillStyle = this.debugCallbackColor;
    +                this.context.fillRect(this._tx, this._ty, this._cw, this._ch);
    +                this.context.fillStyle = this.debugFillColor;
    +            }
    +
    +            this._tx += this.map.tileWidth;
    +
    +        }
    +
    +        this._tx = this._dx;
    +        this._ty += this.map.tileHeight;
    +
    +    }
     
    -/**
    -* Returns the delta y value.
    -* @method Phaser.TilemapLayer#deltaY
    -* @memberof Phaser.TilemapLayer
    -* @return {number} Delta Y value
    -*/
    -Phaser.TilemapLayer.prototype.deltaY = function () {
    -    return this._dy - this._prevY;
     }
     
     /**
    @@ -1176,16 +1186,17 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollX", {
     
         set: function (value) {
     
    -        if (value !== this._x && value >= 0 && this.layer)
    +        // if (value !== this._x && value >= 0 && this.layer && this.layer.widthInPixels > this.width)
    +        if (value !== this._x && value >= 0 && this.layer.widthInPixels > this.width)
             {
                 this._x = value;
    -
    -            if (this._x > (this.widthInPixels - this.renderWidth))
    +    
    +            if (this._x > (this.layer.widthInPixels - this.width))
                 {
    -                this._x = this.widthInPixels - this.renderWidth;
    +                this._x = this.layer.widthInPixels - this.width;
                 }
     
    -            this._startX = this.game.math.floor(this._x / this.tileWidth);
    +            this._startX = this.game.math.floor(this._x / this.map.tileWidth);
     
                 if (this._startX < 0)
                 {
    @@ -1216,16 +1227,17 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollY", {
     
         set: function (value) {
     
    -        if (value !== this._y && value >= 0 && this.layer)
    +        // if (value !== this._y && value >= 0 && this.layer && this.heightInPixels > this.renderHeight)
    +        if (value !== this._y && value >= 0 && this.layer.heightInPixels > this.height)
             {
                 this._y = value;
     
    -            if (this._y > (this.heightInPixels - this.renderHeight))
    +            if (this._y > (this.layer.heightInPixels - this.height))
                 {
    -                this._y = this.heightInPixels - this.renderHeight;
    +                this._y = this.layer.heightInPixels - this.height;
                 }
     
    -            this._startY = this.game.math.floor(this._y / this.tileHeight);
    +            this._startY = this.game.math.floor(this._y / this.map.tileHeight);
     
                 if (this._startY < 0)
                 {
    @@ -1242,6 +1254,46 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollY", {
     
         }
     
    +});
    +
    +/**
    +* @name Phaser.TilemapLayer#collisionWidth
    +* @property {number} collisionWidth - The width of the collision tiles.
    +*/
    +Object.defineProperty(Phaser.TilemapLayer.prototype, "collisionWidth", {
    +    
    +    get: function () {
    +        return this._cw;
    +    },
    +
    +    set: function (value) {
    +
    +        this._cw = value;
    +
    +        this.dirty = true;
    +
    +    }
    +
    +});
    +
    +/**
    +* @name Phaser.TilemapLayer#collisionHeight
    +* @property {number} collisionHeight - The height of the collision tiles.
    +*/
    +Object.defineProperty(Phaser.TilemapLayer.prototype, "collisionHeight", {
    +    
    +    get: function () {
    +        return this._ch;
    +    },
    +
    +    set: function (value) {
    +
    +        this._ch = value;
    +
    +        this.dirty = true;
    +
    +    }
    +
     });
     
    @@ -1258,13 +1310,13 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "scrollY", { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/TilemapParser.js.html b/docs/TilemapParser.js.html index c4f1ddb2..8bd6058b 100644 --- a/docs/TilemapParser.js.html +++ b/docs/TilemapParser.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -438,47 +432,45 @@ Phaser.TilemapParser = {
         * Creates a Tileset object.
         * @method Phaser.TilemapParser.tileset
         * @param {Phaser.Game} game - Game reference to the currently running game.
    -    * @param {string} key
    -    * @param {number} tileWidth
    -    * @param {number} tileHeight
    -    * @param {number} tileMax
    -    * @param {number} tileMargin
    -    * @param {number} tileSpacing
    +    * @param {string} key - The Cache key of this tileset.
    +    * @param {number} tileWidth - Width of each single tile in pixels.
    +    * @param {number} tileHeight - Height of each single tile in pixels.
    +    * @param {number} [tileMargin=0] - If the tiles have been drawn with a margin, specify the amount here.
    +    * @param {number} [tileSpacing=0] - If the tiles have been drawn with spacing between them, specify the amount here.
    +    * @param {number} [rows=-1] - How many tiles are placed horizontally in each row? If -1 it will calculate rows by dividing the image width by tileWidth.
    +    * @param {number} [columns=-1] - How many tiles are placed vertically in each column? If -1 it will calculate columns by dividing the image height by tileHeight.
    +    * @param {number} [total=-1] - The maximum number of tiles to extract from the image. If -1 it will extract `rows * columns` worth. You can also set a value lower than the actual number of tiles.
         * @return {Phaser.Tileset} Generated Tileset object.
         */
    -    tileset: function (game, key, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) {
    +    tileset: function (game, key, tileWidth, tileHeight, tileMargin, tileSpacing, rows, columns, total) {
     
             //  How big is our image?
             var img = game.cache.getTilesetImage(key);
     
    -        if (img == null)
    +        if (img === null)
             {
    +            console.warn("Phaser.TilemapParser.tileSet: Invalid image key given");
                 return null;
             }
     
             var width = img.width;
             var height = img.height;
     
    -        //  If no tile width/height is given, try and figure it out (won't work if the tileset has margin/spacing)
    -        if (tileWidth <= 0)
    +        if (rows === -1)
             {
    -            tileWidth = Math.floor(-width / Math.min(-1, tileWidth));
    +            rows = Math.round(width / tileWidth);
             }
     
    -        if (tileHeight <= 0)
    +        if (columns === -1)
             {
    -            tileHeight = Math.floor(-height / Math.min(-1, tileHeight));
    +            columns = Math.round(height / tileHeight);
             }
     
    -        var row = Math.round(width / tileWidth);
    -        var column = Math.round(height / tileHeight);
    -        var total = row * column;
    +        if (total === -1)
    +        {
    +            total = rows * columns;
    +        }
             
    -        if (tileMax !== -1)
    -        {
    -            total = tileMax;
    -        }
    -
             //  Zero or smaller than tile sizes?
             if (width === 0 || height === 0 || width < tileWidth || height < tileHeight || total === 0)
             {
    @@ -486,26 +478,7 @@ Phaser.TilemapParser = {
                 return null;
             }
     
    -        //  Let's create some tiles
    -        var x = tileMargin;
    -        var y = tileMargin;
    -
    -        var tileset = new Phaser.Tileset(img, key, tileWidth, tileHeight, tileMargin, tileSpacing);
    -
    -        for (var i = 0; i < total; i++)
    -        {
    -            tileset.addTile(new Phaser.Tile(tileset, i, x, y, tileWidth, tileHeight));
    -
    -            x += tileWidth + tileSpacing;
    -
    -            if (x === width)
    -            {
    -                x = tileMargin;
    -                y += tileHeight + tileSpacing;
    -            }
    -        }
    -
    -        return tileset;
    +        return new Phaser.Tileset(img, key, tileWidth, tileHeight, tileMargin, tileSpacing, rows, columns, total);
     
         },
     
    @@ -513,19 +486,27 @@ Phaser.TilemapParser = {
         * Parse tileset data from the cache and creates a Tileset object.
         * @method Phaser.TilemapParser.parse
         * @param {Phaser.Game} game - Game reference to the currently running game.
    -    * @param {object} data
    -    * @param {string} format
    -    * @return {Phaser.Tileset} Generated Tileset object.
    +    * @param {string} key - The key of the tilemap in the Cache.
    +    * @return {object} The parsed map object.
         */
    -    parse: function (game, data, format) {
    +    parse: function (game, key) {
     
    -        if (format === Phaser.Tilemap.CSV)
    +        var map = game.cache.getTilemapData(key);
    +
    +        if (map)
             {
    -            return this.parseCSV(data);
    +            if (map.format === Phaser.Tilemap.CSV)
    +            {
    +                return this.parseCSV(map.data);
    +            }
    +            else if (map.format === Phaser.Tilemap.TILED_JSON)
    +            {
    +                return this.parseTiledJSON(map.data);
    +            }
             }
    -        else if (format === Phaser.Tilemap.TILED_JSON)
    +        else
             {
    -            return this.parseTiledJSON(data);
    +            return { layers: [], objects: [], images: [], tilesets: [] };
             }
     
         },
    @@ -563,6 +544,8 @@ Phaser.TilemapParser = {
                 }
             }
     
    +        //  Build collision map
    +
             return [{ name: 'csv', width: width, height: height, alpha: 1, visible: true, indexes: [], tileMargin: 0, tileSpacing: 0, data: output }];
     
         },
    @@ -570,66 +553,242 @@ Phaser.TilemapParser = {
         /**
         * Parses a Tiled JSON file into valid map data.
         * @method Phaser.TilemapParser.parseJSON
    -    * @param {object} json- The Tiled JSON data.
    -    * @return {object} Generated map data.
    +    * @param {object} json - The JSON map data.
    +    * @return {object} Generated and parsed map data.
         */
         parseTiledJSON: function (json) {
     
    +        if (json.orientation !== 'orthogonal')
    +        {
    +            console.warn('TilemapParser.parseTiledJSON: Only orthogonal map types are supported in this version of Phaser');
    +            return null;
    +        }
    +
    +        //  Map data will consist of: layers, objects, images, tilesets, sizes
    +        var map = {};
    +
    +        map.width = json.width;
    +        map.height = json.height;
    +        map.tileWidth = json.tilewidth;
    +        map.tileHeight = json.tileheight;
    +        map.orientation = json.orientation;
    +        map.version = json.version;
    +        map.properties = json.properties;
    +        map.widthInPixels = map.width * map.tileWidth;
    +        map.heightInPixels = map.height * map.tileHeight;
    +
    +        //  Tile Layers
             var layers = [];
     
             for (var i = 0; i < json.layers.length; i++)
             {
    -            //  Check it's a data layer
    -            if (!json.layers[i].data)
    +            if (json.layers[i].type !== 'tilelayer')
                 {
                     continue;
                 }
     
    -            //  json.tilewidth
    -            //  json.tileheight
    -
                 var layer = {
     
                     name: json.layers[i].name,
    +                x: json.layers[i].x,
    +                y: json.layers[i].y,
                     width: json.layers[i].width,
                     height: json.layers[i].height,
    +                widthInPixels: json.layers[i].width * json.tilewidth,
    +                heightInPixels: json.layers[i].height * json.tileheight,
                     alpha: json.layers[i].opacity,
                     visible: json.layers[i].visible,
    +                properties: {},
                     indexes: [],
    -
    -                tileMargin: json.tilesets[0].margin,
    -                tileSpacing: json.tilesets[0].spacing
    +                callbacks: []
     
                 };
     
    -            var output = [];
    -            var c = 0;
    -            var row;
    -
    -            for (var t = 0; t < json.layers[i].data.length; t++)
    +            if (json.layers[i].properties)
                 {
    -                if (c === 0)
    +                layer.properties = json.layers[i].properties;
    +            }
    +
    +            var x = 0;
    +            var row = [];
    +            var output = [];
    +
    +            //  Loop through the data field in the JSON.
    +
    +            //  This is an array containing the tile indexes, one after the other. 0 = no tile, everything else = the tile index (starting at 1)
    +            //  If the map contains multiple tilesets then the indexes are relative to that which the set starts from.
    +            //  Need to set which tileset in the cache = which tileset in the JSON, if you do this manually it means you can use the same map data but a new tileset.
    +
    +            for (var t = 0, len = json.layers[i].data.length; t < len; t++)
    +            {
    +                //  index, x, y, width, height
    +                if (json.layers[i].data[t] > 0)
                     {
    -                    row = [];
    +                    row.push(new Phaser.Tile(layer, json.layers[i].data[t], x, output.length, json.tilewidth, json.tileheight));
    +                }
    +                else
    +                {
    +                    row.push(null);
                     }
     
    -                row.push(json.layers[i].data[t]);
    -                c++;
    +                x++;
     
    -                if (c == json.layers[i].width)
    +                if (x === json.layers[i].width)
                     {
                         output.push(row);
    -                    c = 0;
    +                    x = 0;
    +                    row = [];
                     }
                 }
     
                 layer.data = output;
    -            
    +
                 layers.push(layer);
     
             }
     
    -        return layers;
    +        map.layers = layers;
    +
    +        //  Images
    +        var images = [];
    +
    +        for (var i = 0; i < json.layers.length; i++)
    +        {
    +            if (json.layers[i].type !== 'imagelayer')
    +            {
    +                continue;
    +            }
    +
    +            var image = {
    +
    +                name: json.layers[i].name,
    +                image: json.layers[i].image,
    +                x: json.layers[i].x,
    +                y: json.layers[i].y,
    +                alpha: json.layers[i].opacity,
    +                visible: json.layers[i].visible,
    +                properties: {}
    +
    +            };
    +
    +            if (json.layers[i].properties)
    +            {
    +                image.properties = json.layers[i].properties;
    +            }
    +
    +            images.push(image);
    +
    +        }
    +
    +        map.images = images;
    +
    +        //  Objects
    +        var objects = {};
    +
    +        for (var i = 0; i < json.layers.length; i++)
    +        {
    +            if (json.layers[i].type !== 'objectgroup')
    +            {
    +                continue;
    +            }
    +
    +            objects[json.layers[i].name] = [];
    +
    +            for (var v = 0, len = json.layers[i].objects.length; v < len; v++)
    +            {
    +                //  For now we'll just support object tiles
    +                if (json.layers[i].objects[v].gid)
    +                {
    +                    var object = {
    +
    +                        gid: json.layers[i].objects[v].gid,
    +                        name: json.layers[i].objects[v].name,
    +                        x: json.layers[i].objects[v].x,
    +                        y: json.layers[i].objects[v].y,
    +                        visible: json.layers[i].objects[v].visible,
    +                        properties: json.layers[i].objects[v].properties
    +
    +                    };
    +        
    +                    objects[json.layers[i].name].push(object);
    +                }
    +
    +            }
    +        }
    +
    +        map.objects = objects;
    +
    +        //  Tilesets
    +        var tilesets = [];
    +
    +        for (var i = 0; i < json.tilesets.length; i++)
    +        {
    +            //  name, firstgid, width, height, margin, spacing, properties
    +            var set = json.tilesets[i];
    +            var newSet = new Phaser.Tileset(set.name, set.firstgid, set.tilewidth, set.tileheight, set.margin, set.spacing, set.properties);
    +
    +            if (set.tileproperties)
    +            {
    +                newSet.tileProperties = set.tileproperties;
    +            }
    +
    +            newSet.rows = (set.imageheight - set.margin) / (set.tileheight + set.spacing);
    +            newSet.columns = (set.imagewidth - set.margin) / (set.tilewidth + set.spacing);
    +            newSet.total = newSet.rows * newSet.columns;
    +
    +            tilesets.push(newSet);
    +        }
    +
    +        map.tilesets = tilesets;
    +
    +        map.tiles = [];
    +
    +        //  Finally lets build our super tileset index
    +        for (var i = 0; i < map.tilesets.length; i++)
    +        {
    +            var set = map.tilesets[i];
    +    
    +            var x = set.tileMargin;
    +            var y = set.tileMargin;
    +
    +            var count = 0;
    +            var countX = 0;
    +            var countY = 0;
    +
    +            for (var t = set.firstgid; t < set.firstgid + set.total; t++)
    +            {
    +                //  Can add extra properties here as needed
    +                map.tiles[t] = [x, y, i];
    +
    +                x += set.tileWidth + set.tileSpacing;
    +
    +                count++;
    +
    +                if (count === set.total)
    +                {
    +                    break;
    +                }
    +
    +                countX++;
    +
    +                if (countX === set.columns)
    +                {
    +                    x = set.tileMargin;
    +                    y += set.tileHeight + set.tileSpacing;
    +
    +                    countX = 0;
    +                    countY++;
    +
    +                    if (countY === set.rows)
    +                    {
    +                        break;
    +                    }
    +                }
    +            }
    +
    +        }
    +
    +        return map;
     
         }
     
    @@ -649,13 +808,13 @@ Phaser.TilemapParser = {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Tileset.js.html b/docs/Tileset.js.html index faf94c4d..56d573a1 100644 --- a/docs/Tileset.js.html +++ b/docs/Tileset.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,97 +417,129 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
     /**
     * A Tile set is a combination of an image containing the tiles and collision data per tile.
    +* You should not normally instantiate this class directly.
     *
     * @class Phaser.Tileset
     * @constructor
    -* @param {Image} image - The Image object from the Cache.
    -* @param {string} key - The key of the tileset in the cache.
    -* @param {number} tileWidth - The width of the tile in pixels.
    -* @param {number} tileHeight - The height of the tile in pixels.
    -* @param {number} [tileMargin] - The margin around the tiles in the sheet.
    -* @param {number} [tileSpacing] - The spacing between the tiles in the sheet.
    +* @param {string} name - The name of the tileset in the map data.
    +* @param {number} firstgid - The Tiled firstgid value.
    +* @param {number} width - Width of each tile in pixels.
    +* @param {number} height - Height of each tile in pixels.
    +* @param {number} margin - The amount of margin around the tilesheet.
    +* @param {number} spacing - The amount of spacing between each tile in the sheet.
    +* @param {object} properties - Tileset properties.
     */
    -Phaser.Tileset = function (image, key, tileWidth, tileHeight, tileMargin, tileSpacing) {
    -
    -    if (typeof tileMargin === "undefined") { tileMargin = 0; }
    -    if (typeof tileSpacing === "undefined") { tileSpacing = 0; }
    +Phaser.Tileset = function (name, firstgid, width, height, margin, spacing, properties) {
     
         /**
    -    * @property {string} key - The cache ID.
    +    * @property {string} name - The name of the Tileset.
         */
    -    this.key = key;
    +    this.name = name;
     
         /**
    -    * @property {object} image - The image used for rendering.
    +    * @property {number} firstgid - The Tiled firstgid value.
    +    * @default
         */
    -    this.image = image;
    +    this.firstgid = firstgid;
     
         /**
         * @property {number} tileWidth - The width of a tile in pixels.
         */
    -    this.tileWidth = tileWidth;
    +    this.tileWidth = width;
     
         /**
         * @property {number} tileHeight - The height of a tile in pixels.
         */
    -    this.tileHeight = tileHeight;
    +    this.tileHeight = height;
     
         /**
         * @property {number} tileMargin - The margin around the tiles in the sheet.
         */
    -    this.margin = tileMargin;
    +    this.tileMargin = margin;
     
         /**
         * @property {number} tileSpacing - The margin around the tiles in the sheet.
         */
    -    this.spacing = tileSpacing;
    +    this.tileSpacing = spacing;
     
         /**
    -    * @property {array} tiles - An array of the tile collision data.
    +    * @property {object} properties - Tileset specific properties (typically defined in the Tiled editor).
         */
    -    this.tiles = [];
    +    this.properties = properties;
     
    -}
    +    /**
    +    * @property {object} tilePproperties - Tile specific properties (typically defined in the Tiled editor).
    +    */
    +    // this.tileProperties = {};
    +
    +    /**
    +    * @property {object} image - The image used for rendering. This is a reference to the image stored in Phaser.Cache.
    +    */
    +    this.image = null;
    +
    +    /**
    +    * @property {number} rows - The number of rows in the tile sheet.
    +    */
    +    this.rows = 0;
    +
    +    /**
    +    * @property {number} columns - The number of columns in the tile sheet.
    +    */
    +    this.columns = 0;
    +
    +    /**
    +    * @property {number} total - The total number of tiles in the tilesheet.
    +    */
    +    this.total = 0;
    +
    +};
     
     Phaser.Tileset.prototype = {
     
    -    /**
    -    * Adds a Tile into this set.
    -    *
    -    * @method Phaser.Tileset#addTile
    -    * @param {Phaser.Tile} tile - The tile to add to this set.
    -    */
    -    addTile: function (tile) {
    -
    -        this.tiles.push(tile);
    -
    -        return tile;
    -
    -    },
    -
         /**
         * Gets a Tile from this set.
         *
         * @method Phaser.Tileset#getTile
         * @param {number} index - The index of the tile within the set.
    -    * @return {Phaser.Tile} The tile.
    -    */
    +    * @return {object} The tile object.
         getTile: function (index) {
     
    -        if (this.tiles[index])
    -        {
    -            return this.tiles[index];
    -        }
    -
    -        return null;
    +        return this.tiles[index];
     
         },
    +    */
    +
    +    /**
    +    * Gets a Tile from this set.
    +    *
    +    * @method Phaser.Tileset#getTileX
    +    * @param {number} index - The index of the tile within the set.
    +    * @return {object} The tile object.
    +    getTileX: function (index) {
    +
    +        return this.tiles[index][0];
    +
    +    },
    +    */
    +
    +    /**
    +    * Gets a Tile from this set.
    +    *
    +    * @method Phaser.Tileset#getTileY
    +    * @param {number} index - The index of the tile within the set.
    +    * @return {object} The tile object.
    +    getTileY: function (index) {
    +
    +        return this.tiles[index][1];
    +
    +    },
    +    */
     
         /**
         * Sets tile spacing and margins.
    @@ -529,93 +555,22 @@ Phaser.Tileset.prototype = {
     
         },
     
    -    /**
    -    * Checks if the tile at the given index can collide.
    -    *
    -    * @method Phaser.Tileset#canCollide
    -    * @param {number} index - The index of the tile within the set.
    -    * @return {boolean} True or false depending on the tile collision or null if no tile was found at the given index.
    -    */
    -    canCollide: function (index) {
    -
    -        if (this.tiles[index])
    -        {
    -            return this.tiles[index].collideNone;
    -        }
    -
    -        return null;
    -
    -    },
    -
         /**
         * Checks if the tile at the given index exists.
         *
         * @method Phaser.Tileset#checkTileIndex
         * @param {number} index - The index of the tile within the set.
         * @return {boolean} True if a tile exists at the given index otherwise false.
    -    */
         checkTileIndex: function (index) {
     
             return (this.tiles[index]);
     
    -    },
    -
    -    /**
    -    * Sets collision values on a range of tiles in the set.
    -    *
    -    * @method Phaser.Tileset#setCollisionRange
    -    * @param {number} start - The index to start setting the collision data on.
    -    * @param {number} stop - The index to stop setting the collision data on.
    -    * @param {boolean} left - Should the tile collide on the left?
    -    * @param {boolean} right - Should the tile collide on the right?
    -    * @param {boolean} up - Should the tile collide on the top?
    -    * @param {boolean} down - Should the tile collide on the bottom?
    -    */
    -    setCollisionRange: function (start, stop, left, right, up, down) {
    -
    -        if (this.tiles[start] && this.tiles[stop] && start < stop)
    -        {
    -            for (var i = start; i <= stop; i++)
    -            {
    -                this.tiles[i].setCollision(left, right, up, down);
    -            }
    -        }
    -
    -    },
    -
    -    /**
    -    * Sets collision values on a tile in the set.
    -    *
    -    * @method Phaser.Tileset#setCollision
    -    * @param {number} index - The index of the tile within the set.
    -    * @param {boolean} left - Should the tile collide on the left?
    -    * @param {boolean} right - Should the tile collide on the right?
    -    * @param {boolean} up - Should the tile collide on the top?
    -    * @param {boolean} down - Should the tile collide on the bottom?
    -    */
    -    setCollision: function (index, left, right, up, down) {
    -
    -        if (this.tiles[index])
    -        {
    -            this.tiles[index].setCollision(left, right, up, down);
    -        }
    -
         }
    +    */
     
    -}
    +};
     
    -/**
    -* @name Phaser.Tileset#total
    -* @property {number} total - The total number of tiles in this Tileset.
    -* @readonly
    -*/
    -Object.defineProperty(Phaser.Tileset.prototype, "total", {
    -
    -    get: function () {
    -        return this.tiles.length;
    -    }
    -
    -});
    +Phaser.Tileset.prototype.constructor = Phaser.Tileset;
     
    @@ -631,13 +586,13 @@ Object.defineProperty(Phaser.Tileset.prototype, "total", { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Time.js.html b/docs/Time.js.html index 07640993..91ac8c29 100644 --- a/docs/Time.js.html +++ b/docs/Time.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -437,228 +431,338 @@
     */
     Phaser.Time = function (game) {
     
    -	/**
    -	* @property {Phaser.Game} game - Local reference to game.
    -	*/
    -	this.game = game;
    +    /**
    +    * @property {Phaser.Game} game - Local reference to game.
    +    */
    +    this.game = game;
     
    -	/**
    -	* @property {number} _started - The time at which the Game instance started.
    -	* @private
    -	*/
    -	this._started = 0;
    +    /**
    +    * @property {number} time - Game time counter. If you need a value for in-game calculation please use Phaser.Time.now instead.
    +    * @protected
    +    */
    +    this.time = 0;
     
    -	/**
    -	* @property {number} _timeLastSecond - The time (in ms) that the last second counter ticked over.
    -	* @private
    -	*/
    -	this._timeLastSecond = 0;
    +    /**
    +    * @property {number} now - The time right now.
    +    * @protected
    +    */
    +    this.now = 0;
     
    -	/**
    -	* @property {number} _pauseStarted - The time the game started being paused.
    -	* @private
    -	*/
    -	this._pauseStarted = 0;
    +    /**
    +    * @property {number} elapsed - Elapsed time since the last frame (in ms).
    +    * @protected
    +    */
    +    this.elapsed = 0;
     
    -	/**
    -	* @property {number} physicsElapsed - The elapsed time calculated for the physics motion updates.
    -	*/
    -	this.physicsElapsed = 0;
    +    /**
    +    * @property {number} pausedTime - Records how long the game has been paused for. Is reset each time the game pauses.
    +    * @protected
    +    */
    +    this.pausedTime = 0;
     
    -	/**
    -	* @property {number} time - Game time counter.
    -	*/
    -	this.time = 0;
    +    /**
    +    * @property {number} fps - Frames per second.
    +    * @protected
    +    */
    +    this.fps = 0;
     
    -	/**
    -	* @property {number} pausedTime - Records how long the game has been paused for. Is reset each time the game pauses.
    -	*/
    -	this.pausedTime = 0;
    +    /**
    +    * @property {number} fpsMin - The lowest rate the fps has dropped to.
    +    */
    +    this.fpsMin = 1000;
     
    -	/**
    -	* @property {number} now - The time right now.
    -	*/
    -	this.now = 0;
    +    /**
    +    * @property {number} fpsMax - The highest rate the fps has reached (usually no higher than 60fps).
    +    */
    +    this.fpsMax = 0;
     
    -	/**
    -	* @property {number} elapsed - Elapsed time since the last frame.
    -	*/
    -	this.elapsed = 0;
    +    /**
    +    * @property {number} msMin - The minimum amount of time the game has taken between two frames.
    +    * @default
    +    */
    +    this.msMin = 1000;
     
    -	/**
    -	* @property {number} fps - Frames per second.
    -	*/
    -	this.fps = 0;
    +    /**
    +    * @property {number} msMax - The maximum amount of time the game has taken between two frames.
    +    */
    +    this.msMax = 0;
     
    -	/**
    -	* @property {number} fpsMin - The lowest rate the fps has dropped to.
    -	*/
    -	this.fpsMin = 1000;
    +    /**
    +    * @property {number} physicsElapsed - The elapsed time calculated for the physics motion updates.
    +    */
    +    this.physicsElapsed = 0;
     
    -	/**
    -	* @property {number} fpsMax - The highest rate the fps has reached (usually no higher than 60fps).
    -	*/
    -	this.fpsMax = 0;
    +    /**
    +    * @property {number} frames - The number of frames record in the last second.
    +    */
    +    this.frames = 0;
     
    -	/**
    -	* @property {number} msMin - The minimum amount of time the game has taken between two frames.
    -	* @default
    -	*/
    -	this.msMin = 1000;
    +    /**
    +    * @property {number} pauseDuration - Records how long the game was paused for in miliseconds.
    +    */
    +    this.pauseDuration = 0;
     
    -	/**
    -	* @property {number} msMax - The maximum amount of time the game has taken between two frames.
    -	*/
    -	this.msMax = 0;
    +    /**
    +    * @property {number} timeToCall - The value that setTimeout needs to work out when to next update
    +    */
    +    this.timeToCall = 0;
     
    -	/**
    -	* @property {number} frames - The number of frames record in the last second.
    -	*/
    -	this.frames = 0;
    +    /**
    +    * @property {number} lastTime - Internal value used by timeToCall as part of the setTimeout loop
    +    */
    +    this.lastTime = 0;
     
    -	/**
    -	* @property {number} pauseDuration - Records how long the game was paused for in miliseconds.
    -	*/
    -	this.pauseDuration = 0;
    +    /**
    +    * @property {Phaser.Timer} events - This is a Phaser.Timer object bound to the master clock to which you can add timed events.
    +    */
    +    this.events = new Phaser.Timer(this.game, false);
     
    -	/**
    -	* @property {number} timeToCall - The value that setTimeout needs to work out when to next update
    -	*/
    -	this.timeToCall = 0;
    -
    -	/**
    -	* @property {number} lastTime - Internal value used by timeToCall as part of the setTimeout loop
    -	*/
    -	this.lastTime = 0;
    -
    -	//	Listen for game pause/resume events
    -	this.game.onPause.add(this.gamePaused, this);
    -	this.game.onResume.add(this.gameResumed, this);
    -
    -	/**
    -	* @property {boolean} _justResumed - Internal value used to recover from the game pause state.
    +    /**
    +    * @property {number} _started - The time at which the Game instance started.
         * @private
    -	*/
    -	this._justResumed = false;
    +    */
    +    this._started = 0;
    +
    +    /**
    +    * @property {number} _timeLastSecond - The time (in ms) that the last second counter ticked over.
    +    * @private
    +    */
    +    this._timeLastSecond = 0;
    +
    +    /**
    +    * @property {number} _pauseStarted - The time the game started being paused.
    +    * @private
    +    */
    +    this._pauseStarted = 0;
    +
    +    /**
    +    * @property {boolean} _justResumed - Internal value used to recover from the game pause state.
    +    * @private
    +    */
    +    this._justResumed = false;
    +
    +    /**
    +    * @property {array} _timers - Internal store of Phaser.Timer objects.
    +    * @private
    +    */
    +    this._timers = [];
    +
    +    /**
    +    * @property {number} _len - Temp. array length variable.
    +    * @private
    +    */
    +    this._len = 0;
    +
    +    /**
    +    * @property {number} _i - Temp. array counter variable.
    +    * @private
    +    */
    +    this._i = 0;
    +
    +    //  Listen for game pause/resume events
    +    this.game.onPause.add(this.gamePaused, this);
    +    this.game.onResume.add(this.gameResumed, this);
     
     };
     
     Phaser.Time.prototype = {
     
    -	/**
    -	* Updates the game clock and calculate the fps. This is called automatically by Phaser.Game.
    -	* @method Phaser.Time#update
    -	* @param {number} time - The current timestamp, either performance.now or Date.now depending on the browser.
    -	*/
    -	update: function (time) {
    +    /**
    +    * @method Phaser.Time#boot
    +    */
    +    boot: function () {
     
    -		this.now = time;
    +        this.events.start();
     
    -		if (this._justResumed)
    -		{
    -			this.time = this.now;
    -			this._justResumed = false;
    -		}
    +    },
     
    -		this.timeToCall = this.game.math.max(0, 16 - (time - this.lastTime));
    +    /**
    +    * Creates a new stand-alone Phaser.Timer object.
    +    * @method Phaser.Time#create
    +    * @param {boolean} [autoDestroy=true] - A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events).
    +    * @return {Phaser.Timer} The Timer object that was created.
    +    */
    +    create: function (autoDestroy) {
     
    -		this.elapsed = this.now - this.time;
    +        if (typeof autoDestroy === 'undefined') { autoDestroy = true; }
     
    -		this.msMin = this.game.math.min(this.msMin, this.elapsed);
    -		this.msMax = this.game.math.max(this.msMax, this.elapsed);
    +        var timer = new Phaser.Timer(this.game, autoDestroy);
     
    -		this.frames++;
    +        this._timers.push(timer);
     
    -		if (this.now > this._timeLastSecond + 1000)
    -		{
    -			this.fps = Math.round((this.frames * 1000) / (this.now - this._timeLastSecond));
    -			this.fpsMin = this.game.math.min(this.fpsMin, this.fps);
    -			this.fpsMax = this.game.math.max(this.fpsMax, this.fps);
    -			this._timeLastSecond = this.now;
    -			this.frames = 0;
    -		}
    +        return timer;
     
    -		this.time = this.now;
    +    },
    +
    +    /**
    +    * Remove all Timer objects, regardless of their state.
    +    * @method Phaser.Time#removeAll
    +    */
    +    removeAll: function () {
    +
    +        for (var i = 0; i < this._timers.length; i++)
    +        {
    +            this._timers[i].destroy();
    +        }
    +
    +        this._timers = [];
    +
    +    },
    +
    +    /**
    +    * Updates the game clock and calculate the fps. This is called automatically by Phaser.Game.
    +    * @method Phaser.Time#update
    +    * @param {number} time - The current timestamp, either performance.now or Date.now depending on the browser.
    +    */
    +    update: function (time) {
    +
    +        this.now = time;
    +
    +        if (this._justResumed)
    +        {
    +            this.time = this.now;
    +            this._justResumed = false;
    +    
    +            this.events.resume();
    +
    +            for (var i = 0; i < this._timers.length; i++)
    +            {
    +                this._timers[i].resume();
    +            }
    +        }
    +
    +        this.timeToCall = this.game.math.max(0, 16 - (time - this.lastTime));
    +
    +        this.elapsed = this.now - this.time;
    +
    +        this.msMin = this.game.math.min(this.msMin, this.elapsed);
    +        this.msMax = this.game.math.max(this.msMax, this.elapsed);
    +
    +        this.frames++;
    +
    +        if (this.now > this._timeLastSecond + 1000)
    +        {
    +            this.fps = Math.round((this.frames * 1000) / (this.now - this._timeLastSecond));
    +            this.fpsMin = this.game.math.min(this.fpsMin, this.fps);
    +            this.fpsMax = this.game.math.max(this.fpsMax, this.fps);
    +            this._timeLastSecond = this.now;
    +            this.frames = 0;
    +        }
    +
    +        this.time = this.now;
             this.lastTime = time + this.timeToCall;
    -		this.physicsElapsed = 1.0 * (this.elapsed / 1000);
    +        this.physicsElapsed = 1.0 * (this.elapsed / 1000);
     
    -		//	Clamp the delta
    -		if (this.physicsElapsed > 1)
    -		{
    -			this.physicsElapsed = 1;
    -		}
    +        //  Clamp the delta
    +        if (this.physicsElapsed > 0.05)
    +        {
    +            this.physicsElapsed = 0.05;
    +        }
     
    -		//  Paused?
    -		if (this.game.paused)
    -		{
    -			this.pausedTime = this.now - this._pauseStarted;
    -		}
    +        //  Paused?
    +        if (this.game.paused)
    +        {
    +            this.pausedTime = this.now - this._pauseStarted;
    +        }
    +        else
    +        {
    +            //  Our internal Phaser.Timer
    +            this.events.update(this.now);
     
    -	},
    +            //  Any game level timers
    +            this._i = 0;
    +            this._len = this._timers.length;
     
    -	/**
    -	* Called when the game enters a paused state.
    -	* @method Phaser.Time#gamePaused
    -	* @private
    -	*/
    -	gamePaused: function () {
    -		
    -		this._pauseStarted = this.now;
    +            while (this._i < this._len)
    +            {
    +                if (this._timers[this._i].update(this.now))
    +                {
    +                    this._i++;
    +                }
    +                else
    +                {
    +                    this._timers.splice(this._i, 1);
     
    -	},
    +                    this._len--;
    +                }
    +            }
    +        }
     
    -	/**
    -	* Called when the game resumes from a paused state.
    -	* @method Phaser.Time#gameResumed
    -	* @private
    -	*/
    -	gameResumed: function () {
    +    },
     
    -		//  Level out the elapsed timer to avoid spikes
    -		this.time = Date.now();
    -		this.pauseDuration = this.pausedTime;
    -		this._justResumed = true;
    +    /**
    +    * Called when the game enters a paused state.
    +    * @method Phaser.Time#gamePaused
    +    * @private
    +    */
    +    gamePaused: function () {
    +        
    +        this._pauseStarted = this.now;
     
    -	},
    +        this.events.pause();
     
    -	/**
    -	* The number of seconds that have elapsed since the game was started.
    -	* @method Phaser.Time#totalElapsedSeconds
    -	* @return {number}
    -	*/
    -	totalElapsedSeconds: function() {
    -		return (this.now - this._started) * 0.001;
    -	},
    +        for (var i = 0; i < this._timers.length; i++)
    +        {
    +            this._timers[i].pause();
    +        }
     
    -	/**
    -	* How long has passed since the given time.
    -	* @method Phaser.Time#elapsedSince
    -	* @param {number} since - The time you want to measure against.
    -	* @return {number} The difference between the given time and now.
    -	*/
    -	elapsedSince: function (since) {
    -		return this.now - since;
    -	},
    +    },
     
    -	/**
    -	* How long has passed since the given time (in seconds).
    -	* @method Phaser.Time#elapsedSecondsSince
    -	* @param {number} since - The time you want to measure (in seconds).
    -	* @return {number} Duration between given time and now (in seconds).
    -	*/
    -	elapsedSecondsSince: function (since) {
    -		return (this.now - since) * 0.001;
    -	},
    +    /**
    +    * Called when the game resumes from a paused state.
    +    * @method Phaser.Time#gameResumed
    +    * @private
    +    */
    +    gameResumed: function () {
     
    -	/**
    -	* Resets the private _started value to now.
    -	* @method Phaser.Time#reset
    -	*/
    -	reset: function () {
    -		this._started = this.now;
    -	}
    +        //  Level out the elapsed timer to avoid spikes
    +        this.time = Date.now();
    +        this.pauseDuration = this.pausedTime;
    +        this._justResumed = true;
     
    -};
    + }, + + /** + * The number of seconds that have elapsed since the game was started. + * @method Phaser.Time#totalElapsedSeconds + * @return {number} + */ + totalElapsedSeconds: function() { + return (this.now - this._started) * 0.001; + }, + + /** + * How long has passed since the given time. + * @method Phaser.Time#elapsedSince + * @param {number} since - The time you want to measure against. + * @return {number} The difference between the given time and now. + */ + elapsedSince: function (since) { + return this.now - since; + }, + + /** + * How long has passed since the given time (in seconds). + * @method Phaser.Time#elapsedSecondsSince + * @param {number} since - The time you want to measure (in seconds). + * @return {number} Duration between given time and now (in seconds). + */ + elapsedSecondsSince: function (since) { + return (this.now - since) * 0.001; + }, + + /** + * Resets the private _started value to now. + * @method Phaser.Time#reset + */ + reset: function () { + this._started = this.now; + } + +}; + +Phaser.Time.prototype.constructor = Phaser.Time; +
    @@ -673,13 +777,13 @@ Phaser.Time.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Timer.js.html b/docs/Timer.js.html index b61fefbe..fd8151d7 100644 --- a/docs/Timer.js.html +++ b/docs/Timer.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,19 +417,24 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
     /**
    -* Timer constructor.
    +* A Timer is a way to create small re-usable or disposable objects that do nothing but wait for a specific moment in time, and then dispatch an event.
    +* You can add as many events to a Timer as you like, each with their own delays. A Timer uses milliseconds as its unit of time. There are 1000 ms in 1 second.
    +* So if you want to fire an event every quarter of a second you'd need to set the delay to 250.
     *
     * @class Phaser.Timer
    -* @classdesc A Timer
    +* @classdesc A Timer is a way to create small re-usable or disposable objects that do nothing but wait for a specific moment in time, and then dispatch an event.
     * @constructor
     * @param {Phaser.Game} game A reference to the currently running game.
    +* @param {boolean} [autoDestroy=true] - A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events).
     */
    -Phaser.Timer = function (game) {
    +Phaser.Timer = function (game, autoDestroy) {
    +
    +    if (typeof autoDestroy === 'undefined') { autoDestroy = true; }
     
         /**
         * @property {Phaser.Game} game - Local reference to game.
    @@ -443,67 +442,208 @@ Phaser.Timer = function (game) {
         this.game = game;
     
         /**
    -    * The time at which this Timer instance started.
    -    * @property {number} _started
    +    * @property {boolean} running - True if the Timer is actively running. Do not switch this boolean, if you wish to pause the timer then use Timer.pause() instead.
    +    * @default
    +    */
    +    this.running = false;
    +
    +    /**
    +    * @property {boolean} autoDestroy - A Timer that is set to automatically destroy itself will do so after all of its events have been dispatched (assuming no looping events).
    +    */
    +    this.autoDestroy = autoDestroy;
    +
    +    /**
    +    * @property {boolean} expired - An expired Timer is one in which all of its events have been dispatched and none are pending.
    +    * @readonly
    +    * @default
    +    */
    +    this.expired = false;
    +
    +    /**
    +    * @property {array<Phaser.TimerEvent>} events - An array holding all of this timers Phaser.TimerEvent objects. Use the methods add, repeat and loop to populate it.
    +    */
    +    this.events = [];
    +
    +    /**
    +    * @property {Phaser.Signal} onComplete - This signal will be dispatched when this Timer has completed, meaning there are no more events in the queue.
    +    */
    +    this.onComplete = new Phaser.Signal();
    +
    +    /**
    +    * @property {number} nextTick - The time the next tick will occur.
    +    * @readonly
    +    * @protected
    +    */
    +    this.nextTick = 0;
    +
    +    /**
    +    * @property {boolean} paused - The paused state of the Timer. You can pause the timer by calling Timer.pause() and Timer.resume() or by the game pausing.
    +    * @readonly
    +    * @default
    +    */
    +    this.paused = false;
    +
    +    /**
    +    * @property {number} _started - The time at which this Timer instance started running.
         * @private
         * @default
         */
         this._started = 0;
     
         /**
    -    * The time (in ms) that the last second counter ticked over.
    -    * @property {number} _timeLastSecond
    +    * @property {number} _pauseStarted - The time the game started being paused.
         * @private
    -    * @default
         */
    -    this._timeLastSecond = 0;
    +    this._pauseStarted = 0;
     
    -    this.running = false;
    +    /**
    +    * @property {number} _now - The current start-time adjusted time.
    +    * @private
    +    */
    +    this._now = 0;
     
    -    this.events = [];
    +    /**
    +    * @property {number} _len - Temp. array length variable.
    +    * @private
    +    */
    +    this._len = 0;
     
    -    this.onEvent = new Phaser.Signal();
    +    /**
    +    * @property {number} _i - Temp. array counter variable.
    +    * @private
    +    */
    +    this._i = 0;
     
    -    //  Need to add custom FPS rate, for now we'll just use seconds
    +};
     
    -}
    +/**
    +* @constant
    +* @type {number}
    +*/
    +Phaser.Timer.MINUTE = 60000;
    +
    +/**
    +* @constant
    +* @type {number}
    +*/
    +Phaser.Timer.SECOND = 1000;
    +
    +/**
    +* @constant
    +* @type {number}
    +*/
    +Phaser.Timer.HALF = 500;
    +
    +/**
    +* @constant
    +* @type {number}
    +*/
    +Phaser.Timer.QUARTER = 250;
     
     Phaser.Timer.prototype = {
     
    -    //  delay could be from now, when the timer is created, or relative to an already running timer
    +    /**
    +    * Creates a new TimerEvent on this Timer. Use the methods add, repeat or loop instead of this.
    +    * @method Phaser.Timer#create
    +    * @private
    +    * @param {number} delay - The number of milliseconds that should elapse before the Timer will call the given callback.
    +    * @param {boolean} loop - Should the event loop or not?
    +    * @param {number} repeatCount - The number of times the event will repeat.
    +    * @param {function} callback - The callback that will be called when the Timer event occurs.
    +    * @param {object} callbackContext - The context in which the callback will be called.
    +    * @param {array} arguments - The values to be sent to your callback function when it is called.
    +    * @return {Phaser.TimerEvent} The Phaser.TimerEvent object that was created.
    +    */
    +    create: function (delay, loop, repeatCount, callback, callbackContext, args) {
     
    -    // add: function (delay, callback, callbackContext) {
    -    add: function (delay) {
    +        var tick = delay;
     
    -        this.events.push({
    -            delay: delay,
    -            dispatched: false,
    -            args: Array.prototype.splice.call(arguments, 1)
    -        });
    +        if (this.running)
    +        {
    +            tick += this._now;
    +        }
     
    -        // this.events.push({
    -        //  delay: delay,
    -        //  dispatched: false,
    -        //  callback: callback,
    -        //  callbackContext: callbackContext,
    -        //  args: Array.prototype.splice.call(arguments, 3)
    -        // });
    +        var event = new Phaser.TimerEvent(this, delay, tick, repeatCount, loop, callback, callbackContext, args);
    +
    +        this.events.push(event);
    +
    +        this.order();
    +
    +        this.expired = false;
    +
    +        return event;
     
         },
     
    +    /**
    +    * Adds a new Event to this Timer. The event will fire after the given amount of 'delay' in milliseconds has passed, once the Timer has started running.
    +    * Call Timer.start() once you have added all of the Events you require for this Timer. The delay is in relation to when the Timer starts, not the time it was added.
    +    * If the Timer is already running the delay will be calculated based on the timers current time.
    +    * @method Phaser.Timer#add
    +    * @param {number} delay - The number of milliseconds that should elapse before the Timer will call the given callback.
    +    * @param {function} callback - The callback that will be called when the Timer event occurs.
    +    * @param {object} callbackContext - The context in which the callback will be called.
    +    * @param {...*} arguments - The values to be sent to your callback function when it is called.
    +    * @return {Phaser.TimerEvent} The Phaser.TimerEvent object that was created.
    +    */
    +    add: function (delay, callback, callbackContext) {
    +
    +        return this.create(delay, false, 0, callback, callbackContext, Array.prototype.splice.call(arguments, 3));
    +
    +    },
    +
    +    /**
    +    * Adds a new Event to this Timer that will repeat for the given number of iterations.
    +    * The event will fire after the given amount of 'delay' milliseconds has passed once the Timer has started running.
    +    * Call Timer.start() once you have added all of the Events you require for this Timer. The delay is in relation to when the Timer starts, not the time it was added.
    +    * If the Timer is already running the delay will be calculated based on the timers current time.
    +    * @method Phaser.Timer#repeat
    +    * @param {number} delay - The number of milliseconds that should elapse before the Timer will call the given callback.
    +    * @param {number} repeatCount - The number of times the event will repeat.
    +    * @param {function} callback - The callback that will be called when the Timer event occurs.
    +    * @param {object} callbackContext - The context in which the callback will be called.
    +    * @param {...*} arguments - The values to be sent to your callback function when it is called.
    +    * @return {Phaser.TimerEvent} The Phaser.TimerEvent object that was created.
    +    */
    +    repeat: function (delay, repeatCount, callback, callbackContext) {
    +
    +        return this.create(delay, false, repeatCount, callback, callbackContext, Array.prototype.splice.call(arguments, 4));
    +
    +    },
    +
    +    /**
    +    * Adds a new looped Event to this Timer that will repeat forever or until the Timer is stopped.
    +    * The event will fire after the given amount of 'delay' milliseconds has passed once the Timer has started running.
    +    * Call Timer.start() once you have added all of the Events you require for this Timer. The delay is in relation to when the Timer starts, not the time it was added.
    +    * If the Timer is already running the delay will be calculated based on the timers current time.
    +    * @method Phaser.Timer#loop
    +    * @param {number} delay - The number of milliseconds that should elapse before the Timer will call the given callback.
    +    * @param {function} callback - The callback that will be called when the Timer event occurs.
    +    * @param {object} callbackContext - The context in which the callback will be called.
    +    * @param {...*} arguments - The values to be sent to your callback function when it is called.
    +    * @return {Phaser.TimerEvent} The Phaser.TimerEvent object that was created.
    +    */
    +    loop: function (delay, callback, callbackContext) {
    +
    +        return this.create(delay, true, 0, callback, callbackContext, Array.prototype.splice.call(arguments, 3));
    +
    +    },
    +
    +    /**
    +    * Starts this Timer running.
    +    * @method Phaser.Timer#start
    +    */
         start: function() {
     
             this._started = this.game.time.now;
             this.running = true;
     
    -        //  sort the events based on delay here, also don't run unless events is populated
    -        //  add ability to auto-stop once all events are done
    -        //  add support for maximum duration
    -        //  add support for delay before starting
    -        //  add signals?
    -
         },
     
    +    /**
    +    * Stops this Timer from running. Does not cause it to be destroyed if autoDestroy is set to true.
    +    * @method Phaser.Timer#stop
    +    */
         stop: function() {
     
             this.running = false;
    @@ -511,33 +651,258 @@ Phaser.Timer.prototype = {
     
         },
     
    -    update: function() {
    +    /**
    +    * Removes a pending TimerEvent from the queue.
    +    * @param {Phaser.TimerEvent} event - The event to remove from the queue.
    +    * @method Phaser.Timer#remove
    +    */
    +    remove: function(event) {
     
    -        //  TODO: Game Paused support
    -
    -        if (this.running)
    +        for (var i = 0; i < this.events.length; i++)
             {
    -            var seconds = this.seconds();
    -
    -            for (var i = 0, len = this.events.length; i < len; i++)
    +            if (this.events[i] === event)
                 {
    -                if (this.events[i].dispatched === false && seconds >= this.events[i].delay)
    -                {
    -                    this.events[i].dispatched = true;
    -                    // this.events[i].callback.apply(this.events[i].callbackContext, this.events[i].args);
    -                    this.onEvent.dispatch.apply(this, this.events[i].args);
    -                    //  ought to slice it now
    -                }
    +                this.events.splice(i, 1);
    +                return true;
                 }
             }
     
    +        return false;
    +
    +    },
    +
    +    /**
    +    * Orders the events on this Timer so they are in tick order. This is called automatically when new events are created.
    +    * @method Phaser.Timer#order
    +    */
    +    order: function () {
    +
    +        if (this.events.length > 0)
    +        {
    +            //  Sort the events so the one with the lowest tick is first
    +            this.events.sort(this.sortHandler);
    +
    +            this.nextTick = this.events[0].tick;
    +        }
    +
         },
     
    -    seconds: function() {
    -        return (this.game.time.now - this._started) * 0.001;
    +    /**
    +    * Sort handler used by Phaser.Timer.order.
    +    * @method Phaser.Timer#sortHandler
    +    * @protected
    +    */
    +    sortHandler: function (a, b) {
    +
    +        if (a.tick < b.tick)
    +        {
    +            return -1;
    +        }
    +        else if (a.tick > b.tick)
    +        {
    +            return 1;
    +        }
    +
    +        return 0;
    +
    +    },
    +
    +    /**
    +    * The main Timer update event, called automatically by the Game clock.
    +    * @method Phaser.Timer#update
    +    * @protected
    +    * @param {number} time - The time from the core game clock.
    +    * @return {boolean} True if there are still events waiting to be dispatched, otherwise false if this Timer can be destroyed.
    +    */
    +    update: function(time) {
    +
    +        if (this.paused)
    +        {
    +            return true;
    +        }
    +
    +        this._now = time - this._started;
    +
    +        this._len = this.events.length;
    +
    +        if (this.running && this._now >= this.nextTick && this._len > 0)
    +        {
    +            this._i = 0;
    +
    +            while (this._i < this._len)
    +            {
    +                if (this._now >= this.events[this._i].tick)
    +                {
    +                    if (this.events[this._i].loop === true)
    +                    {
    +                        this.events[this._i].tick += this.events[this._i].delay - (this._now - this.events[this._i].tick);
    +                        this.events[this._i].callback.apply(this.events[this._i].callbackContext, this.events[this._i].args);
    +                    }
    +                    else if (this.events[this._i].repeatCount > 0)
    +                    {
    +                        this.events[this._i].repeatCount--;
    +                        this.events[this._i].tick += this.events[this._i].delay - (this._now - this.events[this._i].tick);
    +                        this.events[this._i].callback.apply(this.events[this._i].callbackContext, this.events[this._i].args);
    +                    }
    +                    else
    +                    {
    +                        this.events[this._i].callback.apply(this.events[this._i].callbackContext, this.events[this._i].args);
    +                        this.events.splice(this._i, 1);
    +                        this._len--;
    +                    }
    +
    +                    this._i++;
    +                }
    +                else
    +                {
    +                    break;
    +                }
    +            }
    +
    +            //  Are there any events left?
    +            if (this.events.length > 0)
    +            {
    +                this.order();
    +            }
    +            else
    +            {
    +                this.expired = true;
    +                this.onComplete.dispatch(this);
    +            }
    +        }
    +
    +        if (this.expired && this.autoDestroy)
    +        {
    +            return false;
    +        }
    +        else
    +        {
    +            return true;
    +        }
    +
    +    },
    +
    +    /**
    +    * Pauses the Timer and all events in the queue.
    +    * @method Phaser.Timer#pause
    +    */
    +    pause: function () {
    +        
    +        this._pauseStarted = this.game.time.now;
    +
    +        this.paused = true;
    +
    +    },
    +
    +    /**
    +    * Resumes the Timer and updates all pending events.
    +    * @method Phaser.Timer#resume
    +    */
    +    resume: function () {
    +
    +        var pauseDuration = this.game.time.now - this._pauseStarted;
    +
    +        for (var i = 0; i < this.events.length; i++)
    +        {
    +            this.events[i].tick += pauseDuration;
    +        }
    +
    +        this.nextTick += pauseDuration;
    +
    +        this.paused = false;
    +
    +    },
    +
    +    /**
    +    * Destroys this Timer. Events are not dispatched.
    +    * @method Phaser.Timer#destroy
    +    */
    +    destroy: function() {
    +
    +        this.onComplete.removeAll();
    +        this.running = false;
    +        this.events = [];
    +
         }
     
    -}
    +}; + +/** +* @name Phaser.Timer#next +* @property {number} next - The time at which the next event will occur. +* @readonly +*/ +Object.defineProperty(Phaser.Timer.prototype, "next", { + + get: function () { + return this.nextTick; + } + +}); + +/** +* @name Phaser.Timer#duration +* @property {number} duration - The duration in ms remaining until the next event will occur. +* @readonly +*/ +Object.defineProperty(Phaser.Timer.prototype, "duration", { + + get: function () { + + if (this.running && this.nextTick > this._now) + { + return this.nextTick - this._now; + } + else + { + return 0; + } + + } + +}); + +/** +* @name Phaser.Timer#length +* @property {number} length - The number of pending events in the queue. +* @readonly +*/ +Object.defineProperty(Phaser.Timer.prototype, "length", { + + get: function () { + return this.events.length; + } + +}); + +/** +* @name Phaser.Timer#ms +* @property {number} ms - The duration in milliseconds that this Timer has been running for. +* @readonly +*/ +Object.defineProperty(Phaser.Timer.prototype, "ms", { + + get: function () { + return this._now; + } + +}); + +/** +* @name Phaser.Timer#seconds +* @property {number} seconds - The duration in seconds that this Timer has been running for. +* @readonly +*/ +Object.defineProperty(Phaser.Timer.prototype, "seconds", { + + get: function () { + return this._now * 0.001; + } + +}); + +Phaser.Timer.prototype.constructor = Phaser.Timer; +
    @@ -552,13 +917,13 @@ Phaser.Timer.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/TimerEvent.js.html b/docs/TimerEvent.js.html new file mode 100644 index 00000000..d0a9f1e5 --- /dev/null +++ b/docs/TimerEvent.js.html @@ -0,0 +1,546 @@ + + + + + + Phaser Source: time/TimerEvent.js + + + + + + + + + + +
    + + +
    + + +
    + +
    + + + +

    Source: time/TimerEvent.js

    + +
    +
    +
    /**
    +* @author       Richard Davey <rich@photonstorm.com>
    +* @copyright    2014 Photon Storm Ltd.
    +* @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
    +*/
    +
    +/**
    +* A TimerEvent is a single event that is processed by a Phaser.Timer. It consists of a delay, which is a value in milliseconds after which the event will fire.
    +* It can call a specific callback, passing in optional parameters.
    +*
    +* @class Phaser.TimerEvent
    +* @classdesc A TimerEvent is a single event that is processed by a Phaser.Timer. It consists of a delay, which is a value in milliseconds after which the event will fire.
    +* @constructor
    +* @param {Phaser.Timer} timer - The Timer object that this TimerEvent belongs to.
    +* @param {number} delay - The delay in ms at which this TimerEvent fires.
    +* @param {number} tick - The tick is the next game clock time that this event will fire at.
    +* @param {number} repeatCount - If this TimerEvent repeats it will do so this many times.
    +* @param {boolean} loop - True if this TimerEvent loops, otherwise false.
    +* @param {function} callback - The callback that will be called when the TimerEvent occurs.
    +* @param {object} callbackContext - The context in which the callback will be called.
    +* @param {array} arguments - The values to be passed to the callback.
    +*/
    +Phaser.TimerEvent = function (timer, delay, tick, repeatCount, loop, callback, callbackContext, args) {
    +
    +    /**
    +    * @property {Phaser.Timer} timer - The Timer object that this TimerEvent belongs to.
    +    */
    +	this.timer = timer;
    +
    +    /**
    +    * @property {number} delay - The delay in ms at which this TimerEvent fires.
    +    */
    +	this.delay = delay;
    +
    +    /**
    +    * @property {number} tick - The tick is the next game clock time that this event will fire at.
    +    */
    +	this.tick = tick;
    +
    +    /**
    +    * @property {number} repeatCount - If this TimerEvent repeats it will do so this many times.
    +    */
    +	this.repeatCount = repeatCount - 1;
    +
    +    /**
    +    * @property {boolean} loop - True if this TimerEvent loops, otherwise false.
    +    */
    +	this.loop = loop;
    +
    +    /**
    +    * @property {function} callback - The callback that will be called when the TimerEvent occurs.
    +    */
    +	this.callback = callback;
    +
    +    /**
    +    * @property {object} callbackContext - The context in which the callback will be called.
    +    */
    +	this.callbackContext = callbackContext;
    +
    +    /**
    +    * @property {array} arguments - The values to be passed to the callback.
    +    */
    +	this.args = args;
    +
    +};
    +
    +Phaser.TimerEvent.prototype.constructor = Phaser.TimerEvent;
    +
    +
    +
    + + + + + +
    + +
    +
    + + + + Phaser Copyright © 2012-2014 Photon Storm Ltd. + +
    + + + Documentation generated by JSDoc 3.3.0-dev + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. + +
    +
    + + +
    +
    + +
    + + + + + + + + + + + + + + + + + + + + diff --git a/docs/Touch.js.html b/docs/Touch.js.html index a03f5f91..3c6bfc6b 100644 --- a/docs/Touch.js.html +++ b/docs/Touch.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -490,7 +484,8 @@ Phaser.Touch = function (game) {
         this.preventDefault = true;
     
         /**
    -    * @property {TouchEvent} event - The browser touch event.
    +    * @property {TouchEvent} event - The browser touch DOM event. Will be set to null if no touch event has ever been received.
    +    * @default
         */
         this.event = null;
     
    @@ -691,13 +686,6 @@ Phaser.Touch.prototype = {
                 event.preventDefault();
             }
     
    -        /*
    -        for (var i = 0; i < event.changedTouches.length; i++)
    -        {
    -            //console.log('touch enter');
    -        }
    -       */
    -
         },
     
         /**
    @@ -720,13 +708,6 @@ Phaser.Touch.prototype = {
                 event.preventDefault();
             }
     
    -        /*
    -        for (var i = 0; i < event.changedTouches.length; i++)
    -        {
    -            //console.log('touch leave');
    -        }
    -       */
    -
         },
     
         /**
    @@ -802,7 +783,10 @@ Phaser.Touch.prototype = {
     
         }
     
    -};
    +}; + +Phaser.Touch.prototype.constructor = Phaser.Touch; +
    @@ -817,13 +801,13 @@ Phaser.Touch.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Tween.js.html b/docs/Tween.js.html index 352a9b05..9b4e0de5 100644 --- a/docs/Tween.js.html +++ b/docs/Tween.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -451,119 +445,112 @@ Phaser.Tween = function (object, game) {
         this.game = game;
     
         /**
    -    * @property {object} _manager - Description.
    +    * @property {Phaser.TweenManager} _manager - Reference to the TweenManager.
         * @private
         */
         this._manager = this.game.tweens;
     
         /**
    -    * @property {object} _valuesStart - Description.
    +    * @property {object} _valuesStart - Private value object.
         * @private
         */
         this._valuesStart = {};
     
         /**
    -    * @property {object} _valuesEnd - Description.
    +    * @property {object} _valuesEnd - Private value object.
         * @private
         */
         this._valuesEnd = {};
     
         /**
    -    * @property {object} _valuesStartRepeat - Description.
    +    * @property {object} _valuesStartRepeat - Private value object.
         * @private
         */
         this._valuesStartRepeat = {};
     
         /**
    -    * @property {number} _duration - Description.
    +    * @property {number} _duration - Private duration counter.
         * @private
         * @default
         */
         this._duration = 1000;
     
         /**
    -    * @property {number} _repeat - Description.
    +    * @property {number} _repeat - Private repeat counter.
         * @private
         * @default
         */
         this._repeat = 0;
     
         /**
    -    * @property {boolean} _yoyo - Description.
    +    * @property {boolean} _yoyo - Private yoyo flag.
         * @private
         * @default
         */
         this._yoyo = false;
     
         /**
    -    * @property {boolean} _reversed - Description.
    +    * @property {boolean} _reversed - Private reversed flag.
         * @private
         * @default
         */
         this._reversed = false;
     
         /**
    -    * @property {number} _delayTime - Description.
    +    * @property {number} _delayTime - Private delay counter.
         * @private
         * @default
         */
         this._delayTime = 0;
     
         /**
    -    * @property {Description} _startTime - Description.
    +    * @property {number} _startTime - Private start time counter.
         * @private
         * @default null
         */
         this._startTime = null;
     
         /**
    -    * @property {Description} _easingFunction - Description.
    +    * @property {function} _easingFunction - The easing function used for the tween.
         * @private
         */
         this._easingFunction = Phaser.Easing.Linear.None;
     
         /**
    -    * @property {Description} _interpolationFunction - Description.
    +    * @property {function} _interpolationFunction - The interpolation function used for the tween.
         * @private
         */
         this._interpolationFunction = Phaser.Math.linearInterpolation;
     
         /**
    -    * @property {Description} _chainedTweens - Description.
    +    * @property {array} _chainedTweens - A private array of chained tweens.
         * @private
         */
         this._chainedTweens = [];
     
         /**
    -    * @property {Description} _onStartCallback - Description.
    -    * @private
    -    * @default
    -    */
    -    this._onStartCallback = null;
    -
    -    /**
    -    * @property {boolean} _onStartCallbackFired - Description.
    +    * @property {boolean} _onStartCallbackFired - Private flag.
         * @private
         * @default
         */
         this._onStartCallbackFired = false;
     
         /**
    -    * @property {Description} _onUpdateCallback - Description.
    +    * @property {function} _onUpdateCallback - An onUpdate callback.
         * @private
         * @default null
         */
         this._onUpdateCallback = null;
    -
    +   
         /**
    -    * @property {Description} _onCompleteCallback - Description.
    +    * @property {object} _onUpdateCallbackContext - The context in which to call the onUpdate callback.
         * @private
         * @default null
         */
    -    this._onCompleteCallback = null;
    -    
    +    this._onUpdateCallbackContext = null;
    +
         /**
    -    * @property {number} _pausedTime - Description.
    +    * @property {number} _pausedTime - Private pause timer.
         * @private
         * @default
         */
    @@ -576,22 +563,28 @@ Phaser.Tween = function (object, game) {
         this.pendingDelete = false;
     
         // Set all starting values present on the target object
    -    for ( var field in object ) {
    -        this._valuesStart[ field ] = parseFloat(object[field], 10);
    +    for (var field in object)
    +    {
    +        this._valuesStart[field] = parseFloat(object[field], 10);
         }
         
         /**
    -    * @property {Phaser.Signal} onStart - Description.
    +    * @property {Phaser.Signal} onStart - The onStart event is fired when the Tween begins.
         */
         this.onStart = new Phaser.Signal();
     
         /**
    -    * @property {Phaser.Signal} onComplete - Description.
    +    * @property {Phaser.Signal} onLoop - The onLoop event is fired if the Tween loops.
    +    */
    +    this.onLoop = new Phaser.Signal();
    +
    +    /**
    +    * @property {Phaser.Signal} onComplete - The onComplete event is fired when the Tween completes. Does not fire if the Tween is set to loop.
         */
         this.onComplete = new Phaser.Signal();
     
         /**
    -    * @property {boolean} isRunning - Description.
    +    * @property {boolean} isRunning - If the tween is running this is set to true, otherwise false. Tweens that are in a delayed state, waiting to start, are considered as being running.
         * @default
         */
         this.isRunning = false;
    @@ -605,15 +598,15 @@ Phaser.Tween.prototype = {
         *
         * @method Phaser.Tween#to
         * @param {object} properties - Properties you want to tween.
    -    * @param {number} duration - Duration of this tween.
    -    * @param {function} ease - Easing function.
    -    * @param {boolean} autoStart - Whether this tween will start automatically or not.
    -    * @param {number} delay - Delay before this tween will start, defaults to 0 (no delay).
    -    * @param {boolean} repeat - Should the tween automatically restart once complete? (ignores any chained tweens).
    -    * @param {Phaser.Tween} yoyo - Description.
    -    * @return {Phaser.Tween} Itself.
    +    * @param {number} [duration=1000] - Duration of this tween in ms.
    +    * @param {function} [ease=null] - Easing function. If not set it will default to Phaser.Easing.Linear.None.
    +    * @param {boolean} [autoStart=false] - Whether this tween will start automatically or not.
    +    * @param {number} [delay=0] - Delay before this tween will start, defaults to 0 (no delay). Value given is in ms.
    +    * @param {boolean} [repeat=0] - Should the tween automatically restart once complete? (ignores any chained tweens).
    +    * @param {boolean} [yoyo=false] - A tween that yoyos will reverse itself when it completes.
    +    * @return {Phaser.Tween} This Tween object.
         */
    -    to: function ( properties, duration, ease, autoStart, delay, repeat, yoyo ) {
    +    to: function (properties, duration, ease, autoStart, delay, repeat, yoyo) {
     
             duration = duration || 1000;
             ease = ease || null;
    @@ -623,6 +616,7 @@ Phaser.Tween.prototype = {
             yoyo = yoyo || false;
     
             var self;
    +
             if (this._parent)
             {
                 self = this._manager.create(this._object);
    @@ -652,9 +646,12 @@ Phaser.Tween.prototype = {
     
             self._yoyo = yoyo;
     
    -        if (autoStart) {
    +        if (autoStart)
    +        {
                 return this.start();
    -        } else {
    +        }
    +        else
    +        {
                 return this;
             }
     
    @@ -668,43 +665,41 @@ Phaser.Tween.prototype = {
         */
         start: function () {
     
    -        if (this.game === null || this._object === null) {
    +        if (this.game === null || this._object === null)
    +        {
                 return;
             }
     
             this._manager.add(this);
     
    -        this.onStart.dispatch(this._object);
    -
             this.isRunning = true;
     
             this._onStartCallbackFired = false;
     
             this._startTime = this.game.time.now + this._delayTime;
     
    -        for ( var property in this._valuesEnd ) {
    -
    +        for (var property in this._valuesEnd)
    +        {
                 // check if an Array was provided as property value
    -            if ( this._valuesEnd[ property ] instanceof Array ) {
    -
    -                if ( this._valuesEnd[ property ].length === 0 ) {
    -
    +            if (this._valuesEnd[property] instanceof Array)
    +            {
    +                if (this._valuesEnd[property].length === 0)
    +                {
                         continue;
    -
                     }
     
                     // create a local copy of the Array with the start value at the front
    -                this._valuesEnd[ property ] = [ this._object[ property ] ].concat( this._valuesEnd[ property ] );
    -
    +                this._valuesEnd[property] = [this._object[property]].concat(this._valuesEnd[property]);
                 }
     
    -            this._valuesStart[ property ] = this._object[ property ];
    +            this._valuesStart[property] = this._object[property];
     
    -            if ( ( this._valuesStart[ property ] instanceof Array ) === false ) {
    -                this._valuesStart[ property ] *= 1.0; // Ensures we're using numbers, not strings
    +            if ((this._valuesStart[property] instanceof Array) === false)
    +            {
    +                this._valuesStart[property] *= 1.0; // Ensures we're using numbers, not strings
                 }
     
    -            this._valuesStartRepeat[ property ] = this._valuesStart[ property ] || 0;
    +            this._valuesStartRepeat[property] = this._valuesStart[property] || 0;
     
             }
     
    @@ -722,6 +717,8 @@ Phaser.Tween.prototype = {
     
             this.isRunning = false;
     
    +        this._onUpdateCallback = null;
    +
             this._manager.remove(this);
     
             return this;
    @@ -735,7 +732,7 @@ Phaser.Tween.prototype = {
         * @param {number} amount - The amount of the delay in ms.
         * @return {Phaser.Tween} Itself.
         */
    -    delay: function ( amount ) {
    +    delay: function (amount) {
     
             this._delayTime = amount;
             return this;
    @@ -749,7 +746,7 @@ Phaser.Tween.prototype = {
         * @param {number} times - How many times to repeat.
         * @return {Phaser.Tween} Itself.
         */
    -    repeat: function ( times ) {
    +    repeat: function (times) {
     
             this._repeat = times;
             return this;
    @@ -764,7 +761,7 @@ Phaser.Tween.prototype = {
         * @param {boolean} yoyo - Set to true to yoyo this tween.
         * @return {Phaser.Tween} Itself.
         */
    -    yoyo: function( yoyo ) {
    +    yoyo: function(yoyo) {
     
             this._yoyo = yoyo;
             return this;
    @@ -778,7 +775,7 @@ Phaser.Tween.prototype = {
         * @param {function} easing - The easing function this tween will use, i.e. Phaser.Easing.Linear.None.
         * @return {Phaser.Tween} Itself.
         */
    -    easing: function ( easing ) {
    +    easing: function (easing) {
     
             this._easingFunction = easing;
             return this;
    @@ -787,12 +784,13 @@ Phaser.Tween.prototype = {
     
         /**
         * Set interpolation function the tween will use, by default it uses Phaser.Math.linearInterpolation.
    +    * Also available: Phaser.Math.bezierInterpolation and Phaser.Math.catmullRomInterpolation.
         *
         * @method Phaser.Tween#interpolation
         * @param {function} interpolation - The interpolation function to use (Phaser.Math.linearInterpolation by default)
         * @return {Phaser.Tween} Itself.
         */
    -    interpolation: function ( interpolation ) {
    +    interpolation: function (interpolation) {
     
             this._interpolationFunction = interpolation;
             return this;
    @@ -832,20 +830,6 @@ Phaser.Tween.prototype = {
     
         },
     
    -    /**
    -    * Sets a callback to be fired when the tween starts. Note: callback will be called in the context of the global scope.
    -    *
    -    * @method Phaser.Tween#onStartCallback
    -    * @param {function} callback - The callback to invoke on start.
    -    * @return {Phaser.Tween} Itself.
    -    */
    -    onStartCallback: function ( callback ) {
    -
    -        this._onStartCallback = callback;
    -        return this;
    -
    -    },
    -
         /**
         * Sets a callback to be fired each time this tween updates. Note: callback will be called in the context of the global scope.
         *
    @@ -853,23 +837,11 @@ Phaser.Tween.prototype = {
         * @param {function} callback - The callback to invoke each time this tween is updated.
         * @return {Phaser.Tween} Itself.
         */
    -    onUpdateCallback: function ( callback ) {
    +    onUpdateCallback: function (callback, callbackContext) {
     
             this._onUpdateCallback = callback;
    -        return this;
    +        this._onUpdateCallbackContext = callbackContext;
     
    -    },
    -
    -    /**
    -    * Sets a callback to be fired when the tween completes. Note: callback will be called in the context of the global scope.
    -    *
    -    * @method Phaser.Tween#onCompleteCallback
    -    * @param {function} callback - The callback to invoke on completion.
    -    * @return {Phaser.Tween} Itself.
    -    */
    -    onCompleteCallback: function ( callback ) {
    -
    -        this._onCompleteCallback = callback;
             return this;
     
         },
    @@ -880,8 +852,10 @@ Phaser.Tween.prototype = {
         * @method Phaser.Tween#pause
         */
         pause: function () {
    +
             this._paused = true;
             this._pausedTime = this.game.time.now;
    +
         },
     
         /**
    @@ -890,8 +864,10 @@ Phaser.Tween.prototype = {
         * @method Phaser.Tween#resume
         */
         resume: function () {
    +
             this._paused = false;
             this._startTime += (this.game.time.now - this._pausedTime);
    +
         },
     
         /**
    @@ -901,127 +877,112 @@ Phaser.Tween.prototype = {
         * @param {number} time - A timestamp passed in by the TweenManager.
         * @return {boolean} false if the tween has completed and should be deleted from the manager, otherwise true (still active).
         */
    -    update: function ( time ) {
    +    update: function (time) {
     
             if (this.pendingDelete)
             {
                 return false;
             }
     
    -        if (this._paused || time < this._startTime) {
    -
    +        if (this._paused || time < this._startTime)
    +        {
                 return true;
    -
             }
     
             var property;
     
    -        if ( time < this._startTime ) {
    -
    +        if (time < this._startTime)
    +        {
                 return true;
    -
             }
     
    -        if ( this._onStartCallbackFired === false ) {
    -
    -            if ( this._onStartCallback !== null ) {
    -
    -                this._onStartCallback.call( this._object );
    -
    -            }
    -
    +        if (this._onStartCallbackFired === false)
    +        {
    +            this.onStart.dispatch(this._object);
                 this._onStartCallbackFired = true;
    -
             }
     
    -        var elapsed = ( time - this._startTime ) / this._duration;
    +        var elapsed = (time - this._startTime) / this._duration;
             elapsed = elapsed > 1 ? 1 : elapsed;
     
    -        var value = this._easingFunction( elapsed );
    +        var value = this._easingFunction(elapsed);
     
    -        for ( property in this._valuesEnd ) {
    -
    -            var start = this._valuesStart[ property ] || 0;
    -            var end = this._valuesEnd[ property ];
    -
    -            if ( end instanceof Array ) {
    -
    -                this._object[ property ] = this._interpolationFunction( end, value );
    -
    -            } else {
    +        for (property in this._valuesEnd)
    +        {
    +            var start = this._valuesStart[property] || 0;
    +            var end = this._valuesEnd[property];
     
    +            if (end instanceof Array)
    +            {
    +                this._object[property] = this._interpolationFunction(end, value);
    +            }
    +            else
    +            {
                     // Parses relative end values with start as base (e.g.: +10, -3)
    -                if ( typeof(end) === "string" ) {
    +                if (typeof(end) === 'string')
    +                {
                         end = start + parseFloat(end, 10);
                     }
     
                     // protect against non numeric properties.
    -                if ( typeof(end) === "number" ) {
    -                    this._object[ property ] = start + ( end - start ) * value;
    +                if (typeof(end) === 'number')
    +                {
    +                    this._object[property] = start + ( end - start ) * value;
                     }
    -
                 }
    -
             }
     
    -        if ( this._onUpdateCallback !== null ) {
    -
    -            this._onUpdateCallback.call( this._object, value );
    -
    +        if (this._onUpdateCallback !== null)
    +        {
    +            this._onUpdateCallback.call(this._onUpdateCallbackContext, this, value);
             }
     
    -        if ( elapsed == 1 ) {
    -
    -            if ( this._repeat > 0 ) {
    -
    -                if ( isFinite( this._repeat ) ) {
    +        if (elapsed == 1)
    +        {
    +            if (this._repeat > 0)
    +            {
    +                if (isFinite(this._repeat))
    +                {
                         this._repeat--;
                     }
     
                     // reassign starting values, restart by making startTime = now
    -                for ( property in this._valuesStartRepeat ) {
    -
    -                    if ( typeof( this._valuesEnd[ property ] ) === "string" ) {
    -                        this._valuesStartRepeat[ property ] = this._valuesStartRepeat[ property ] + parseFloat(this._valuesEnd[ property ], 10);
    +                for (property in this._valuesStartRepeat)
    +                {
    +                    if (typeof(this._valuesEnd[property]) === 'string')
    +                    {
    +                        this._valuesStartRepeat[property] = this._valuesStartRepeat[property] + parseFloat(this._valuesEnd[property], 10);
                         }
     
    -                    if (this._yoyo) {
    -                        var tmp = this._valuesStartRepeat[ property ];
    -                        this._valuesStartRepeat[ property ] = this._valuesEnd[ property ];
    -                        this._valuesEnd[ property ] = tmp;
    +                    if (this._yoyo)
    +                    {
    +                        var tmp = this._valuesStartRepeat[property];
    +                        this._valuesStartRepeat[property] = this._valuesEnd[property];
    +                        this._valuesEnd[property] = tmp;
                             this._reversed = !this._reversed;
                         }
    -                    this._valuesStart[ property ] = this._valuesStartRepeat[ property ];
     
    +                    this._valuesStart[property] = this._valuesStartRepeat[property];
                     }
     
                     this._startTime = time + this._delayTime;
     
    -                this.onComplete.dispatch(this._object);
    -
    -                if ( this._onCompleteCallback !== null ) {
    -                    this._onCompleteCallback.call( this._object );
    -                }
    +                this.onLoop.dispatch(this._object);
     
                     return true;
     
    -            } else {
    -
    +            }
    +            else
    +            {
                     this.isRunning = false;
                     this.onComplete.dispatch(this._object);
     
    -                if ( this._onCompleteCallback !== null ) {
    -                    this._onCompleteCallback.call( this._object );
    -                }
    -
    -                for ( var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i ++ ) {
    -
    -                    this._chainedTweens[ i ].start( time );
    -
    +                for (var i = 0, numChainedTweens = this._chainedTweens.length; i < numChainedTweens; i ++)
    +                {
    +                    this._chainedTweens[i].start(time);
                     }
     
                     return false;
    -
                 }
     
             }
    @@ -1031,6 +992,8 @@ Phaser.Tween.prototype = {
         }
         
     };
    +
    +Phaser.Tween.prototype.constructor = Phaser.Tween;
     
    @@ -1046,13 +1009,13 @@ Phaser.Tween.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/TweenManager.js.html b/docs/TweenManager.js.html index b705ba69..07e47e17 100644 --- a/docs/TweenManager.js.html +++ b/docs/TweenManager.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -451,13 +445,13 @@ Phaser.TweenManager = function (game) {
         this.game = game;
         
         /**
    -    * @property {array} _tweens - Description.
    +    * @property {array<Phaser.Tween>} _tweens - All of the currently running tweens.
         * @private
         */
         this._tweens = [];
         
         /**
    -    * @property {array} _add - Description.
    +    * @property {array<Phaser.Tween>} _add - All of the tweens queued to be added in the next update.
         * @private
         */
         this._add = [];
    @@ -469,13 +463,6 @@ Phaser.TweenManager = function (game) {
     
     Phaser.TweenManager.prototype = {
     
    -    /**
    -    * Version number of this library.
    -    * @property {string} REVISION
    -    * @default 
    -    */
    -    REVISION: '11dev',
    -
         /**
         * Get all the tween objects in an array.
         * @method Phaser.TweenManager#getAll
    @@ -488,12 +475,17 @@ Phaser.TweenManager.prototype = {
         },
     
         /**
    -    * Remove all tween objects.
    +    * Remove all tweens running and in the queue. Doesn't call any of the tween onComplete events.
         * @method Phaser.TweenManager#removeAll
         */
         removeAll: function () {
     
    -        this._tweens = [];
    +        for (var i = 0; i < this._tweens.length; i++)
    +        {
    +            this._tweens[i].pendingDelete = true;
    +        }
    +
    +        this._add = [];
     
         },
     
    @@ -504,9 +496,9 @@ Phaser.TweenManager.prototype = {
         * @param {Phaser.Tween} tween - The tween object you want to add.
         * @returns {Phaser.Tween} The tween object you added to the manager.
         */
    -    add: function ( tween ) {
    +    add: function (tween) {
     
    -        this._add.push( tween );
    +        this._add.push(tween);
     
         },
     
    @@ -529,14 +521,13 @@ Phaser.TweenManager.prototype = {
         * @method Phaser.TweenManager#remove
         * @param {Phaser.Tween} tween - The tween object you want to remove.
         */
    -    remove: function ( tween ) {
    +    remove: function (tween) {
     
    -        var i = this._tweens.indexOf( tween );
    -
    -        if ( i !== -1 ) {
    +        var i = this._tweens.indexOf(tween);
     
    +        if (i !== -1)
    +        {
                 this._tweens[i].pendingDelete = true;
    -
             }
     
         },
    @@ -549,7 +540,7 @@ Phaser.TweenManager.prototype = {
         */
         update: function () {
     
    -        if ( this._tweens.length === 0 && this._add.length === 0 )
    +        if (this._tweens.length === 0 && this._add.length === 0)
             {
                 return false;
             }
    @@ -557,20 +548,18 @@ Phaser.TweenManager.prototype = {
             var i = 0;
             var numTweens = this._tweens.length;
     
    -        while ( i < numTweens ) {
    -
    -            if ( this._tweens[ i ].update( this.game.time.now ) ) {
    -
    +        while (i < numTweens)
    +        {
    +            if (this._tweens[i].update(this.game.time.now))
    +            {
                     i++;
    -
    -            } else {
    -
    -                this._tweens.splice( i, 1 );
    +            }
    +            else
    +            {
    +                this._tweens.splice(i, 1);
     
                     numTweens--;
    -
                 }
    -
             }
     
             //  If there are any new tweens to be added, do so now - otherwise they can be spliced out of the array before ever running
    @@ -606,7 +595,8 @@ Phaser.TweenManager.prototype = {
         */
         pauseAll: function () {
     
    -        for (var i = this._tweens.length - 1; i >= 0; i--) {
    +        for (var i = this._tweens.length - 1; i >= 0; i--)
    +        {
                 this._tweens[i].pause();
             }
     
    @@ -619,13 +609,17 @@ Phaser.TweenManager.prototype = {
         */
         resumeAll: function () {
     
    -        for (var i = this._tweens.length - 1; i >= 0; i--) {
    +        for (var i = this._tweens.length - 1; i >= 0; i--)
    +        {
                 this._tweens[i].resume();
             }
     
         }
     
    -};
    +}; + +Phaser.TweenManager.prototype.constructor = Phaser.TweenManager; +
    @@ -640,13 +634,13 @@ Phaser.TweenManager.prototype = { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/Utils.js.html b/docs/Utils.js.html index 4dd4ef8d..abbfff1f 100644 --- a/docs/Utils.js.html +++ b/docs/Utils.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -425,7 +419,7 @@ /** * @author Richard Davey <rich@photonstorm.com> -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -620,53 +614,14 @@ Phaser.Utils = { }; -// Global functions that PIXI needs - -(function() { - var consoleDisabled = false; - if (consoleDisabled) { - window.console = undefined; - } - if (window.console === undefined) { - window.console = { - debug: function() { - return true; - }, - info: function() { - return false; - }, - warn: function() { - return false; - }, - log: function() { - return false; - } - } - } - debug = (function(args) { - window.console.debug(args); - }); - info = (function(args) { - window.console.info(args); - }); - warn = (function(args) { - window.console.warn(args); - }); - log = (function(args) { - window.console.log(args); - }); -})(); - -/** -* Converts a hex color number to an [R, G, B] array -* -* @param {number} hex -* @return {array} -*/ function HEXtoRGB(hex) { return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; } +PIXI.hex2rgb = function hex2rgb(hex) { + return [(hex >> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255]; +}; + /** * A polyfill for Function.prototype.bind */ @@ -703,6 +658,16 @@ if (typeof Function.prototype.bind != 'function') { }; })(); } + +/** +* A polyfill for Array.isArray +*/ +if (!Array.isArray) { + Array.isArray = function (arg) { + return Object.prototype.toString.call(arg) == '[object Array]'; + }; +} +
    @@ -718,13 +683,13 @@ if (typeof Function.prototype.bind != 'function') { - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/World.js.html b/docs/World.js.html index 94cc8e92..dc04dbad 100644 --- a/docs/World.js.html +++ b/docs/World.js.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -423,7 +417,7 @@
    /**
     * @author       Richard Davey <rich@photonstorm.com>
    -* @copyright    2013 Photon Storm Ltd.
    +* @copyright    2014 Photon Storm Ltd.
     * @license      {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
     */
     
    @@ -435,6 +429,7 @@
     * the world at world-based coordinates. By default a world is created the same size as your Stage.
     *
     * @class Phaser.World
    +* @extends Phaser.Group
     * @constructor
     * @param {Phaser.Game} game - Reference to the current game instance.
     */
    @@ -442,11 +437,6 @@ Phaser.World = function (game) {
     
         Phaser.Group.call(this, game, null, '__world', false);
     
    -    /**
    -    * @property {Phaser.Point} scale - Replaces the PIXI.Point with a slightly more flexible one.
    -    */
    -    this.scale = new Phaser.Point(1, 1);
    -
         /**
         * The World has no fixed size, but it does have a bounds outside of which objects are no longer considered as being "in world" and you should use this to clean-up the display list and purge dead objects.
         * By default we set the Bounds to be from 0,0 to Game.width,Game.height. I.e. it will match the size given to the game constructor with 0,0 representing the top-left of the display.
    @@ -488,34 +478,21 @@ Phaser.World.prototype.boot = function () {
     }
     
     /**
    -* This is called automatically every frame, and is where main logic happens.
    +* This is called automatically after the plugins preUpdate and before the State.update.
    +* Most objects have preUpdate methods and it's where initial movement, drawing and calculations are done.
     * 
     * @method Phaser.World#update
     */
    -Phaser.World.prototype.update = function () {
    -
    -    this.currentRenderOrderID = 0;
    +Phaser.World.prototype.preUpdate = function () {
         
         if (this.game.stage._stage.first._iNext)
         {
             var currentNode = this.game.stage._stage.first._iNext;
    -        var skipChildren;
             
             do
             {
    -            skipChildren = false;
    -
    -            if (currentNode['preUpdate'])
    -            {
    -                skipChildren = (currentNode.preUpdate() === false);
    -            }
    -
    -            if (currentNode['update'])
    -            {
    -                skipChildren = (currentNode.update() === false) || skipChildren;
    -            }
    -            
    -            if (skipChildren)
    +            // If preUpdate exists, and it returns false, skip PIXI child objects
    +            if (currentNode['preUpdate'] && !currentNode.preUpdate())
                 {
                     currentNode = currentNode.last._iNext;
                 }
    @@ -531,48 +508,123 @@ Phaser.World.prototype.update = function () {
     }
     
     /**
    -* This is called automatically every frame, and is where main logic happens.
    -* @method Phaser.World#postUpdate
    +* This is called automatically after the State.update, but before particles or plugins update.
    +* Most objects won't have an update method set unless explicitly given one.
    +* 
    +* @method Phaser.World#update
     */
    -Phaser.World.prototype.postUpdate = function () {
    +Phaser.World.prototype.update = function () {
     
    +    this.currentRenderOrderID = 0;
    +    
         if (this.game.stage._stage.first._iNext)
         {
             var currentNode = this.game.stage._stage.first._iNext;
             
             do
             {
    -            if (currentNode['postUpdate'])
    +            // If update exists, and it returns false, skip PIXI child objects
    +            if (currentNode['update'] && !currentNode.update())
                 {
    -                currentNode.postUpdate();
    +                currentNode = currentNode.last._iNext;
    +            }
    +            else
    +            {
    +                currentNode = currentNode._iNext;
                 }
                 
    -            currentNode = currentNode._iNext;
             }
             while (currentNode != this.game.stage._stage.last._iNext)
         }
     
    -    this.camera.update();
    +}
    +
    +/**
    +* This is called automatically before the renderer runs and after the plugins have updated.
    +* In postUpdate this is where all the final physics calculatations and object positioning happens.
    +* The objects are processed in the order of the display list.
    +* The only exception to this is if the camera is following an object, in which case that is updated first.
    +* 
    +* @method Phaser.World#postUpdate
    +*/
    +Phaser.World.prototype.postUpdate = function () {
    +
    +    if (this.camera.target && this.camera.target['postUpdate'])
    +    {
    +        this.camera.target.postUpdate();
    +
    +        this.camera.update();
    +
    +        if (this.game.stage._stage.first._iNext)
    +        {
    +            var currentNode = this.game.stage._stage.first._iNext;
    +            
    +            do
    +            {
    +                if (currentNode['postUpdate'] && currentNode !== this.camera.target)
    +                {
    +                    currentNode.postUpdate();
    +                }
    +                
    +                currentNode = currentNode._iNext;
    +            }
    +            while (currentNode != this.game.stage._stage.last._iNext)
    +        }
    +    }
    +    else
    +    {
    +        this.camera.update();
    +
    +        if (this.game.stage._stage.first._iNext)
    +        {
    +            var currentNode = this.game.stage._stage.first._iNext;
    +            
    +            do
    +            {
    +                if (currentNode['postUpdate'])
    +                {
    +                    currentNode.postUpdate();
    +                }
    +                
    +                currentNode = currentNode._iNext;
    +            }
    +            while (currentNode != this.game.stage._stage.last._iNext)
    +        }
    +    }
    +
     }
     
     /**
     * Updates the size of this world. Note that this doesn't modify the world x/y coordinates, just the width and height.
    -* If you need to adjust the bounds of the world
    +*
     * @method Phaser.World#setBounds
     * @param {number} x - Top left most corner of the world.
     * @param {number} y - Top left most corner of the world.
    -* @param {number} width - New width of the world.
    -* @param {number} height - New height of the world.
    +* @param {number} width - New width of the world. Can never be smaller than the Game.width.
    +* @param {number} height - New height of the world. Can never be smaller than the Game.height.
     */
     Phaser.World.prototype.setBounds = function (x, y, width, height) {
     
    +    if (width < this.game.width)
    +    {
    +        width = this.game.width;
    +    }
    +
    +    if (height < this.game.height)
    +    {
    +        height = this.game.height;
    +    }
    +
         this.bounds.setTo(x, y, width, height);
     
         if (this.camera.bounds)
         {
    +        //  The Camera can never be smaller than the game size
             this.camera.bounds.setTo(x, y, width, height);
         }
     
    +    this.game.physics.setBoundsToWorld();
    +
     }
     
     /**
    @@ -722,13 +774,13 @@ Object.defineProperty(Phaser.World.prototype, "visible", {
     					
     					
     		
    -		Phaser Copyright © 2012-2013 Photon Storm Ltd.
    +		Phaser Copyright © 2012-2014 Photon Storm Ltd.
     		
     					
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/build/build dev.bat b/docs/build/build dev.bat deleted file mode 100644 index 144602f1..00000000 --- a/docs/build/build dev.bat +++ /dev/null @@ -1 +0,0 @@ -jsdoc -c conf_dev.json \ No newline at end of file diff --git a/docs/build/build master.bat b/docs/build/build master.bat index 25b9d2c4..a1279222 100644 --- a/docs/build/build master.bat +++ b/docs/build/build master.bat @@ -1 +1 @@ -jsdoc -c conf.json \ No newline at end of file +jsdoc -c conf.json ../../README.md \ No newline at end of file diff --git a/docs/build/conf.json b/docs/build/conf.json index 95acdf2a..b965156b 100644 --- a/docs/build/conf.json +++ b/docs/build/conf.json @@ -5,7 +5,6 @@ "source": { "include": [ "../../src/Phaser.js", - "../../src/IntroDocs.js", "../../src/animation/", "../../src/core/", "../../src/gameobjects/", @@ -36,7 +35,7 @@ }, "systemName" : "Phaser", "footer" : "", - "copyright" : "Phaser Copyright © 2012-2013 Photon Storm Ltd.", + "copyright" : "Phaser Copyright © 2012-2014 Photon Storm Ltd.", "navType" : "vertical", "theme" : "cerulean", "linenums" : true, diff --git a/docs/build/conf_dev.json b/docs/build/conf_dev.json deleted file mode 100644 index 95acdf2a..00000000 --- a/docs/build/conf_dev.json +++ /dev/null @@ -1,58 +0,0 @@ -{ - "tags": { - "allowUnknownTags": true - }, - "source": { - "include": [ - "../../src/Phaser.js", - "../../src/IntroDocs.js", - "../../src/animation/", - "../../src/core/", - "../../src/gameobjects/", - "../../src/geom/", - "../../src/input/", - "../../src/loader/", - "../../src/math/", - "../../src/net/", - "../../src/particles/", - "../../src/physics/arcade/", - "../../src/sound/", - "../../src/system/", - "../../src/tilemap/", - "../../src/time/", - "../../src/tween/", - "../../src/utils/" - ], - "exclude": [], - "includePattern": ".+\\.js(doc)?$", - "excludePattern": "(^|\\/|\\\\)_" - }, - "plugins" : ["plugins/markdown"], - "templates": { - "cleverLinks" : false, - "monospaceLinks" : false, - "default" : { - "outputSourceFiles" : true - }, - "systemName" : "Phaser", - "footer" : "", - "copyright" : "Phaser Copyright © 2012-2013 Photon Storm Ltd.", - "navType" : "vertical", - "theme" : "cerulean", - "linenums" : true, - "collapseSymbols" : false, - "inverseNav" : true - }, - "markdown" : { - "parser" : "gfm", - "hardwrap" : true - }, - "opts": { - "template": "docstrap-master/template/", - "encoding": "utf8", - "destination": "../", - "recurse": true, - "private": false, - "lenient": true - } -} \ No newline at end of file diff --git a/docs/classes.list.html b/docs/classes.list.html index 6dc2e9d4..411a0665 100644 --- a/docs/classes.list.html +++ b/docs/classes.list.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -514,6 +508,9 @@
    Device
    +
    DOMSprite
    +
    +
    Easing
    @@ -568,6 +565,12 @@
    GameObjectFactory
    +
    Gamepad
    +
    + +
    GamepadButton
    +
    +
    Graphics
    @@ -586,6 +589,9 @@
    Keyboard
    +
    Line
    +
    +
    LinkedList
    @@ -655,6 +661,9 @@
    Signal
    +
    SinglePad
    +
    +
    Sound
    @@ -703,6 +712,9 @@
    Timer
    +
    TimerEvent
    +
    +
    Touch
    @@ -756,13 +768,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/global.html b/docs/global.html index d6ada66d..36df3ad4 100644 --- a/docs/global.html +++ b/docs/global.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -381,7 +405,7 @@
    - - - -
    -

    bottom(value)

    - - -
    -
    - - -
    -

    The sum of the y and height properties. Changing the bottom property of a Rectangle object has no effect on the x, y and width properties, but does change the height property.

    +

    Converts a hex color number to an [R, G, B] array

    @@ -616,13 +548,13 @@ - value + hex -number +Number @@ -664,7 +596,7 @@
    Source:
    @@ -782,7 +714,7 @@
    Source:
    @@ -829,473 +761,13 @@
    -

    render(displayObject, position, clear)

    +

    x() → {number}

    -
    -

    This function will draw the display object to the texture. If the display object is a Group or has children it will -draw all children as well.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeArgumentDefaultDescription
    displayObject - - -DisplayObject - - - - - - - - - - - -

    The display object to render this texture on.

    position - - -Phaser.Point - - - - - - <optional>
    - - - - - -
    - -

    Where to draw the display object.

    clear - - -boolean - - - - - - <optional>
    - - - - - -
    - - false - -

    If true the texture will be cleared before the displayObject is drawn.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    -

    renderXY(displayObject, x, y, clear)

    - - -
    -
    - - -
    -

    This function will draw the display object to the texture at the given x/y coordinates. -If the display object is a Group or has children it will draw all children as well.

    -
    - - - - - - - -
    Parameters:
    - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
    NameTypeArgumentDefaultDescription
    displayObject - - -DisplayObject - - - - - - - - - - - -

    The display object to render this texture on.

    x - - -number - - - - - - - - - - - -

    The x coordinate to draw the display object at.

    y - - -number - - - - - - - - - - - -

    The y coordinate to draw the display object at.

    clear - - -boolean - - - - - - <optional>
    - - - - - -
    - - false - -

    If true the texture will be cleared before the displayObject is drawn.

    - - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - - - - - - - - - - -
    - - - -
    - - - -
    -
    - - -
    -

    The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties. -However it does affect the width property.

    -
    - @@ -1326,7 +798,7 @@ However it does affect the width property.

    Source:
    @@ -1373,18 +845,13 @@ However it does affect the width property.

    - +

    x(value)

    -
    -

    The sum of the x and width properties. Changing the right property of a Rectangle object has no effect on the x, y and height properties. -However it does affect the width property.

    -
    - @@ -1464,7 +931,205 @@ However it does affect the width property.

    Source:
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    +

    y() → {number}

    + + +
    +
    + + + + + + + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    + + + + + + + +
    + + + + + + + + + + + +
    Returns:
    + + + + +
    +
    + Type +
    +
    + +number + + +
    +
    + + + + + +
    + + + +
    +

    y(value)

    + + +
    +
    + + + + + + + + +
    Parameters:
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    NameTypeDescription
    value + + +number + + + +
    + + + + +
    + + + + + + + + + + + + + + + + + + + +
    Source:
    +
    @@ -1509,13 +1174,13 @@ However it does affect the width property.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:20:17 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/index.html b/docs/index.html index f483d9dc..0af4ffc2 100644 --- a/docs/index.html +++ b/docs/index.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -440,102 +434,333 @@ +
    +

    Phaser Logo

    +

    Phaser 1.1.4

    +

    Phaser is a fast, free and fun open source game framework for making desktop and mobile browser HTML5 games. It uses Pixi.js internally for fast 2D Canvas and WebGL rendering.

    +

    Version: 1.1.4 "Kandor" - Released: February 5th 2014

    +

    By Richard Davey, Photon Storm

    + +

    Subscribe to our new Phaser Newsletter. We'll email you when new versions are released as well as send you our regular Phaser game making magazine.

    +

    Bitdeli Badge

    +

    Welcome to Phaser

    +

    As you may know we had planned to release 1.1.4 at the end of 2013. For various reasons this didn't quite happen, but we're happy to announce it's finally out! There have been some dramatic changes internally, and if you make use of either the physics systems or tilemaps then you are going to need to update your code. Hopefully only a little bit, but there have been a number of core API changes which we detail below. There are also a host of new features, the headliners being:

    +
      +
    • New Physics system. Uses SAT.js internally so physics bodies can now be rectangles, circles or polygons and support rotation.
    • +
    • New Tilemap system. Brand new collision system for tiles, much more advanced layer handling, tile properties, multiple tilesets of layer and more.
    • +
    • New Timer. This handy new class lets you create timed events easily.
    • +
    • Your Game can now be configured from an external configuration object.
    • +
    • Over 150 new features and updates and over 30 reported bug fixes.
    • +
    +

    This release also brings the TypeScript definitions file as bang up to date as possible. There are still a few areas that need looking at, but with your help hopefully we can iron those final few bits out and have a 100% accruate defs file on offer.

    +

    There is a new Contributors Guide which we'd urge you to follow if you wish to help with Phaser development, and we've updated the doc files and added lots more details into key areas. The Examples have grown too! Now over 220 of them including several great ones from the community.

    +

    We're going to settle on this build for a short while as we do some quick iteration bug fixing, so expect to see some small point releases very soon that do nothing but address any issues you may find. But in parallel to this we are also now rebuilding our core to bring it in-line with the latest version of Pixi.js, which has had some dramatic changes under the hood, changes will impact a lot of what Phaser does internally. But the changes are all for the better and once we upgrade Pixi you'll have a significantly faster renderer and a smaller codebase too, as we do away with stacks of linked list code :)

    +

    As always we offer a heart-felt "Thank you!" to everyone who has encouraged us along the way. To those of you who worked with Phaser during its various incarnations. The number of games being released that were made with Phaser is staggering and we really love to see how you use it! You are our heroes. It's your kind words and enthusiasm that has keeps us going.

    +

    Phaser is everything we ever wanted from an HTML5 game framework. It powers all of our client work in build today and remains our single most important product, and we've still only just scratched the surface of what we have planned for it.

    +

    MiniCybernoid

    +

    Getting Started Guides

    +

    We have a new Getting Started Guide which covers all you need to begin developing games with Phaser. From setting up a web server to picking an IDE. If you're new to HTML5 game development, or are coming from another language like AS3, then we recommend starting there.

    +

    There is a comprehensive How to Learn Phaser guide on the GameDevTuts+ site which is a great place to learn where to find tutorials, examples and support.

    +

    There is also an un-official Getting Started Guide.

    +

    Change Log

    +

    Version 1.1.4 - "Kandor" - February 5th 2014

    +

    Significant API changes:

    +
      +
    • Loader.tileset has been removed as it's no longer required, this was as part of the Tilemap system overhaul.
    • +
    • TilemapLayers are now created via the Tilemap object itself: map.createLayer(x, y, width, height, tileset, layer, group) and no longer via the GameObjectFactory.
    • +
    • Tilemap.createFromObjects can now turn a bunch of Tiled objects into Sprites in one single call, and copies across all properties as well.
    • +
    • Tween.onStartCallback and onCompleteCallback have been removed to avoid confusion. You should use the onStart, onLoop and onComplete events instead.
    • +
    • Button.forceOut default value has changed from true to false, so Buttons will revert to an Up state (if set) when pressed and released.
    • +
    • The way the collision process callback works has changed significantly and now works as originally intended.
    • +
    • The World level quadtree is no longer created, they are now built and ripped down each time you collide a Group, this helps collision accuracy.
    • +
    • A SAT system has been integrated for Body collision and separation.
    • +
    • Bodies are no longer added to a world quadtree, so have had all of their quadtree properties removed such as skipQuadtree, quadTreeIndex, etc.
    • +
    • Body.drag has been removed. Please use the new Body.linearDamping value instead (which is a number value, not a Point object)
    • +
    • Body.embedded and Body.wasTouching have been removed as they are no longer required.
    • +
    • Body.customSeparateX/Y have been removed as you should now use Body.customSeparateCallback.
    • +
    • Body.maxVelocity defaults have been removed from 10,000 to 2000.
    • +
    • Body.customSeparateCallback allows you to set your own callback when two Bodies need to separate rather than using the built-in method.
    • +
    • Body.collideCallback allows you to set a callback that is fired whenever the Body is hit on any of its active faces.
    • +
    • Body.allowCollision has been renamed to Body.checkCollision.
    • +
    • Body.rebound is a boolean that controls if a body will exchange velocity on collision. Set to false to allow it to be 'pushed' (see new examples).
    • +
    • Removed Body.deltaAbsX and deltaAbsY as they are no longer used internally.
    • +
    • Body.screenX and screenY moved to getters, no longer calculated every frame.
    • +
    • ArcadePhysics now has setBounds and setBoundsToWorld, and you can specify which walls are created or not (left, right, up, down)
    • +
    • Removed: Debug.renderSpriteTouching, Debug.renderLocalTransformInfo, Debug.renderWorldTransformInfo, Debug.renderSpriteCollision and Debug.dumpLinkedList.
    • +
    • Body.setSize has been removed. Please use Body.setCircle, setRectangle or setPolygon instead.
    • +
    +

    New features:

    +
      +
    • Phaser.Timer is now feature complete and fully documented. You can create Phaser.TimerEvents on a Timer and lots of new examples have been provided.
    • +
    • Gamepad API support has been added with lots of new examples (thanks Karl Macklin)
    • +
    • Phaser.Game constructor can now be passed a single object containing all of your game settings + Stage settings. Useful for advanced configurations.
    • +
    • The width/height given to Phaser.Game can now be percentages, i.e. "100%" will set the width to the maximum window innerWidth.
    • +
    • Added a stage.fullScreenScaleMode property to determine scaling when fullscreen (thanks oysterCrusher)
    • +
    • Added support for margin and spacing around a frame in Loader.spritesheet.
    • +
    • Added Device.vibration to check if the Vibration API is available or not.
    • +
    • Added Device.trident and Device.tridentVersion for testing IE11.
    • +
    • Added Device.silk for detecting a Kindle Fire and updated desktop OS check to exclude Kindles (thanks LuckieLordie)
    • +
    • TilemapLayers now have debug and debugAlpha values, this turns on the drawing of the collision edges (very handy for debugging, as the name implies!)
    • +
    • Tweens have a new event: onLoop.
    • +
    • You can now load any binary file via the Loader: game.load.binary(key, url, callback) - the optional callback allows for post-load processing before entering the Cache.
    • +
    • Group.set will let you deep set a new propery on a single child of the Group.
    • +
    • Stage.display property added. A direct reference to the root Pixi Stage object (very useful for RenderTexture manipulation)
    • +
    • Added Ejecta detection to Device (thanks endel)
    • +
    • Tweens can now work with relative + and - values. You can do: tween(sprite).to( { x: '+400' }) and it will add 400 to the current sprite.x value.
    • +
    • Buttons now properly use their upFrame if set.
    • +
    • InputHandler now has snapOffsetX and snapOffsetY properties so your snap grid doesn't have to be 0,0 aligned (thanks srmeier)
    • +
    • Loader.progressFloat contains the actual non-rounded progress value, where-as Loader.progress contains a rounded value. Use progressFloat if you've > 100 files to load.
    • +
    • Groups can now be added to other Groups as children via group.add() and group.addAt()
    • +
    • Groups now have an 'alive' property, which can be useful when iterating through child groups with functions like forEachAlive.
    • +
    • Added a new Project Template "Full Screen Mobile" which you can find in the resources folder. Contains html / css / layout needed for a deployed Phaser game.
    • +
    • Body.speed - the current speed of the body.
    • +
    • Body.angle - the current angle the Body is facing based on its velocity. This is not the same as the Sprite angle that may own the body.
    • +
    • Body.linearDamping - This now replaces Body.drag and provides for a much smoother damping (friction) experience.
    • +
    • Body.minBounceVelocity - If a Body has bounce set, this threshold controls if it should rebound or not. Use it to stop 'jittering' on bounds/tiles with super-low velocities.
    • +
    • QuadTree.populate - you can pass it a Group and it'll automatically insert all of the children ready for inspection.
    • +
    • Input.setMoveCallback allows you to set a callback that will be fired each time the activePointer receives a DOM move event.
    • +
    • Math.distancePow(x1,y1,x2,y2,power) returns the distance between two coordinates at the given power.
    • +
    • Physics.collide now supports the 2nd parameter as an array, for when you want to collide an object against a number of sprites that aren't all in the same Group.
    • +
    • Physics.overlap now supports the 2nd parameter as an array, for when you want to overlap test an object against a number of sprites that aren't all in the same Group.
    • +
    • Math.reverseAngle - reverses an angle (in radians).
    • +
    • Math.normalizeAngle - normalises an angle, now in radians only.
    • +
    • Math.normalizeLatitude - Normalizes a latitude to the [-90,90] range.
    • +
    • Math.normalizeLongitude - Normalizes a longitude to the [-180,180] range.
    • +
    • Phaser.Line added to the geometry classes, with full point on line/segment and intersection tests (see new examples)
    • +
    • Phaser.CANVAS_PX_ROUND is a boolean. If 'true' the Canvas renderer will Math.floor() all coordinates before drawImage, stopping pixel interpolation. Defaults to false.
    • +
    • Phaser.CANVAS_CLEAR_RECT is a boolean. If 'true' (the default) it will context.clearRect() every frame. If false this is skipped (useful if you know you don't need it)
    • +
    • Collision now works between Sprites positioned via sprite.x/y, sprite.body.x/y or sprite.body.velocity.
    • +
    • If you are tweening a sprite and still want physics collision, set sprite.body.moves = false otherwise it will fight against the tween motion.
    • +
    • Game.enableStep will enable core game loop stepping. When enabled you must call game.step() directly (perhaps via a DOM button?), very useful for debugging!
    • +
    • Game.disableStep turns core update loop stepping off.
    • +
    • Debug.renderPhysicsBody(body, color) is extremely useful for debugging the new physics bodies. Will draw the outline + points in the color given.
    • +
    • Debug.renderBodyInfo(sprite, x, y, color) will display lots of Sprite body data.
    • +
    • Sprite.events.onBeginContact will be fired when a Body makes contact with another Body. Once contact is over an onEndContact event will be dispatched.
    • +
    +

    New Examples:

    +
      +
    • Physics - Bounce by Patrick OReilly.
    • +
    • Physics - Bounce with gravity by Patrick OReilly.
    • +
    • Physics - Bounce accelerator (use the keyboard) by Patrick OReilly.
    • +
    • Physics - Bounce knock (use the keyboard) by Patrick OReilly.
    • +
    • Physics - Snake (use the keyboard to control the snake like creature) by Patrick OReilly and Richard Davey.
    • +
    • Physics - Launcher - Angry Birds style ball launcher demo by Patrick OReilly.
    • +
    • Physics - Launcher Follow - throw the sprite anywhere in the world by Patrick OReilly.
    • +
    • Physics - Launcher Follow World - an advanced version of the Launcher Follow example by Patrick OReilly.
    • +
    • Input - Touch Joystick example showing how to use the clay.io virtual game controller (thanks gabehollombe)
    • +
    • Games - Matching Pairs by Patrick OReilly.
    • +
    • Games - Simon Says by Patrick OReilly.
    • +
    • Games - Wabbits by Patrick OReilly.
    • +
    • Tweens - Example showing how to use the tween events, onStart, onLoop and onComplete.
    • +
    • Display - Pixi Render Texture. A Phaser conversion of the Pixi.js Render Texture example.
    • +
    • Input - 5 new examples showing how to use the Gamepad API (thanks Karl Macklin)
    • +
    • Animation - Group Creation, showing how to create animations across all Group children in one call.
    • +
    • Particles - Rain by Jens Anders Bakke.
    • +
    • Particles - Snow by Jens Anders Bakke.
    • +
    • Groups - Nested Groups - showing how to embed one Group into another Group.
    • +
    • Time - Lots of new examples showing how to use the updated Phaser.Timer class.
    • +
    +

    Updates:

    +
      +
    • Updated to latest Pixi.js dev branch build (pre 1.4 release)
    • +
    • When a Sprite is destroyed any active filters are removed at the same time.
    • +
    • Updated Pixi.js so that removing filters now works correctly without breaking the display list.
    • +
    • Phaser.Canvas.create updated so it can be given an ID as the 3rd parameter (can also be set via new Game configuration object).
    • +
    • Updated display/fullscreen example to reflect new full screen change.
    • +
    • Loads of updates to the TypeScript definitions files - games fully compile now and lots of missing classes added :) (thanks Niondir)
    • +
    • Removed 'null parent' check from Group constructor. Will parent to game.world only if parent value is undefined.
    • +
    • The tutorials have now been translated into Spanish - thanks feiss :)
    • +
    • separateY updated to re-implement the 'riding platforms' special condition (thanks cocoademon)
    • +
    • SoundManager.onSoundDecode now dispatches the key followed by the sound object, also now dispatched by the Cache when doing an auto-decode on load.
    • +
    • Switch method of using trimmed sprites to support scaling and rotation (thanks cocoademon)
    • +
    • Most of the GameObjectFactory functions now have a group parameter, so you can do: game.add.sprite(x, y, frame, frameName, group) rather than defaulting to the World group.
    • +
    • Group.countLiving and countDead used to return -1 if the Group was empty, but now return 0.
    • +
    • Text can now be fixedToCamera, updated world/fixed to camera example to show this.
    • +
    • ArcadePhysics.overlap and collide now recognise TileSprites in the collision checks.
    • +
    • Lots of documentation fixes in the Tween class.
    • +
    • Tweens fire an onLoop event if they are set to repeat. onComplete is now only fired for the final repeat (or never if the repeat is infinite)
    • +
    • Pointer used to un-pause a paused game every time it was clicked/touched (this avoided some rogue browser plugins). Now only happens if Stage.disableVisibilityChange is true.
    • +
    • Input doesn't set the cursor to default if it's already set to none.
    • +
    • You can now collide a group against itself. This will check all children against each other, but not themselves (thanks cocoademon)
    • +
    • RenderTexture.render / renderXY has a new parameter: renderHidden, a boolean which will allow you to render Sprites even if their visible is set to false.
    • +
    • Added in prototype.constructor definitions to every class (thanks darkoverlordofdata)
    • +
    • Group.destroy has a new parameter: destroyChildren (boolean) which will optionally call the destroy method of all Group children.
    • +
    • Button.clearFrames method has been added.
    • +
    • Device.quirksMode is a boolean that informs you if the page is in strict (false) or quirks (true) mode.
    • +
    • Canvas.getOffset now runs a strict/quirks check and uses document.documentElement when calculating scrollTop and scrollLeft to avoid Chrome console warnings.
    • +
    • The Time class now has its own Phaser.Timer which you can access through game.time.events. See the new Timer examples to show how to use them.
    • +
    • Added StateManager.getCurrentState to return the currently running State object (thanks Niondir)
    • +
    • Removed the console.log redirect from Utils as it was messing with Firefox.
    • +
    • Body.acceleration is now much smoother and less eratic at high speeds.
    • +
    • Removed ArcadePhysics binding to the QuadTree, so it can now be used independantly of the physics system.
    • +
    • Removed ArcadePhysics.preUpdate and postUpdate as neither are needed any more.
    • +
    • Body.bottom and Body.right are no longer rounded, so will give accurate sub-pixel values.
    • +
    • Fixed lots of documentation in the Emitter class.
    • +
    • The delta timer value used for physics calculations has had its cap limit modified from 1.0 to 0.05 in line with the core updates.
    • +
    • Phaser.Math.min enhanced so you can now pass in either an array of numbers or lots of numbers as parameters to get the lowest.
    • +
    • Phaser.Math.max added as the opposite of Math.min.
    • +
    • Phaser.Math.minProperty and maxProperty added. Like Math.min/max but can be given a property an an array or list of objects to inspect.
    • +
    • Added 'full' paramter to Body.reset, allowing you to control if motion or all data is reset or not.
    • +
    • Exposed Group.pivot and Sprite.pivot to allow you to directly set the pivot points for rotation.
    • +
    • Swapped to using the native and faster Array.isArray check.
    • +
    • Added callback context parameter to Tween.onUpdateCallback(callback, context) to avoid having to bind or create anonymous functions.
    • +
    • Updated TweenManager.removeAll so it flags all tweens as pendingDelete rather than nuking the array, to avoid tween callback array size errors (thanks DarkDev)
    • +
    +

    Bug Fixes:

    +
      +
    • Cache.getImageKeys returned __missing in the array, now excluded.
    • +
    • Fixed Group.scale so you can now scale a Group directly.
    • +
    • Removed World.scale as it was preventing Group.scale from working - you can still scale the world, but you'll need to factor in Input changes yourself.
    • +
    • Moved 'dirty' flag for Tilemap to a per-layer flag. Fixes #242
    • +
    • Group.length now returns the number of children in the Group regardless of their exists/alive state, or 0 if the Group has no children.
    • +
    • Switch Camera.setBoundsToWorld to match world.bounds instead of world (thanks cocoademon)
    • +
    • Fixed an issue where passing null as the Group parent wouldn't set it to game.world as it should have (thanks tito100)
    • +
    • Fixed Pixi bug (#425) incorrect width property for multi-line BitmapText (thanks jcd-as)
    • +
    • Tween.onStart is now called when the tween starts AFTER the delay value, if given (thanks stevenbouma)
    • +
    • Sprites that are fixedToCamera can now be input dragged regardless of world position (thanks RafaelOliveira)
    • +
    • RenderTexture now displays correctly in Canvas games.
    • +
    • Canvas.addToDOM is now more robust when applying the overflowHidden style.
    • +
    • Fixed Pixi.StripShader which should stop the weird TileSprite GPU issues some were reporting (thanks GoodboyDigital)
    • +
    • Patched desyrel.xml so it doesn't contain any zero width/height characters, as they broke Firefox 25.
    • +
    • Cache.addSound now implements a locked attribute (thanks haden)
    • +
    • Sound now checks for CocoonJS during playback to avoid readyState clash (thanks haden)
    • +
    • Buttons now clear previously set frames correctly if you call setFrames.
    • +
    • Sounds will now loop correctly if they are paused and resumed (thanks haden)
    • +
    • InputHandler.checkBoundsRect and checkBoundsSprite now take into account if the Sprite is fixedToCamera or not.
    • +
    • Removed the frame property from TileSprites as it cannot use them, it tiles the whole image only, not just a section of it.
    • +
    • Fixed WebGLRenderer updateGraphics bug (thanks theadam)
    • +
    • Removed duplicate Timer.create line (thanks hstolte)
    • +
    • Fixed issue with the camera being slightly out of sync with 'fixedToCamera' sprites.
    • +
    • 1px camera jitter issue fixed where map is same size, or smaller than the game size.
    • +
    +

    You can view the Change Log for all previous versions at https://github.com/photonstorm/phaser/changelog.md

    +

    How to Build

    +

    We provide a fully compiled version of Phaser in the build directory, in both plain and minified formats.

    +

    We also provide a Grunt script that will build Phaser from source along with all the examples.

    +

    Run grunt in the phaser folder for a list of command-line options.

    +

    Koding

    +

    You can ![clone the Phaser repo in Koding]koding and then start editing and previewing code right away using their web based VM development system.

    +

    Bower

    +

    If you use bowser you can install phaser with:

    +

    bower install phaser

    +

    Nice and easy :)

    +

    Tanks

    +

    CDNJS

    +

    Thanks to a community member Phaser is now available on CDNJS. You can include the following in your html:

    +

    http://cdnjs.cloudflare.com/ajax/libs/phaser/1.1.3/phaser.min.js

    +

    Or if you prefer you can leave the protocol off, so it works via http and https:

    +

    //cdnjs.cloudflare.com/ajax/libs/phaser/1.1.3/phaser.min.js

    +

    Requirements

    +

    Games created with Phaser require a modern web browser that supports the canvas tag. This includes Internet Explorer 9+, Firefox, Chrome, Safari and Opera. It also works on mobile web browsers including stock Android 2.x browser and above and iOS5 Mobile Safari and above.

    +

    For developing with Phaser you can use either a plain-vanilla JavaScript approach or TypeScript using the provided TypeScript definitions file. We made no assumptions about how you like to code your games, and were careful not to impose any form of class/inheritance/structure upon you.

    +

    Phaser is 321 KB minified and 72 KB gzipped.

    +

    Learn By Example

    +

    Phaser comes with an ever growing suite of Examples. Personally I feel that we learn better by looking at small refined code examples, so we created over 200 of them and create new ones to test every new feature added. Inside the examples folder you'll find the current set. If you write a particularly good example then please send it to us.

    +

    The examples need to be run through a local web server (in order to avoid file access permission errors from your browser). You can use your own web server, or start the included web server using grunt.

    +

    Using a locally installed web server browse to the examples folder:

    +
    examples/index.html
    +

    Alternatively in order to start the included web server, after you've cloned the repo, run npm install to install all dependencies, then grunt connect to start a local server. After running this command you should be able to access your local webserver at http://127.0.0.1:8000. Then browse to the examples folder: http://127.0.0.1:8000/examples/index.html

    +

    There is a new 'Side View' example viewer as well. This loads all the examples into a left-hand frame for faster navigation.

    +

    You can also browse all Phaser Examples online.

    +

    Features

    +

    WebGL & Canvas

    +

    Phaser uses both a Canvas and WebGL renderer internally and can automatically swap between them based on browser support. This allows for lightning fast rendering across Desktop and Mobile. When running under WebGL Phaser now supports shaders, allowing for some incredible in-game effects. Phaser uses and contributes towards the excellent Pixi.js library for rendering.

    +

    Preloader

    +

    We've made the loading of assets as simple as one line of code. Images, Sounds, Sprite Sheets, Tilemaps, JSON data, XML and JavaScrtip files - all parsed and handled automatically, ready for use in game and stored in a global Cache for Sprites to share.

    +

    Physics

    +

    Phaser ships with our Arcade Physics system. A SAT based collision and physics library perfect for low-powered devices and fast collision response. Control velocity, acceleration, bounce, damping and full collision and separation control. As of version 1.1.4 we now support rectangles, circles and polygon collision with full rotation.

    +

    Sprites

    +

    Sprites are the life-blood of your game. Position them, tween them, rotate them, scale them, animate them, collide them, paint them onto custom textures and so much more! +Sprites also have full Input support: click them, touch them, drag them around, snap them - even pixel perfect click detection if needed.

    +

    Groups

    +

    Group bundles of Sprites together for easy pooling and recycling, avoiding constant object creation. Groups can also be collided: for example a "Bullets" group checking for collision against the "Aliens" group, with a custom collision callback to handle the outcome.

    +

    Animation

    +

    Phaser supports classic Sprite Sheets with a fixed frame size, Texture Packer and Flash CS6/CC JSON files (both Hash and Array formats) and Starling XML files. All of these can be used to easily create animation for Sprites.

    +

    Particles

    +

    An Arcade Particle system is built-in, which allows you to create fun particle effects easily. Create explosions or constant streams for effects like rain or fire. Or attach the Emitter to a Sprite for a jet trail.

    +

    Camera

    +

    Phaser has a built-in Game World. Objects can be placed anywhere within the world and you've got access to a powerful Camera to look into that world. Pan around and follow Sprites with ease.

    +

    Input

    +

    Talk to a Phaser.Pointer and it doesn't matter if the input came from a touch-screen or mouse, it can even change mid-game without dropping a beat. Multi-touch, Mouse, Keyboard and lots of useful functions allow you to code custom gesture recognition.

    +

    Sound

    +

    Phaser supports both Web Audio and legacy HTML Audio. It automatically handles mobile device locking, easy Audio Sprite creation, looping, streaming and volume. We know how much of a pain dealing with audio on mobile is, so we did our best to resolve that!

    +

    Tilemaps

    +

    Phaser can load, render and collide with a tilemap with just a couple of lines of code. We support CSV and Tiled map data formats with multiple tile layers. There are lots of powerful tile manipulation functions: swap tiles, replace them, delete them, add them and update the map in realtime.

    +

    Device Scaling

    +

    Phaser has a built-in Scale Manager which allows you to scale your game to fit any size screen. Control aspect ratios, minimum and maximum scales and full-screen support.

    +

    Plugin system

    +

    We are trying hard to keep the core of Phaser limited to only essential classes, so we built a smart Plugin system to handle everything else. Create your own plugins easily and share them with the community.

    +

    Mobile Browser

    +

    Phaser was built specifically for Mobile web browsers. Of course it works blazingly fast on Desktop too, but unlike lots of frameworks mobile was our main focus. If it doesn't perform well on mobile then we don't add it into the Core.

    +

    Developer Support

    +

    We use Phaser every day on our many client projects. As a result it's constantly evolving and improving and we jump on bugs and pull requests quickly. This is a living, breathing framework maintained by a commercial company with custom feature development and support packages available. We live and breathe HTML5 games.

    +

    Battle Tested

    +

    Although Phaser 1.0 is a brand new release it is born from years of experience building some of the biggest mobile HTML5 games out there. We're not saying it is 100% bug free, but we use it for our client work every day, so issues get resolved <em>fast</em> and we stay on-top of the changing browser landscape.

    +

    FruitParty

    +

    Road Map

    +

    Here is what's on our road map for the coming months:

    +

    Version 1.1.5 ("Saldaea")

    +
      +
    • A fast turn-around point release that will focus on addressing any bugs that occured as a result of the large changes that took place in 1.1.4.
    • +
    +

    Version 1.2 ("Shienar")

    +
      +
    • Update to Pixi 1.4 - this newly released build has lots of internal changes and new features we want to take advantage of.
    • +
    +

    Version 1.3 ("Tarabon")

    +
      +
    • Enhance the State Management, so you can perform non-destructive State swaps and persistence.
    • +
    • Dedicated CocoonJS packaging features (screencanvas, etc)
    • +
    • A more advanced Particle system, one that can render to a single canvas (rather than spawn hundreds of Sprites), more advanced effects, etc.
    • +
    • Ability to control DOM elements from the core game and layer them into the game.
    • +
    • Touch Gestures.
    • +
    • Support for parallel asset loading.
    • +
    • Fixed width bitmap font support, plus enhanced Bitmap font rendering.
    • +
    +

    Version 2.0 ("Aes Sedai")

    +
      +
    • Integrate p2.js physics system completely.
    • +
    • Comprehensive testing across Firefox OS devices, CocoonJS and Ejecta.
    • +
    • Integration with third party services like Google Play Game Services and Amazon JS SDK.
    • +
    • Flash CC HTML5 export integration.
    • +
    • Massively enhance the audio side of Phaser. Although it does what it does well, it could do with taking more advantage of Web Audio - echo effects, positional sound, etc.
    • +
    +

    Beyond version 2.0

    +
      +
    • Test out packaging with Node-webkit.
    • +
    • Game parameters stored in Google Docs.
    • +
    • Look at HiDPI Canvas settings.
    • +
    • Multiple Camera support.
    • +
    +

    Contributing

    +

    We now have a full Contributors Guide which goes into the process in more detail, but here are the headlines:

    +
      +
    • If you find a bug then please report it on GitHub Issues or our Support Forum.

      +
    • +
    • If you have a feature request, or have written a game or demo that shows Phaser in use, then please get in touch. We'd love to hear from you! Either post to our forum or email: rich@photonstorm.com

      +
    • +
    • If you issue a Pull Request for Phaser, please only do so againt the dev branch and not against the master branch.

      +
    • +
    • Before submitting a Pull Request please run your code through JSHint to check for stylistic or formatting errors. To use JSHint, first install it by running npm install jshint, then test your code by running jshint src. This isn't a strict requirement and we are happy to receive Pull Requests that haven't been JSHinted, so don't let it put you off contributing, but do know that we'll reformat your source before going live with it.

      +
    • +
    +

    Bugs?

    +

    Please add them to the Issue Tracker with as much info as possible, especially source code demonstrating the issue.

    +

    Phaser Tilemap

    +

    "Being negative is not how we make progress" - Larry Page, Google

    +

    License

    +

    Phaser is released under the MIT License.

    +

    Analytics

    +
    - - - - -

    Index

    -
    - -
    -

    - D:\wamp\www\phaser\src/IntroDocs.js -

    - -
    - -
    -
    - - - - -

    Phaser - http://www.phaser.io

    -

    v1.1.3 - Released November 28th 2013.

    -

    By Richard Davey http://www.photonstorm.com @photonstorm

    -

    A feature-packed 2D HTML5 game framework born from the smouldering pits of Flixel and -constructed via plenty of blood, sweat, tears and coffee by Richard Davey (@photonstorm).

    -

    Phaser uses Pixi.js for rendering, created by Mat Groves http://matgroves.com/ @Doormat23.

    -

    Follow Phaser development progress at http://www.photonstorm.com

    -

    Many thanks to Adam Saltsman (@ADAMATOMIC) for releasing Flixel, from both which Phaser -and my love of game development originate.

    -

    "If you want your children to be intelligent, read them fairy tales." -"If you want them to be more intelligent, read them more fairy tales." - -- Albert Einstein

    - - - -
    - - - - - - - - - - - - - - - - - - - -
    Source:
    -
    - - - - - - - -
    - - - - -
    - - - - - - - - - - - - - - - - - - -
    - -
    @@ -547,13 +772,13 @@ and my love of game development originate.

    - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:26 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/docs/namespaces.list.html b/docs/namespaces.list.html index b93eaf9e..f5a3ebbe 100644 --- a/docs/namespaces.list.html +++ b/docs/namespaces.list.html @@ -90,6 +90,10 @@ Device +
  • + DOMSprite +
  • +
  • Easing
  • @@ -162,6 +166,14 @@ GameObjectFactory +
  • + Gamepad +
  • + +
  • + GamepadButton +
  • +
  • Graphics
  • @@ -186,6 +198,10 @@ Keyboard +
  • + Line +
  • +
  • LinkedList
  • @@ -278,6 +294,10 @@ Signal +
  • + SinglePad +
  • +
  • Sound
  • @@ -342,6 +362,10 @@ Timer +
  • + TimerEvent +
  • +
  • Touch
  • @@ -374,36 +398,6 @@ - - @@ -514,6 +508,9 @@
    Device
    +
    DOMSprite
    +
    +
    Easing
    @@ -568,6 +565,12 @@
    GameObjectFactory
    +
    Gamepad
    +
    + +
    GamepadButton
    +
    +
    Graphics
    @@ -586,6 +589,9 @@
    Keyboard
    +
    Line
    +
    +
    LinkedList
    @@ -655,6 +661,9 @@
    Signal
    +
    SinglePad
    +
    +
    Sound
    @@ -703,6 +712,9 @@
    Timer
    +
    TimerEvent
    +
    +
    Touch
    @@ -756,13 +768,13 @@ - Phaser Copyright © 2012-2013 Photon Storm Ltd. + Phaser Copyright © 2012-2014 Photon Storm Ltd.
    Documentation generated by JSDoc 3.3.0-dev - on Thu Nov 28 2013 15:56:25 GMT-0000 (GMT) using the DocStrap template. + on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template. diff --git a/examples/_site/examples.json b/examples/_site/examples.json index 7897fca7..dcd475f9 100644 --- a/examples/_site/examples.json +++ b/examples/_site/examples.json @@ -4,6 +4,10 @@ "file": "change+texture+on+click.js", "title": "change texture on click" }, + { + "file": "group+creation.js", + "title": "group creation" + }, { "file": "local+json+object.js", "title": "local json object" @@ -37,6 +41,10 @@ { "file": "play+music.js", "title": "play music" + }, + { + "file": "protracker.js", + "title": "protracker" } ], "basics": [ @@ -106,14 +114,30 @@ } ], "collision": [ + { + "file": "body+scale.js", + "title": "body scale" + }, { "file": "bounding+box.js", "title": "bounding box" }, + { + "file": "circle+body.js", + "title": "circle body" + }, + { + "file": "circle+vs+polygon.js", + "title": "circle vs polygon" + }, { "file": "group+vs+group.js", "title": "group vs group" }, + { + "file": "group+vs+self.js", + "title": "group vs self" + }, { "file": "larger+bounding+box.js", "title": "larger bounding box" @@ -123,30 +147,60 @@ "title": "offset bounding box" }, { - "file": "sprite+tiles.js", - "title": "sprite tiles" + "file": "one+way+collision.js", + "title": "one way collision" + }, + { + "file": "polygon+body.js", + "title": "polygon body" + }, + { + "file": "process+callback.js", + "title": "process callback" + }, + { + "file": "rotated+bounding+box.js", + "title": "rotated bounding box" }, { "file": "sprite+vs+group.js", "title": "sprite vs group" }, - { - "file": "sprite+vs+sprite+custom.js", - "title": "sprite vs sprite custom" - }, { "file": "sprite+vs+sprite.js", "title": "sprite vs sprite" }, - { - "file": "transform.js", - "title": "transform" - }, { "file": "vertical+collision.js", "title": "vertical collision" } ], + "debug": [ + { + "file": "debug+camera.js", + "title": "debug camera" + }, + { + "file": "debug+display.js", + "title": "debug display" + }, + { + "file": "debug+draw.js", + "title": "debug draw" + }, + { + "file": "debug+input.js", + "title": "debug input" + }, + { + "file": "debug+physics.js", + "title": "debug physics" + }, + { + "file": "debug+sprite.js", + "title": "debug sprite" + } + ], "display": [ { "file": "bitmapdata+wobble.js", @@ -160,6 +214,10 @@ "file": "graphics.js", "title": "graphics" }, + { + "file": "pixi+render+texture.js", + "title": "pixi render texture" + }, { "file": "render+crisp.js", "title": "render crisp" @@ -216,6 +274,14 @@ "file": "invaders.js", "title": "invaders" }, + { + "file": "matching+pairs.js", + "title": "matching pairs" + }, + { + "file": "simon.js", + "title": "simon" + }, { "file": "starstruck.js", "title": "starstruck" @@ -230,6 +296,10 @@ "file": "circle.js", "title": "circle" }, + { + "file": "line+intersection.js", + "title": "line intersection" + }, { "file": "line.js", "title": "line" @@ -252,14 +322,14 @@ "file": "add+a+sprite+to+group.js", "title": "add a sprite to group" }, - { - "file": "bring+a+child+to+top.js", - "title": "bring a child to top" - }, { "file": "bring+a+group+to+top.js", "title": "bring a group to top" }, + { + "file": "call+all+animations.js", + "title": "call all animations" + }, { "file": "call+all.js", "title": "call all" @@ -308,6 +378,10 @@ "file": "group+transform.js", "title": "group transform" }, + { + "file": "nested+groups.js", + "title": "nested groups" + }, { "file": "recyling.js", "title": "recyling" @@ -334,6 +408,10 @@ } ], "input": [ + { + "file": "bring+a+child+to+top.js", + "title": "bring a child to top" + }, { "file": "cursor+key+movement.js", "title": "cursor key movement" @@ -358,6 +436,30 @@ "file": "game+scale.js", "title": "game scale" }, + { + "file": "gamepad+analog+button.js", + "title": "gamepad analog button" + }, + { + "file": "gamepad+debug.js", + "title": "gamepad debug" + }, + { + "file": "gamepad+hotkeys.js", + "title": "gamepad hotkeys" + }, + { + "file": "gamepad+multiple+pads.js", + "title": "gamepad multiple pads" + }, + { + "file": "gamepad+tanks.js", + "title": "gamepad tanks" + }, + { + "file": "gamepad.js", + "title": "gamepad" + }, { "file": "key.js", "title": "key" @@ -484,10 +586,18 @@ "file": "no+rotation.js", "title": "no rotation" }, + { + "file": "rain.js", + "title": "rain" + }, { "file": "random+sprite.js", "title": "random sprite" }, + { + "file": "snow.js", + "title": "snow" + }, { "file": "when+particles+collide.js", "title": "when particles collide" @@ -518,6 +628,42 @@ "file": "angular+velocity.js", "title": "angular velocity" }, + { + "file": "bounce+accelerator.js", + "title": "bounce accelerator" + }, + { + "file": "bounce+knock.js", + "title": "bounce knock" + }, + { + "file": "bounce+with+gravity.js", + "title": "bounce with gravity" + }, + { + "file": "bounce.js", + "title": "bounce" + }, + { + "file": "framerate+independence.js", + "title": "framerate independence" + }, + { + "file": "gravity.js", + "title": "gravity" + }, + { + "file": "launcher+follow+world.js", + "title": "launcher follow world" + }, + { + "file": "launcher+follow.js", + "title": "launcher follow" + }, + { + "file": "launcher.js", + "title": "launcher" + }, { "file": "mass+velocity+test.js", "title": "mass velocity test" @@ -538,10 +684,18 @@ "file": "quadtree+-+ids.js", "title": "quadtree - ids" }, + { + "file": "ship+trail.js", + "title": "ship trail" + }, { "file": "shoot+the+pointer.js", "title": "shoot the pointer" }, + { + "file": "snake.js", + "title": "snake" + }, { "file": "sprite+bounds.js", "title": "sprite bounds" @@ -640,12 +794,20 @@ "file": "animated+tiling+sprite.js", "title": "animated tiling sprite" }, + { + "file": "colliding+with+tiling+sprite.js", + "title": "colliding with tiling sprite" + }, { "file": "tiling+sprite.js", "title": "tiling sprite" } ], "tilemaps": [ + { + "file": "create+from+objects.js", + "title": "create from objects" + }, { "file": "fill+tiles.js", "title": "fill tiles" @@ -674,9 +836,39 @@ "file": "sci+fly.js", "title": "sci fly" }, + { + "file": "shuffle+tiles.js", + "title": "shuffle tiles" + }, { "file": "swap+tiles.js", "title": "swap tiles" + }, + { + "file": "tile+callbacks.js", + "title": "tile callbacks" + } + ], + "time": [ + { + "file": "basic+looped+event.js", + "title": "basic looped event" + }, + { + "file": "basic+repeat+event.js", + "title": "basic repeat event" + }, + { + "file": "basic+timed+event.js", + "title": "basic timed event" + }, + { + "file": "remove+event.js", + "title": "remove event" + }, + { + "file": "timed+slideshow.js", + "title": "timed slideshow" } ], "tweens": [ @@ -712,6 +904,14 @@ "file": "pause+tween.js", "title": "pause tween" }, + { + "file": "tween+loop+event.js", + "title": "tween loop event" + }, + { + "file": "tween+relative.js", + "title": "tween relative" + }, { "file": "tween+several+properties.js", "title": "tween several properties" diff --git a/examples/_site/js/jquery-2.0.3.min.map b/examples/_site/js/jquery-2.0.3.min.map new file mode 100644 index 00000000..43e3e2fa --- /dev/null +++ b/examples/_site/js/jquery-2.0.3.min.map @@ -0,0 +1 @@ +{"version":3,"file":"jquery.min.js","sources":["jquery.js"],"names":["window","undefined","rootjQuery","readyList","core_strundefined","location","document","docElem","documentElement","_jQuery","jQuery","_$","$","class2type","core_deletedIds","core_version","core_concat","concat","core_push","push","core_slice","slice","core_indexOf","indexOf","core_toString","toString","core_hasOwn","hasOwnProperty","core_trim","trim","selector","context","fn","init","core_pnum","source","core_rnotwhite","rquickExpr","rsingleTag","rmsPrefix","rdashAlpha","fcamelCase","all","letter","toUpperCase","completed","removeEventListener","ready","prototype","jquery","constructor","match","elem","this","charAt","length","exec","find","merge","parseHTML","nodeType","ownerDocument","test","isPlainObject","isFunction","attr","getElementById","parentNode","makeArray","toArray","call","get","num","pushStack","elems","ret","prevObject","each","callback","args","promise","done","apply","arguments","first","eq","last","i","len","j","map","end","sort","splice","extend","options","name","src","copy","copyIsArray","clone","target","deep","isArray","expando","Math","random","replace","noConflict","isReady","readyWait","holdReady","hold","wait","resolveWith","trigger","off","obj","type","Array","isWindow","isNumeric","isNaN","parseFloat","isFinite","String","e","isEmptyObject","error","msg","Error","data","keepScripts","parsed","scripts","createElement","buildFragment","remove","childNodes","parseJSON","JSON","parse","parseXML","xml","tmp","DOMParser","parseFromString","getElementsByTagName","noop","globalEval","code","script","indirect","eval","text","head","appendChild","removeChild","camelCase","string","nodeName","toLowerCase","value","isArraylike","arr","results","Object","inArray","second","l","grep","inv","retVal","arg","guid","proxy","access","key","chainable","emptyGet","raw","bulk","now","Date","swap","old","style","Deferred","readyState","setTimeout","addEventListener","split","support","cachedruns","Expr","getText","isXML","compile","outermostContext","sortInput","setDocument","documentIsHTML","rbuggyQSA","rbuggyMatches","matches","contains","preferredDoc","dirruns","classCache","createCache","tokenCache","compilerCache","hasDuplicate","sortOrder","a","b","strundefined","MAX_NEGATIVE","hasOwn","pop","push_native","booleans","whitespace","characterEncoding","identifier","attributes","pseudos","rtrim","RegExp","rcomma","rcombinators","rsibling","rattributeQuotes","rpseudo","ridentifier","matchExpr","ID","CLASS","TAG","ATTR","PSEUDO","CHILD","bool","needsContext","rnative","rinputs","rheader","rescape","runescape","funescape","_","escaped","escapedWhitespace","high","fromCharCode","els","Sizzle","seed","m","groups","nid","newContext","newSelector","id","getElementsByClassName","qsa","tokenize","getAttribute","setAttribute","toSelector","join","querySelectorAll","qsaError","removeAttribute","select","keys","cache","cacheLength","shift","markFunction","assert","div","addHandle","attrs","handler","attrHandle","siblingCheck","cur","diff","sourceIndex","nextSibling","createInputPseudo","createButtonPseudo","createPositionalPseudo","argument","matchIndexes","node","doc","parent","defaultView","attachEvent","top","className","createComment","innerHTML","firstChild","getById","getElementsByName","filter","attrId","getAttributeNode","tag","input","matchesSelector","webkitMatchesSelector","mozMatchesSelector","oMatchesSelector","msMatchesSelector","disconnectedMatch","compareDocumentPosition","adown","bup","compare","sortDetached","aup","ap","bp","unshift","expr","elements","val","specified","uniqueSort","duplicates","detectDuplicates","sortStable","textContent","nodeValue","selectors","createPseudo","relative",">","dir"," ","+","~","preFilter","excess","unquoted","nodeNameSelector","pattern","operator","check","result","what","simple","forward","ofType","outerCache","nodeIndex","start","useCache","lastChild","pseudo","setFilters","idx","matched","not","matcher","unmatched","has","innerText","lang","elemLang","hash","root","focus","activeElement","hasFocus","href","tabIndex","enabled","disabled","checked","selected","selectedIndex","empty","header","button","even","odd","lt","gt","radio","checkbox","file","password","image","submit","reset","filters","parseOnly","tokens","soFar","preFilters","cached","addCombinator","combinator","base","checkNonElements","doneName","dirkey","elementMatcher","matchers","condense","newUnmatched","mapped","setMatcher","postFilter","postFinder","postSelector","temp","preMap","postMap","preexisting","multipleContexts","matcherIn","matcherOut","matcherFromTokens","checkContext","leadingRelative","implicitRelative","matchContext","matchAnyContext","matcherFromGroupMatchers","elementMatchers","setMatchers","matcherCachedRuns","bySet","byElement","superMatcher","expandContext","setMatched","matchedCount","outermost","contextBackup","dirrunsUnique","group","contexts","token","div1","defaultValue","unique","isXMLDoc","optionsCache","createOptions","object","flag","Callbacks","memory","fired","firing","firingStart","firingLength","firingIndex","list","stack","once","fire","stopOnFalse","self","disable","add","index","lock","locked","fireWith","func","tuples","state","always","deferred","fail","then","fns","newDefer","tuple","action","returned","resolve","reject","progress","notify","pipe","stateString","when","subordinate","resolveValues","remaining","updateFunc","values","progressValues","notifyWith","progressContexts","resolveContexts","fragment","createDocumentFragment","opt","checkOn","optSelected","reliableMarginRight","boxSizingReliable","pixelPosition","noCloneChecked","cloneNode","optDisabled","radioValue","checkClone","focusinBubbles","backgroundClip","clearCloneStyle","container","marginDiv","divReset","body","cssText","zoom","boxSizing","offsetWidth","getComputedStyle","width","marginRight","data_user","data_priv","rbrace","rmultiDash","Data","defineProperty","uid","accepts","owner","descriptor","unlock","defineProperties","set","prop","stored","camel","hasData","discard","acceptData","removeData","_data","_removeData","dataAttr","camelKey","queue","dequeue","startLength","hooks","_queueHooks","next","stop","setter","delay","time","fx","speeds","timeout","clearTimeout","clearQueue","count","defer","nodeHook","boolHook","rclass","rreturn","rfocusable","removeAttr","removeProp","propFix","addClass","classes","clazz","proceed","removeClass","toggleClass","stateVal","classNames","hasClass","valHooks","option","one","max","optionSet","nType","attrHooks","propName","attrNames","for","class","notxml","propHooks","hasAttribute","getter","rkeyEvent","rmouseEvent","rfocusMorph","rtypenamespace","returnTrue","returnFalse","safeActiveElement","err","event","global","types","handleObjIn","eventHandle","events","t","handleObj","special","handlers","namespaces","origType","elemData","handle","triggered","dispatch","delegateType","bindType","namespace","delegateCount","setup","mappedTypes","origCount","teardown","removeEvent","onlyHandlers","bubbleType","ontype","eventPath","Event","isTrigger","namespace_re","noBubble","parentWindow","isPropagationStopped","preventDefault","isDefaultPrevented","_default","fix","handlerQueue","delegateTarget","preDispatch","currentTarget","isImmediatePropagationStopped","stopPropagation","postDispatch","sel","props","fixHooks","keyHooks","original","which","charCode","keyCode","mouseHooks","eventDoc","pageX","clientX","scrollLeft","clientLeft","pageY","clientY","scrollTop","clientTop","originalEvent","fixHook","load","blur","click","beforeunload","returnValue","simulate","bubble","isSimulated","defaultPrevented","getPreventDefault","timeStamp","stopImmediatePropagation","mouseenter","mouseleave","orig","related","relatedTarget","attaches","on","origFn","triggerHandler","isSimple","rparentsprev","rneedsContext","guaranteedUnique","children","contents","prev","targets","winnow","is","closest","pos","prevAll","addBack","sibling","parents","parentsUntil","until","nextAll","nextUntil","prevUntil","siblings","contentDocument","reverse","truncate","n","qualifier","rxhtmlTag","rtagName","rhtml","rnoInnerhtml","manipulation_rcheckableType","rchecked","rscriptType","rscriptTypeMasked","rcleanScript","wrapMap","thead","col","tr","td","optgroup","tbody","tfoot","colgroup","caption","th","append","createTextNode","domManip","manipulationTarget","prepend","insertBefore","before","after","keepData","cleanData","getAll","setGlobalEval","dataAndEvents","deepDataAndEvents","html","replaceWith","detach","allowIntersection","hasScripts","iNoClone","disableScript","restoreScript","_evalUrl","appendTo","prependTo","insertAfter","replaceAll","insert","srcElements","destElements","inPage","fixInput","cloneCopyEvent","selection","wrap","nodes","url","ajax","dataType","async","throws","content","refElements","dest","pdataOld","pdataCur","udataOld","udataCur","wrapAll","firstElementChild","wrapInner","unwrap","curCSS","iframe","rdisplayswap","rmargin","rnumsplit","rnumnonpx","rrelNum","elemdisplay","BODY","cssShow","position","visibility","display","cssNormalTransform","letterSpacing","fontWeight","cssExpand","cssPrefixes","vendorPropName","capName","origName","isHidden","el","css","getStyles","showHide","show","hidden","css_defaultDisplay","styles","hide","toggle","cssHooks","opacity","computed","cssNumber","columnCount","fillOpacity","lineHeight","order","orphans","widows","zIndex","cssProps","float","extra","_computed","minWidth","maxWidth","getPropertyValue","setPositiveNumber","subtract","augmentWidthOrHeight","isBorderBox","getWidthOrHeight","valueIsBorderBox","offsetHeight","actualDisplay","contentWindow","write","close","visible","margin","padding","border","prefix","suffix","expand","expanded","parts","r20","rbracket","rCRLF","rsubmitterTypes","rsubmittable","serialize","param","serializeArray","traditional","s","encodeURIComponent","ajaxSettings","buildParams","v","hover","fnOver","fnOut","bind","unbind","delegate","undelegate","ajaxLocParts","ajaxLocation","ajax_nonce","ajax_rquery","rhash","rts","rheaders","rlocalProtocol","rnoContent","rprotocol","rurl","_load","prefilters","transports","allTypes","addToPrefiltersOrTransports","structure","dataTypeExpression","dataTypes","inspectPrefiltersOrTransports","originalOptions","jqXHR","inspected","seekingTransport","inspect","prefilterOrFactory","dataTypeOrTransport","ajaxExtend","flatOptions","params","response","responseText","complete","status","active","lastModified","etag","isLocal","processData","contentType","*","json","responseFields","converters","* text","text html","text json","text xml","ajaxSetup","settings","ajaxPrefilter","ajaxTransport","transport","cacheURL","responseHeadersString","responseHeaders","timeoutTimer","fireGlobals","callbackContext","globalEventContext","completeDeferred","statusCode","requestHeaders","requestHeadersNames","strAbort","getResponseHeader","getAllResponseHeaders","setRequestHeader","lname","overrideMimeType","mimeType","abort","statusText","finalText","success","method","crossDomain","hasContent","ifModified","headers","beforeSend","send","nativeStatusText","responses","isSuccess","modified","ajaxHandleResponses","ajaxConvert","rejectWith","getJSON","getScript","ct","finalDataType","firstDataType","conv2","current","conv","dataFilter","text script","charset","scriptCharset","evt","oldCallbacks","rjsonp","jsonp","jsonpCallback","originalSettings","callbackName","overwritten","responseContainer","jsonProp","xhr","XMLHttpRequest","xhrSupported","xhrSuccessStatus",1223,"xhrId","xhrCallbacks","ActiveXObject","cors","open","username","xhrFields","onload","onerror","fxNow","timerId","rfxtypes","rfxnum","rrun","animationPrefilters","defaultPrefilter","tweeners","tween","createTween","unit","scale","maxIterations","createFxNow","animation","collection","Animation","properties","stopped","tick","currentTime","startTime","duration","percent","tweens","run","opts","specialEasing","originalProperties","Tween","easing","gotoEnd","propFilter","timer","anim","tweener","prefilter","oldfire","dataShow","unqueued","overflow","overflowX","overflowY","eased","step","cssFn","speed","animate","genFx","fadeTo","to","optall","doAnimation","finish","stopQueue","timers","includeWidth","height","slideDown","slideUp","slideToggle","fadeIn","fadeOut","fadeToggle","linear","p","swing","cos","PI","interval","setInterval","clearInterval","slow","fast","animated","offset","setOffset","win","box","left","getBoundingClientRect","getWindow","pageYOffset","pageXOffset","curPosition","curLeft","curCSSTop","curTop","curOffset","curCSSLeft","calculatePosition","curElem","using","offsetParent","parentOffset","scrollTo","Height","Width","defaultExtra","funcName","size","andSelf","module","exports","define","amd"],"mappings":";;;CAaA,SAAWA,EAAQC,WAOnB,GAECC,GAGAC,EAIAC,QAA2BH,WAG3BI,EAAWL,EAAOK,SAClBC,EAAWN,EAAOM,SAClBC,EAAUD,EAASE,gBAGnBC,EAAUT,EAAOU,OAGjBC,EAAKX,EAAOY,EAGZC,KAGAC,KAEAC,EAAe,QAGfC,EAAcF,EAAgBG,OAC9BC,EAAYJ,EAAgBK,KAC5BC,EAAaN,EAAgBO,MAC7BC,EAAeR,EAAgBS,QAC/BC,EAAgBX,EAAWY,SAC3BC,EAAcb,EAAWc,eACzBC,EAAYb,EAAac,KAGzBnB,EAAS,SAAUoB,EAAUC,GAE5B,MAAO,IAAIrB,GAAOsB,GAAGC,KAAMH,EAAUC,EAAS7B,IAI/CgC,EAAY,sCAAsCC,OAGlDC,EAAiB,OAKjBC,EAAa,sCAGbC,EAAa,6BAGbC,EAAY,QACZC,EAAa,eAGbC,EAAa,SAAUC,EAAKC,GAC3B,MAAOA,GAAOC,eAIfC,EAAY,WACXvC,EAASwC,oBAAqB,mBAAoBD,GAAW,GAC7D7C,EAAO8C,oBAAqB,OAAQD,GAAW,GAC/CnC,EAAOqC,QAGTrC,GAAOsB,GAAKtB,EAAOsC,WAElBC,OAAQlC,EAERmC,YAAaxC,EACbuB,KAAM,SAAUH,EAAUC,EAAS7B,GAClC,GAAIiD,GAAOC,CAGX,KAAMtB,EACL,MAAOuB,KAIR,IAAyB,gBAAbvB,GAAwB,CAUnC,GAPCqB,EAF2B,MAAvBrB,EAASwB,OAAO,IAAyD,MAA3CxB,EAASwB,OAAQxB,EAASyB,OAAS,IAAezB,EAASyB,QAAU,GAE7F,KAAMzB,EAAU,MAGlBO,EAAWmB,KAAM1B,IAIrBqB,IAAUA,EAAM,IAAOpB,EA+CrB,OAAMA,GAAWA,EAAQkB,QACtBlB,GAAW7B,GAAauD,KAAM3B,GAKhCuB,KAAKH,YAAanB,GAAU0B,KAAM3B,EAlDzC,IAAKqB,EAAM,GAAK,CAWf,GAVApB,EAAUA,YAAmBrB,GAASqB,EAAQ,GAAKA,EAGnDrB,EAAOgD,MAAOL,KAAM3C,EAAOiD,UAC1BR,EAAM,GACNpB,GAAWA,EAAQ6B,SAAW7B,EAAQ8B,eAAiB9B,EAAUzB,GACjE,IAIIgC,EAAWwB,KAAMX,EAAM,KAAQzC,EAAOqD,cAAehC,GACzD,IAAMoB,IAASpB,GAETrB,EAAOsD,WAAYX,KAAMF,IAC7BE,KAAMF,GAASpB,EAASoB,IAIxBE,KAAKY,KAAMd,EAAOpB,EAASoB,GAK9B,OAAOE,MAgBP,MAZAD,GAAO9C,EAAS4D,eAAgBf,EAAM,IAIjCC,GAAQA,EAAKe,aAEjBd,KAAKE,OAAS,EACdF,KAAK,GAAKD,GAGXC,KAAKtB,QAAUzB,EACf+C,KAAKvB,SAAWA,EACTuB,KAcH,MAAKvB,GAAS8B,UACpBP,KAAKtB,QAAUsB,KAAK,GAAKvB,EACzBuB,KAAKE,OAAS,EACPF,MAII3C,EAAOsD,WAAYlC,GACvB5B,EAAW6C,MAAOjB,IAGrBA,EAASA,WAAa7B,YAC1BoD,KAAKvB,SAAWA,EAASA,SACzBuB,KAAKtB,QAAUD,EAASC,SAGlBrB,EAAO0D,UAAWtC,EAAUuB,QAIpCvB,SAAU,GAGVyB,OAAQ,EAERc,QAAS,WACR,MAAOjD,GAAWkD,KAAMjB,OAKzBkB,IAAK,SAAUC,GACd,MAAc,OAAPA,EAGNnB,KAAKgB,UAGG,EAANG,EAAUnB,KAAMA,KAAKE,OAASiB,GAAQnB,KAAMmB,IAKhDC,UAAW,SAAUC,GAGpB,GAAIC,GAAMjE,EAAOgD,MAAOL,KAAKH,cAAewB,EAO5C,OAJAC,GAAIC,WAAavB,KACjBsB,EAAI5C,QAAUsB,KAAKtB,QAGZ4C,GAMRE,KAAM,SAAUC,EAAUC,GACzB,MAAOrE,GAAOmE,KAAMxB,KAAMyB,EAAUC,IAGrChC,MAAO,SAAUf,GAIhB,MAFAtB,GAAOqC,MAAMiC,UAAUC,KAAMjD,GAEtBqB,MAGRhC,MAAO,WACN,MAAOgC,MAAKoB,UAAWrD,EAAW8D,MAAO7B,KAAM8B,aAGhDC,MAAO,WACN,MAAO/B,MAAKgC,GAAI,IAGjBC,KAAM,WACL,MAAOjC,MAAKgC,GAAI,KAGjBA,GAAI,SAAUE,GACb,GAAIC,GAAMnC,KAAKE,OACdkC,GAAKF,GAAU,EAAJA,EAAQC,EAAM,EAC1B,OAAOnC,MAAKoB,UAAWgB,GAAK,GAASD,EAAJC,GAAYpC,KAAKoC,SAGnDC,IAAK,SAAUZ,GACd,MAAOzB,MAAKoB,UAAW/D,EAAOgF,IAAIrC,KAAM,SAAUD,EAAMmC,GACvD,MAAOT,GAASR,KAAMlB,EAAMmC,EAAGnC,OAIjCuC,IAAK,WACJ,MAAOtC,MAAKuB,YAAcvB,KAAKH,YAAY,OAK5C/B,KAAMD,EACN0E,QAASA,KACTC,UAAWA,QAIZnF,EAAOsB,GAAGC,KAAKe,UAAYtC,EAAOsB,GAElCtB,EAAOoF,OAASpF,EAAOsB,GAAG8D,OAAS,WAClC,GAAIC,GAASC,EAAMC,EAAKC,EAAMC,EAAaC,EAC1CC,EAASlB,UAAU,OACnBI,EAAI,EACJhC,EAAS4B,UAAU5B,OACnB+C,GAAO,CAqBR,KAlBuB,iBAAXD,KACXC,EAAOD,EACPA,EAASlB,UAAU,OAEnBI,EAAI,GAIkB,gBAAXc,IAAwB3F,EAAOsD,WAAWqC,KACrDA,MAII9C,IAAWgC,IACfc,EAAShD,OACPkC,GAGShC,EAAJgC,EAAYA,IAEnB,GAAmC,OAA7BQ,EAAUZ,UAAWI,IAE1B,IAAMS,IAAQD,GACbE,EAAMI,EAAQL,GACdE,EAAOH,EAASC,GAGXK,IAAWH,IAKXI,GAAQJ,IAAUxF,EAAOqD,cAAcmC,KAAUC,EAAczF,EAAO6F,QAAQL,MAC7EC,GACJA,GAAc,EACdC,EAAQH,GAAOvF,EAAO6F,QAAQN,GAAOA,MAGrCG,EAAQH,GAAOvF,EAAOqD,cAAckC,GAAOA,KAI5CI,EAAQL,GAAStF,EAAOoF,OAAQQ,EAAMF,EAAOF,IAGlCA,IAASjG,YACpBoG,EAAQL,GAASE,GAOrB,OAAOG,IAGR3F,EAAOoF,QAENU,QAAS,UAAazF,EAAe0F,KAAKC,UAAWC,QAAS,MAAO,IAErEC,WAAY,SAAUN,GASrB,MARKtG,GAAOY,IAAMF,IACjBV,EAAOY,EAAID,GAGP2F,GAAQtG,EAAOU,SAAWA,IAC9BV,EAAOU,OAASD,GAGVC,GAIRmG,SAAS,EAITC,UAAW,EAGXC,UAAW,SAAUC,GACfA,EACJtG,EAAOoG,YAEPpG,EAAOqC,OAAO,IAKhBA,MAAO,SAAUkE,IAGXA,KAAS,IAASvG,EAAOoG,UAAYpG,EAAOmG,WAKjDnG,EAAOmG,SAAU,EAGZI,KAAS,KAAUvG,EAAOoG,UAAY,IAK3C3G,EAAU+G,YAAa5G,GAAYI,IAG9BA,EAAOsB,GAAGmF,SACdzG,EAAQJ,GAAW6G,QAAQ,SAASC,IAAI,YAO1CpD,WAAY,SAAUqD,GACrB,MAA4B,aAArB3G,EAAO4G,KAAKD,IAGpBd,QAASgB,MAAMhB,QAEfiB,SAAU,SAAUH,GACnB,MAAc,OAAPA,GAAeA,IAAQA,EAAIrH,QAGnCyH,UAAW,SAAUJ,GACpB,OAAQK,MAAOC,WAAWN,KAAUO,SAAUP,IAG/CC,KAAM,SAAUD,GACf,MAAY,OAAPA,EACWA,EAARQ,GAGc,gBAARR,IAAmC,kBAARA,GACxCxG,EAAYW,EAAc8C,KAAK+C,KAAU,eAClCA,IAGTtD,cAAe,SAAUsD,GAKxB,GAA4B,WAAvB3G,EAAO4G,KAAMD,IAAsBA,EAAIzD,UAAYlD,EAAO8G,SAAUH,GACxE,OAAO,CAOR,KACC,GAAKA,EAAInE,cACNxB,EAAY4C,KAAM+C,EAAInE,YAAYF,UAAW,iBAC/C,OAAO,EAEP,MAAQ8E,GACT,OAAO,EAKR,OAAO,GAGRC,cAAe,SAAUV,GACxB,GAAIrB,EACJ,KAAMA,IAAQqB,GACb,OAAO,CAER,QAAO,GAGRW,MAAO,SAAUC,GAChB,KAAUC,OAAOD,IAMlBtE,UAAW,SAAUwE,EAAMpG,EAASqG,GACnC,IAAMD,GAAwB,gBAATA,GACpB,MAAO,KAEgB,kBAAZpG,KACXqG,EAAcrG,EACdA,GAAU,GAEXA,EAAUA,GAAWzB,CAErB,IAAI+H,GAAS/F,EAAWkB,KAAM2E,GAC7BG,GAAWF,KAGZ,OAAKC,IACKtG,EAAQwG,cAAeF,EAAO,MAGxCA,EAAS3H,EAAO8H,eAAiBL,GAAQpG,EAASuG,GAE7CA,GACJ5H,EAAQ4H,GAAUG,SAGZ/H,EAAOgD,SAAW2E,EAAOK,cAGjCC,UAAWC,KAAKC,MAGhBC,SAAU,SAAUX,GACnB,GAAIY,GAAKC,CACT,KAAMb,GAAwB,gBAATA,GACpB,MAAO,KAIR,KACCa,EAAM,GAAIC,WACVF,EAAMC,EAAIE,gBAAiBf,EAAO,YACjC,MAAQL,GACTiB,EAAM9I,UAMP,QAHM8I,GAAOA,EAAII,qBAAsB,eAAgB5F,SACtD7C,EAAOsH,MAAO,gBAAkBG,GAE1BY,GAGRK,KAAM,aAGNC,WAAY,SAAUC,GACrB,GAAIC,GACFC,EAAWC,IAEbH,GAAO5I,EAAOmB,KAAMyH,GAEfA,IAIgC,IAA/BA,EAAK/H,QAAQ,eACjBgI,EAASjJ,EAASiI,cAAc,UAChCgB,EAAOG,KAAOJ,EACdhJ,EAASqJ,KAAKC,YAAaL,GAASpF,WAAW0F,YAAaN,IAI5DC,EAAUF,KAObQ,UAAW,SAAUC,GACpB,MAAOA,GAAOpD,QAASpE,EAAW,OAAQoE,QAASnE,EAAYC,IAGhEuH,SAAU,SAAU5G,EAAM4C,GACzB,MAAO5C,GAAK4G,UAAY5G,EAAK4G,SAASC,gBAAkBjE,EAAKiE,eAI9DpF,KAAM,SAAUwC,EAAKvC,EAAUC,GAC9B,GAAImF,GACH3E,EAAI,EACJhC,EAAS8D,EAAI9D,OACbgD,EAAU4D,EAAa9C,EAExB,IAAKtC,GACJ,GAAKwB,GACJ,KAAYhD,EAAJgC,EAAYA,IAGnB,GAFA2E,EAAQpF,EAASI,MAAOmC,EAAK9B,GAAKR,GAE7BmF,KAAU,EACd,UAIF,KAAM3E,IAAK8B,GAGV,GAFA6C,EAAQpF,EAASI,MAAOmC,EAAK9B,GAAKR,GAE7BmF,KAAU,EACd,UAOH,IAAK3D,GACJ,KAAYhD,EAAJgC,EAAYA,IAGnB,GAFA2E,EAAQpF,EAASR,KAAM+C,EAAK9B,GAAKA,EAAG8B,EAAK9B,IAEpC2E,KAAU,EACd,UAIF,KAAM3E,IAAK8B,GAGV,GAFA6C,EAAQpF,EAASR,KAAM+C,EAAK9B,GAAKA,EAAG8B,EAAK9B,IAEpC2E,KAAU,EACd,KAMJ,OAAO7C,IAGRxF,KAAM,SAAU6H,GACf,MAAe,OAARA,EAAe,GAAK9H,EAAU0C,KAAMoF,IAI5CtF,UAAW,SAAUgG,EAAKC,GACzB,GAAI1F,GAAM0F,KAaV,OAXY,OAAPD,IACCD,EAAaG,OAAOF,IACxB1J,EAAOgD,MAAOiB,EACE,gBAARyF,IACLA,GAAQA,GAGXlJ,EAAUoD,KAAMK,EAAKyF,IAIhBzF,GAGR4F,QAAS,SAAUnH,EAAMgH,EAAK7E,GAC7B,MAAc,OAAP6E,EAAc,GAAK9I,EAAagD,KAAM8F,EAAKhH,EAAMmC,IAGzD7B,MAAO,SAAU0B,EAAOoF,GACvB,GAAIC,GAAID,EAAOjH,OACdgC,EAAIH,EAAM7B,OACVkC,EAAI,CAEL,IAAkB,gBAANgF,GACX,KAAYA,EAAJhF,EAAOA,IACdL,EAAOG,KAAQiF,EAAQ/E,OAGxB,OAAQ+E,EAAO/E,KAAOxF,UACrBmF,EAAOG,KAAQiF,EAAQ/E,IAMzB,OAFAL,GAAM7B,OAASgC,EAERH,GAGRsF,KAAM,SAAUhG,EAAOI,EAAU6F,GAChC,GAAIC,GACHjG,KACAY,EAAI,EACJhC,EAASmB,EAAMnB,MAKhB,KAJAoH,IAAQA,EAIIpH,EAAJgC,EAAYA,IACnBqF,IAAW9F,EAAUJ,EAAOa,GAAKA,GAC5BoF,IAAQC,GACZjG,EAAIxD,KAAMuD,EAAOa,GAInB,OAAOZ,IAIRe,IAAK,SAAUhB,EAAOI,EAAU+F,GAC/B,GAAIX,GACH3E,EAAI,EACJhC,EAASmB,EAAMnB,OACfgD,EAAU4D,EAAazF,GACvBC,IAGD,IAAK4B,EACJ,KAAYhD,EAAJgC,EAAYA,IACnB2E,EAAQpF,EAAUJ,EAAOa,GAAKA,EAAGsF,GAEnB,MAATX,IACJvF,EAAKA,EAAIpB,QAAW2G,OAMtB,KAAM3E,IAAKb,GACVwF,EAAQpF,EAAUJ,EAAOa,GAAKA,EAAGsF,GAEnB,MAATX,IACJvF,EAAKA,EAAIpB,QAAW2G,EAMvB,OAAOlJ,GAAYkE,SAAWP,IAI/BmG,KAAM,EAINC,MAAO,SAAU/I,EAAID,GACpB,GAAIiH,GAAKjE,EAAMgG,CAUf,OARwB,gBAAZhJ,KACXiH,EAAMhH,EAAID,GACVA,EAAUC,EACVA,EAAKgH,GAKAtI,EAAOsD,WAAYhC,IAKzB+C,EAAO3D,EAAWkD,KAAMa,UAAW,GACnC4F,EAAQ,WACP,MAAO/I,GAAGkD,MAAOnD,GAAWsB,KAAM0B,EAAK9D,OAAQG,EAAWkD,KAAMa,cAIjE4F,EAAMD,KAAO9I,EAAG8I,KAAO9I,EAAG8I,MAAQpK,EAAOoK,OAElCC,GAZC9K,WAiBT+K,OAAQ,SAAUtG,EAAO1C,EAAIiJ,EAAKf,EAAOgB,EAAWC,EAAUC,GAC7D,GAAI7F,GAAI,EACPhC,EAASmB,EAAMnB,OACf8H,EAAc,MAAPJ,CAGR,IAA4B,WAAvBvK,EAAO4G,KAAM2D,GAAqB,CACtCC,GAAY,CACZ,KAAM3F,IAAK0F,GACVvK,EAAOsK,OAAQtG,EAAO1C,EAAIuD,EAAG0F,EAAI1F,IAAI,EAAM4F,EAAUC,OAIhD,IAAKlB,IAAUjK,YACrBiL,GAAY,EAENxK,EAAOsD,WAAYkG,KACxBkB,GAAM,GAGFC,IAECD,GACJpJ,EAAGsC,KAAMI,EAAOwF,GAChBlI,EAAK,OAILqJ,EAAOrJ,EACPA,EAAK,SAAUoB,EAAM6H,EAAKf,GACzB,MAAOmB,GAAK/G,KAAM5D,EAAQ0C,GAAQ8G,MAKhClI,GACJ,KAAYuB,EAAJgC,EAAYA,IACnBvD,EAAI0C,EAAMa,GAAI0F,EAAKG,EAAMlB,EAAQA,EAAM5F,KAAMI,EAAMa,GAAIA,EAAGvD,EAAI0C,EAAMa,GAAI0F,IAK3E,OAAOC,GACNxG,EAGA2G,EACCrJ,EAAGsC,KAAMI,GACTnB,EAASvB,EAAI0C,EAAM,GAAIuG,GAAQE,GAGlCG,IAAKC,KAAKD,IAKVE,KAAM,SAAUpI,EAAM2C,EAASjB,EAAUC,GACxC,GAAIJ,GAAKqB,EACRyF,IAGD,KAAMzF,IAAQD,GACb0F,EAAKzF,GAAS5C,EAAKsI,MAAO1F,GAC1B5C,EAAKsI,MAAO1F,GAASD,EAASC,EAG/BrB,GAAMG,EAASI,MAAO9B,EAAM2B,MAG5B,KAAMiB,IAAQD,GACb3C,EAAKsI,MAAO1F,GAASyF,EAAKzF,EAG3B,OAAOrB,MAITjE,EAAOqC,MAAMiC,QAAU,SAAUqC,GAqBhC,MApBMlH,KAELA,EAAYO,EAAOiL,WAKU,aAAxBrL,EAASsL,WAEbC,WAAYnL,EAAOqC,QAKnBzC,EAASwL,iBAAkB,mBAAoBjJ,GAAW,GAG1D7C,EAAO8L,iBAAkB,OAAQjJ,GAAW,KAGvC1C,EAAU6E,QAASqC,IAI3B3G,EAAOmE,KAAK,gEAAgEkH,MAAM,KAAM,SAASxG,EAAGS,GACnGnF,EAAY,WAAamF,EAAO,KAAQA,EAAKiE,eAG9C,SAASE,GAAa9C,GACrB,GAAI9D,GAAS8D,EAAI9D,OAChB+D,EAAO5G,EAAO4G,KAAMD,EAErB,OAAK3G,GAAO8G,SAAUH,IACd,EAGc,IAAjBA,EAAIzD,UAAkBL,GACnB,EAGQ,UAAT+D,GAA6B,aAATA,IACb,IAAX/D,GACgB,gBAAXA,IAAuBA,EAAS,GAAOA,EAAS,IAAO8D,IAIhEnH,EAAaQ,EAAOJ,GAWpB,SAAWN,EAAQC,WAEnB,GAAIsF,GACHyG,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EACAC,EAGAC,EACAlM,EACAC,EACAkM,EACAC,EACAC,EACAC,EACAC,EAGArG,EAAU,UAAY,GAAK+E,MAC3BuB,EAAe9M,EAAOM,SACtByM,EAAU,EACV9H,EAAO,EACP+H,EAAaC,KACbC,EAAaD,KACbE,EAAgBF,KAChBG,GAAe,EACfC,EAAY,SAAUC,EAAGC,GACxB,MAAKD,KAAMC,GACVH,GAAe,EACR,GAED,GAIRI,QAAsBvN,WACtBwN,EAAe,GAAK,GAGpBC,KAAc/L,eACdyI,KACAuD,EAAMvD,EAAIuD,IACVC,EAAcxD,EAAIjJ,KAClBA,EAAOiJ,EAAIjJ,KACXE,EAAQ+I,EAAI/I,MAEZE,EAAU6I,EAAI7I,SAAW,SAAU6B,GAClC,GAAImC,GAAI,EACPC,EAAMnC,KAAKE,MACZ,MAAYiC,EAAJD,EAASA,IAChB,GAAKlC,KAAKkC,KAAOnC,EAChB,MAAOmC,EAGT,OAAO,IAGRsI,EAAW,6HAKXC,EAAa,sBAEbC,EAAoB,mCAKpBC,EAAaD,EAAkBpH,QAAS,IAAK,MAG7CsH,EAAa,MAAQH,EAAa,KAAOC,EAAoB,IAAMD,EAClE,mBAAqBA,EAAa,wCAA0CE,EAAa,QAAUF,EAAa,OAQjHI,EAAU,KAAOH,EAAoB,mEAAqEE,EAAWtH,QAAS,EAAG,GAAM,eAGvIwH,EAAYC,OAAQ,IAAMN,EAAa,8BAAgCA,EAAa,KAAM,KAE1FO,EAAaD,OAAQ,IAAMN,EAAa,KAAOA,EAAa,KAC5DQ,EAAmBF,OAAQ,IAAMN,EAAa,WAAaA,EAAa,IAAMA,EAAa,KAE3FS,EAAeH,OAAQN,EAAa,SACpCU,EAAuBJ,OAAQ,IAAMN,EAAa,gBAAkBA,EAAa,OAAQ,KAEzFW,EAAcL,OAAQF,GACtBQ,EAAkBN,OAAQ,IAAMJ,EAAa,KAE7CW,GACCC,GAAUR,OAAQ,MAAQL,EAAoB,KAC9Cc,MAAaT,OAAQ,QAAUL,EAAoB,KACnDe,IAAWV,OAAQ,KAAOL,EAAkBpH,QAAS,IAAK,MAAS,KACnEoI,KAAYX,OAAQ,IAAMH,GAC1Be,OAAcZ,OAAQ,IAAMF,GAC5Be,MAAab,OAAQ,yDAA2DN,EAC/E,+BAAiCA,EAAa,cAAgBA,EAC9D,aAAeA,EAAa,SAAU,KACvCoB,KAAYd,OAAQ,OAASP,EAAW,KAAM,KAG9CsB,aAAoBf,OAAQ,IAAMN,EAAa,mDAC9CA,EAAa,mBAAqBA,EAAa,mBAAoB,MAGrEsB,EAAU,yBAGV/M,EAAa,mCAEbgN,EAAU,sCACVC,GAAU,SAEVC,GAAU,QAGVC,GAAgBpB,OAAQ,qBAAuBN,EAAa,MAAQA,EAAa,OAAQ,MACzF2B,GAAY,SAAUC,EAAGC,EAASC,GACjC,GAAIC,GAAO,KAAOF,EAAU,KAI5B,OAAOE,KAASA,GAAQD,EACvBD,EAEO,EAAPE,EACChI,OAAOiI,aAAcD,EAAO,OAE5BhI,OAAOiI,aAA2B,MAAbD,GAAQ,GAA4B,MAAR,KAAPA,GAI9C,KACC1O,EAAK+D,MACHkF,EAAM/I,EAAMiD,KAAMwI,EAAapE,YAChCoE,EAAapE,YAId0B,EAAK0C,EAAapE,WAAWnF,QAASK,SACrC,MAAQkE,IACT3G,GAAS+D,MAAOkF,EAAI7G,OAGnB,SAAU8C,EAAQ0J,GACjBnC,EAAY1I,MAAOmB,EAAQhF,EAAMiD,KAAKyL,KAKvC,SAAU1J,EAAQ0J,GACjB,GAAItK,GAAIY,EAAO9C,OACdgC,EAAI,CAEL,OAASc,EAAOZ,KAAOsK,EAAIxK,MAC3Bc,EAAO9C,OAASkC,EAAI,IAKvB,QAASuK,IAAQlO,EAAUC,EAASsI,EAAS4F,GAC5C,GAAI9M,GAAOC,EAAM8M,EAAGtM,EAEnB2B,EAAG4K,EAAQ1E,EAAK2E,EAAKC,EAAYC,CASlC,KAPOvO,EAAUA,EAAQ8B,eAAiB9B,EAAU+K,KAAmBxM,GACtEkM,EAAazK,GAGdA,EAAUA,GAAWzB,EACrB+J,EAAUA,OAEJvI,GAAgC,gBAAbA,GACxB,MAAOuI,EAGR,IAAuC,KAAjCzG,EAAW7B,EAAQ6B,WAAgC,IAAbA,EAC3C,QAGD,IAAK6I,IAAmBwD,EAAO,CAG9B,GAAM9M,EAAQd,EAAWmB,KAAM1B,GAE9B,GAAMoO,EAAI/M,EAAM,IACf,GAAkB,IAAbS,EAAiB,CAIrB,GAHAR,EAAOrB,EAAQmC,eAAgBgM,IAG1B9M,IAAQA,EAAKe,WAQjB,MAAOkG,EALP,IAAKjH,EAAKmN,KAAOL,EAEhB,MADA7F,GAAQlJ,KAAMiC,GACPiH,MAOT,IAAKtI,EAAQ8B,gBAAkBT,EAAOrB,EAAQ8B,cAAcK,eAAgBgM,KAC3ErD,EAAU9K,EAASqB,IAAUA,EAAKmN,KAAOL,EAEzC,MADA7F,GAAQlJ,KAAMiC,GACPiH,MAKH,CAAA,GAAKlH,EAAM,GAEjB,MADAhC,GAAK+D,MAAOmF,EAAStI,EAAQoH,qBAAsBrH,IAC5CuI,CAGD,KAAM6F,EAAI/M,EAAM,KAAO6I,EAAQwE,wBAA0BzO,EAAQyO,uBAEvE,MADArP,GAAK+D,MAAOmF,EAAStI,EAAQyO,uBAAwBN,IAC9C7F,EAKT,GAAK2B,EAAQyE,OAAS/D,IAAcA,EAAU5I,KAAMhC,IAAc,CASjE,GARAsO,EAAM3E,EAAMjF,EACZ6J,EAAatO,EACbuO,EAA2B,IAAb1M,GAAkB9B,EAMd,IAAb8B,GAAqD,WAAnC7B,EAAQiI,SAASC,cAA6B,CACpEkG,EAASO,GAAU5O,IAEb2J,EAAM1J,EAAQ4O,aAAa,OAChCP,EAAM3E,EAAI9E,QAAS4I,GAAS,QAE5BxN,EAAQ6O,aAAc,KAAMR,GAE7BA,EAAM,QAAUA,EAAM,MAEtB7K,EAAI4K,EAAO5M,MACX,OAAQgC,IACP4K,EAAO5K,GAAK6K,EAAMS,GAAYV,EAAO5K,GAEtC8K,GAAa9B,EAASzK,KAAMhC,IAAcC,EAAQoC,YAAcpC,EAChEuO,EAAcH,EAAOW,KAAK,KAG3B,GAAKR,EACJ,IAIC,MAHAnP,GAAK+D,MAAOmF,EACXgG,EAAWU,iBAAkBT,IAEvBjG,EACN,MAAM2G,IACN,QACKvF,GACL1J,EAAQkP,gBAAgB,QAQ7B,MAAOC,IAAQpP,EAAS6E,QAASwH,EAAO,MAAQpM,EAASsI,EAAS4F,GASnE,QAAShD,MACR,GAAIkE,KAEJ,SAASC,GAAOnG,EAAKf,GAMpB,MAJKiH,GAAKhQ,KAAM8J,GAAO,KAAQiB,EAAKmF,mBAE5BD,GAAOD,EAAKG,SAEZF,EAAOnG,GAAQf,EAExB,MAAOkH,GAOR,QAASG,IAAcvP,GAEtB,MADAA,GAAIwE,IAAY,EACTxE,EAOR,QAASwP,IAAQxP,GAChB,GAAIyP,GAAMnR,EAASiI,cAAc,MAEjC,KACC,QAASvG,EAAIyP,GACZ,MAAO3J,GACR,OAAO,EACN,QAEI2J,EAAItN,YACRsN,EAAItN,WAAW0F,YAAa4H,GAG7BA,EAAM,MASR,QAASC,IAAWC,EAAOC,GAC1B,GAAIxH,GAAMuH,EAAM5F,MAAM,KACrBxG,EAAIoM,EAAMpO,MAEX,OAAQgC,IACP2G,EAAK2F,WAAYzH,EAAI7E,IAAOqM,EAU9B,QAASE,IAAcxE,EAAGC,GACzB,GAAIwE,GAAMxE,GAAKD,EACd0E,EAAOD,GAAsB,IAAfzE,EAAE1J,UAAiC,IAAf2J,EAAE3J,YAChC2J,EAAE0E,aAAexE,KACjBH,EAAE2E,aAAexE,EAGtB,IAAKuE,EACJ,MAAOA,EAIR,IAAKD,EACJ,MAASA,EAAMA,EAAIG,YAClB,GAAKH,IAAQxE,EACZ,MAAO,EAKV,OAAOD,GAAI,EAAI,GAOhB,QAAS6E,IAAmB7K,GAC3B,MAAO,UAAUlE,GAChB,GAAI4C,GAAO5C,EAAK4G,SAASC,aACzB,OAAgB,UAATjE,GAAoB5C,EAAKkE,OAASA,GAQ3C,QAAS8K,IAAoB9K,GAC5B,MAAO,UAAUlE,GAChB,GAAI4C,GAAO5C,EAAK4G,SAASC,aACzB,QAAiB,UAATjE,GAA6B,WAATA,IAAsB5C,EAAKkE,OAASA,GAQlE,QAAS+K,IAAwBrQ,GAChC,MAAOuP,IAAa,SAAUe,GAE7B,MADAA,IAAYA,EACLf,GAAa,SAAUtB,EAAMrD,GACnC,GAAInH,GACH8M,EAAevQ,KAAQiO,EAAK1M,OAAQ+O,GACpC/M,EAAIgN,EAAahP,MAGlB,OAAQgC,IACF0K,EAAOxK,EAAI8M,EAAahN,MAC5B0K,EAAKxK,KAAOmH,EAAQnH,GAAKwK,EAAKxK,SAWnC2G,EAAQ4D,GAAO5D,MAAQ,SAAUhJ,GAGhC,GAAI5C,GAAkB4C,IAASA,EAAKS,eAAiBT,GAAM5C,eAC3D,OAAOA,GAA+C,SAA7BA,EAAgBwJ,UAAsB,GAIhEgC,EAAUgE,GAAOhE,WAOjBQ,EAAcwD,GAAOxD,YAAc,SAAUgG,GAC5C,GAAIC,GAAMD,EAAOA,EAAK3O,eAAiB2O,EAAO1F,EAC7C4F,EAASD,EAAIE,WAGd,OAAKF,KAAQnS,GAA6B,IAAjBmS,EAAI7O,UAAmB6O,EAAIjS,iBAKpDF,EAAWmS,EACXlS,EAAUkS,EAAIjS,gBAGdiM,GAAkBL,EAAOqG,GAMpBC,GAAUA,EAAOE,aAAeF,IAAWA,EAAOG,KACtDH,EAAOE,YAAa,iBAAkB,WACrCpG,MASFR,EAAQiC,WAAauD,GAAO,SAAUC,GAErC,MADAA,GAAIqB,UAAY,KACRrB,EAAId,aAAa,eAO1B3E,EAAQ7C,qBAAuBqI,GAAO,SAAUC,GAE/C,MADAA,GAAI7H,YAAa6I,EAAIM,cAAc,MAC3BtB,EAAItI,qBAAqB,KAAK5F,SAIvCyI,EAAQwE,uBAAyBgB,GAAO,SAAUC,GAQjD,MAPAA,GAAIuB,UAAY,+CAIhBvB,EAAIwB,WAAWH,UAAY,IAGuB,IAA3CrB,EAAIjB,uBAAuB,KAAKjN,SAOxCyI,EAAQkH,QAAU1B,GAAO,SAAUC,GAElC,MADAlR,GAAQqJ,YAAa6H,GAAMlB,GAAK/J,GACxBiM,EAAIU,oBAAsBV,EAAIU,kBAAmB3M,GAAUjD,SAI/DyI,EAAQkH,SACZhH,EAAKzI,KAAS,GAAI,SAAU8M,EAAIxO,GAC/B,SAAYA,GAAQmC,iBAAmBsJ,GAAgBf,EAAiB,CACvE,GAAIyD,GAAInO,EAAQmC,eAAgBqM,EAGhC,OAAOL,IAAKA,EAAE/L,YAAc+L,QAG9BhE,EAAKkH,OAAW,GAAI,SAAU7C,GAC7B,GAAI8C,GAAS9C,EAAG5J,QAAS6I,GAAWC,GACpC,OAAO,UAAUrM,GAChB,MAAOA,GAAKuN,aAAa,QAAU0C,YAM9BnH,GAAKzI,KAAS,GAErByI,EAAKkH,OAAW,GAAK,SAAU7C,GAC9B,GAAI8C,GAAS9C,EAAG5J,QAAS6I,GAAWC,GACpC,OAAO,UAAUrM,GAChB,GAAIoP,SAAcpP,GAAKkQ,mBAAqB9F,GAAgBpK,EAAKkQ,iBAAiB,KAClF,OAAOd,IAAQA,EAAKtI,QAAUmJ,KAMjCnH,EAAKzI,KAAU,IAAIuI,EAAQ7C,qBAC1B,SAAUoK,EAAKxR,GACd,aAAYA,GAAQoH,uBAAyBqE,EACrCzL,EAAQoH,qBAAsBoK,GADtC,WAID,SAAUA,EAAKxR,GACd,GAAIqB,GACH4F,KACAzD,EAAI,EACJ8E,EAAUtI,EAAQoH,qBAAsBoK,EAGzC,IAAa,MAARA,EAAc,CAClB,MAASnQ,EAAOiH,EAAQ9E,KACA,IAAlBnC,EAAKQ,UACToF,EAAI7H,KAAMiC,EAIZ,OAAO4F,GAER,MAAOqB,IAIT6B,EAAKzI,KAAY,MAAIuI,EAAQwE,wBAA0B,SAAUsC,EAAW/Q,GAC3E,aAAYA,GAAQyO,yBAA2BhD,GAAgBf,EACvD1K,EAAQyO,uBAAwBsC,GADxC,WAWDnG,KAOAD,MAEMV,EAAQyE,IAAMrB,EAAQtL,KAAM2O,EAAI1B,qBAGrCS,GAAO,SAAUC,GAMhBA,EAAIuB,UAAY,iDAIVvB,EAAIV,iBAAiB,cAAcxN,QACxCmJ,EAAUvL,KAAM,MAAQ2M,EAAa,aAAeD,EAAW,KAM1D4D,EAAIV,iBAAiB,YAAYxN,QACtCmJ,EAAUvL,KAAK,cAIjBqQ,GAAO,SAAUC,GAOhB,GAAI+B,GAAQf,EAAIlK,cAAc,QAC9BiL,GAAM5C,aAAc,OAAQ,UAC5Ba,EAAI7H,YAAa4J,GAAQ5C,aAAc,IAAK,IAEvCa,EAAIV,iBAAiB,WAAWxN,QACpCmJ,EAAUvL,KAAM,SAAW2M,EAAa,gBAKnC2D,EAAIV,iBAAiB,YAAYxN,QACtCmJ,EAAUvL,KAAM,WAAY,aAI7BsQ,EAAIV,iBAAiB,QACrBrE,EAAUvL,KAAK,YAIX6K,EAAQyH,gBAAkBrE,EAAQtL,KAAO8I,EAAUrM,EAAQmT,uBAChEnT,EAAQoT,oBACRpT,EAAQqT,kBACRrT,EAAQsT,qBAERrC,GAAO,SAAUC,GAGhBzF,EAAQ8H,kBAAoBlH,EAAQtI,KAAMmN,EAAK,OAI/C7E,EAAQtI,KAAMmN,EAAK,aACnB9E,EAAcxL,KAAM,KAAM+M,KAI5BxB,EAAYA,EAAUnJ,QAAc6K,OAAQ1B,EAAUoE,KAAK,MAC3DnE,EAAgBA,EAAcpJ,QAAc6K,OAAQzB,EAAcmE,KAAK,MAQvEjE,EAAWuC,EAAQtL,KAAMvD,EAAQsM,WAActM,EAAQwT,wBACtD,SAAUzG,EAAGC,GACZ,GAAIyG,GAAuB,IAAf1G,EAAE1J,SAAiB0J,EAAE9M,gBAAkB8M,EAClD2G,EAAM1G,GAAKA,EAAEpJ,UACd,OAAOmJ,KAAM2G,MAAWA,GAAwB,IAAjBA,EAAIrQ,YAClCoQ,EAAMnH,SACLmH,EAAMnH,SAAUoH,GAChB3G,EAAEyG,yBAA8D,GAAnCzG,EAAEyG,wBAAyBE,MAG3D,SAAU3G,EAAGC,GACZ,GAAKA,EACJ,MAASA,EAAIA,EAAEpJ,WACd,GAAKoJ,IAAMD,EACV,OAAO,CAIV,QAAO,GAOTD,EAAY9M,EAAQwT,wBACpB,SAAUzG,EAAGC,GAGZ,GAAKD,IAAMC,EAEV,MADAH,IAAe,EACR,CAGR,IAAI8G,GAAU3G,EAAEwG,yBAA2BzG,EAAEyG,yBAA2BzG,EAAEyG,wBAAyBxG,EAEnG,OAAK2G,GAEW,EAAVA,IACFlI,EAAQmI,cAAgB5G,EAAEwG,wBAAyBzG,KAAQ4G,EAGxD5G,IAAMmF,GAAO5F,EAASC,EAAcQ,GACjC,GAEHC,IAAMkF,GAAO5F,EAASC,EAAcS,GACjC,EAIDhB,EACJhL,EAAQ+C,KAAMiI,EAAWe,GAAM/L,EAAQ+C,KAAMiI,EAAWgB,GAC1D,EAGe,EAAV2G,EAAc,GAAK,EAIpB5G,EAAEyG,wBAA0B,GAAK,GAEzC,SAAUzG,EAAGC,GACZ,GAAIwE,GACHxM,EAAI,EACJ6O,EAAM9G,EAAEnJ,WACR8P,EAAM1G,EAAEpJ,WACRkQ,GAAO/G,GACPgH,GAAO/G,EAGR,IAAKD,IAAMC,EAEV,MADAH,IAAe,EACR,CAGD,KAAMgH,IAAQH,EACpB,MAAO3G,KAAMmF,EAAM,GAClBlF,IAAMkF,EAAM,EACZ2B,EAAM,GACNH,EAAM,EACN1H,EACEhL,EAAQ+C,KAAMiI,EAAWe,GAAM/L,EAAQ+C,KAAMiI,EAAWgB,GAC1D,CAGK,IAAK6G,IAAQH,EACnB,MAAOnC,IAAcxE,EAAGC,EAIzBwE,GAAMzE,CACN,OAASyE,EAAMA,EAAI5N,WAClBkQ,EAAGE,QAASxC,EAEbA,GAAMxE,CACN,OAASwE,EAAMA,EAAI5N,WAClBmQ,EAAGC,QAASxC,EAIb,OAAQsC,EAAG9O,KAAO+O,EAAG/O,GACpBA,GAGD,OAAOA,GAENuM,GAAcuC,EAAG9O,GAAI+O,EAAG/O,IAGxB8O,EAAG9O,KAAOuH,EAAe,GACzBwH,EAAG/O,KAAOuH,EAAe,EACzB,GAGK2F,GA1UCnS,GA6UT0P,GAAOpD,QAAU,SAAU4H,EAAMC,GAChC,MAAOzE,IAAQwE,EAAM,KAAM,KAAMC,IAGlCzE,GAAOyD,gBAAkB,SAAUrQ,EAAMoR,GASxC,IAPOpR,EAAKS,eAAiBT,KAAW9C,GACvCkM,EAAapJ,GAIdoR,EAAOA,EAAK7N,QAAS6H,EAAkB,aAElCxC,EAAQyH,kBAAmBhH,GAC5BE,GAAkBA,EAAc7I,KAAM0Q,IACtC9H,GAAkBA,EAAU5I,KAAM0Q,IAErC,IACC,GAAI7P,GAAMiI,EAAQtI,KAAMlB,EAAMoR,EAG9B,IAAK7P,GAAOqH,EAAQ8H,mBAGlB1Q,EAAK9C,UAAuC,KAA3B8C,EAAK9C,SAASsD,SAChC,MAAOe,GAEP,MAAMmD,IAGT,MAAOkI,IAAQwE,EAAMlU,EAAU,MAAO8C,IAAQG,OAAS,GAGxDyM,GAAOnD,SAAW,SAAU9K,EAASqB,GAKpC,OAHOrB,EAAQ8B,eAAiB9B,KAAczB,GAC7CkM,EAAazK,GAEP8K,EAAU9K,EAASqB,IAG3B4M,GAAO/L,KAAO,SAAUb,EAAM4C,IAEtB5C,EAAKS,eAAiBT,KAAW9C,GACvCkM,EAAapJ,EAGd,IAAIpB,GAAKkK,EAAK2F,WAAY7L,EAAKiE,eAE9ByK,EAAM1S,GAAM0L,EAAOpJ,KAAM4H,EAAK2F,WAAY7L,EAAKiE,eAC9CjI,EAAIoB,EAAM4C,GAAOyG,GACjBxM,SAEF,OAAOyU,KAAQzU,UACd+L,EAAQiC,aAAexB,EACtBrJ,EAAKuN,aAAc3K,IAClB0O,EAAMtR,EAAKkQ,iBAAiBtN,KAAU0O,EAAIC,UAC1CD,EAAIxK,MACJ,KACFwK,GAGF1E,GAAOhI,MAAQ,SAAUC,GACxB,KAAUC,OAAO,0CAA4CD,IAO9D+H,GAAO4E,WAAa,SAAUvK,GAC7B,GAAIjH,GACHyR,KACApP,EAAI,EACJF,EAAI,CAOL,IAJA6H,GAAgBpB,EAAQ8I,iBACxBvI,GAAaP,EAAQ+I,YAAc1K,EAAQhJ,MAAO,GAClDgJ,EAAQzE,KAAMyH,GAETD,EAAe,CACnB,MAAShK,EAAOiH,EAAQ9E,KAClBnC,IAASiH,EAAS9E,KACtBE,EAAIoP,EAAW1T,KAAMoE,GAGvB,OAAQE,IACP4E,EAAQxE,OAAQgP,EAAYpP,GAAK,GAInC,MAAO4E,IAOR8B,EAAU6D,GAAO7D,QAAU,SAAU/I,GACpC,GAAIoP,GACH7N,EAAM,GACNY,EAAI,EACJ3B,EAAWR,EAAKQ,QAEjB,IAAMA,GAMC,GAAkB,IAAbA,GAA+B,IAAbA,GAA+B,KAAbA,EAAkB,CAGjE,GAAiC,gBAArBR,GAAK4R,YAChB,MAAO5R,GAAK4R,WAGZ,KAAM5R,EAAOA,EAAK6P,WAAY7P,EAAMA,EAAOA,EAAK8O,YAC/CvN,GAAOwH,EAAS/I,OAGZ,IAAkB,IAAbQ,GAA+B,IAAbA,EAC7B,MAAOR,GAAK6R,cAhBZ,MAASzC,EAAOpP,EAAKmC,GAAKA,IAEzBZ,GAAOwH,EAASqG,EAkBlB,OAAO7N,IAGRuH,EAAO8D,GAAOkF,WAGb7D,YAAa,GAEb8D,aAAc5D,GAEdpO,MAAOwL,EAEPkD,cAEApO,QAEA2R,UACCC,KAAOC,IAAK,aAAclQ,OAAO,GACjCmQ,KAAOD,IAAK,cACZE,KAAOF,IAAK,kBAAmBlQ,OAAO,GACtCqQ,KAAOH,IAAK,oBAGbI,WACC3G,KAAQ,SAAU5L,GAUjB,MATAA,GAAM,GAAKA,EAAM,GAAGwD,QAAS6I,GAAWC,IAGxCtM,EAAM,IAAOA,EAAM,IAAMA,EAAM,IAAM,IAAKwD,QAAS6I,GAAWC,IAE5C,OAAbtM,EAAM,KACVA,EAAM,GAAK,IAAMA,EAAM,GAAK,KAGtBA,EAAM9B,MAAO,EAAG,IAGxB4N,MAAS,SAAU9L,GA6BlB,MAlBAA,GAAM,GAAKA,EAAM,GAAG8G,cAEY,QAA3B9G,EAAM,GAAG9B,MAAO,EAAG,IAEjB8B,EAAM,IACX6M,GAAOhI,MAAO7E,EAAM,IAKrBA,EAAM,KAAQA,EAAM,GAAKA,EAAM,IAAMA,EAAM,IAAM,GAAK,GAAmB,SAAbA,EAAM,IAA8B,QAAbA,EAAM,KACzFA,EAAM,KAAUA,EAAM,GAAKA,EAAM,IAAqB,QAAbA,EAAM,KAGpCA,EAAM,IACjB6M,GAAOhI,MAAO7E,EAAM,IAGdA,GAGR6L,OAAU,SAAU7L,GACnB,GAAIwS,GACHC,GAAYzS,EAAM,IAAMA,EAAM,EAE/B,OAAKwL,GAAiB,MAAE7K,KAAMX,EAAM,IAC5B,MAIHA,EAAM,IAAMA,EAAM,KAAOlD,UAC7BkD,EAAM,GAAKA,EAAM,GAGNyS,GAAYnH,EAAQ3K,KAAM8R,KAEpCD,EAASjF,GAAUkF,GAAU,MAE7BD,EAASC,EAASrU,QAAS,IAAKqU,EAASrS,OAASoS,GAAWC,EAASrS,UAGvEJ,EAAM,GAAKA,EAAM,GAAG9B,MAAO,EAAGsU,GAC9BxS,EAAM,GAAKyS,EAASvU,MAAO,EAAGsU,IAIxBxS,EAAM9B,MAAO,EAAG,MAIzB+R,QAECtE,IAAO,SAAU+G,GAChB,GAAI7L,GAAW6L,EAAiBlP,QAAS6I,GAAWC,IAAYxF,aAChE,OAA4B,MAArB4L,EACN,WAAa,OAAO,GACpB,SAAUzS,GACT,MAAOA,GAAK4G,UAAY5G,EAAK4G,SAASC,gBAAkBD,IAI3D6E,MAAS,SAAUiE,GAClB,GAAIgD,GAAU9I,EAAY8F,EAAY,IAEtC,OAAOgD,KACLA,EAAc1H,OAAQ,MAAQN,EAAa,IAAMgF,EAAY,IAAMhF,EAAa,SACjFd,EAAY8F,EAAW,SAAU1P,GAChC,MAAO0S,GAAQhS,KAAgC,gBAAnBV,GAAK0P,WAA0B1P,EAAK0P,iBAAoB1P,GAAKuN,eAAiBnD,GAAgBpK,EAAKuN,aAAa,UAAY,OAI3J5B,KAAQ,SAAU/I,EAAM+P,EAAUC,GACjC,MAAO,UAAU5S,GAChB,GAAI6S,GAASjG,GAAO/L,KAAMb,EAAM4C,EAEhC,OAAe,OAAViQ,EACgB,OAAbF,EAEFA,GAINE,GAAU,GAEU,MAAbF,EAAmBE,IAAWD,EACvB,OAAbD,EAAoBE,IAAWD,EAClB,OAAbD,EAAoBC,GAAqC,IAA5BC,EAAO1U,QAASyU,GAChC,OAAbD,EAAoBC,GAASC,EAAO1U,QAASyU,GAAU,GAC1C,OAAbD,EAAoBC,GAASC,EAAO5U,OAAQ2U,EAAMzS,UAAayS,EAClD,OAAbD,GAAsB,IAAME,EAAS,KAAM1U,QAASyU,GAAU,GACjD,OAAbD,EAAoBE,IAAWD,GAASC,EAAO5U,MAAO,EAAG2U,EAAMzS,OAAS,KAAQyS,EAAQ,KACxF,IAZO,IAgBV/G,MAAS,SAAU3H,EAAM4O,EAAM5D,EAAUlN,EAAOE,GAC/C,GAAI6Q,GAAgC,QAAvB7O,EAAKjG,MAAO,EAAG,GAC3B+U,EAA+B,SAArB9O,EAAKjG,MAAO,IACtBgV,EAAkB,YAATH,CAEV,OAAiB,KAAV9Q,GAAwB,IAATE,EAGrB,SAAUlC,GACT,QAASA,EAAKe,YAGf,SAAUf,EAAMrB,EAASgH,GACxB,GAAIqI,GAAOkF,EAAY9D,EAAMR,EAAMuE,EAAWC,EAC7ClB,EAAMa,IAAWC,EAAU,cAAgB,kBAC3C1D,EAAStP,EAAKe,WACd6B,EAAOqQ,GAAUjT,EAAK4G,SAASC,cAC/BwM,GAAY1N,IAAQsN,CAErB,IAAK3D,EAAS,CAGb,GAAKyD,EAAS,CACb,MAAQb,EAAM,CACb9C,EAAOpP,CACP,OAASoP,EAAOA,EAAM8C,GACrB,GAAKe,EAAS7D,EAAKxI,SAASC,gBAAkBjE,EAAyB,IAAlBwM,EAAK5O,SACzD,OAAO,CAIT4S,GAAQlB,EAAe,SAAThO,IAAoBkP,GAAS,cAE5C,OAAO,EAMR,GAHAA,GAAUJ,EAAU1D,EAAOO,WAAaP,EAAOgE,WAG1CN,GAAWK,EAAW,CAE1BH,EAAa5D,EAAQlM,KAAckM,EAAQlM,OAC3C4K,EAAQkF,EAAYhP,OACpBiP,EAAYnF,EAAM,KAAOrE,GAAWqE,EAAM,GAC1CY,EAAOZ,EAAM,KAAOrE,GAAWqE,EAAM,GACrCoB,EAAO+D,GAAa7D,EAAOhK,WAAY6N,EAEvC,OAAS/D,IAAS+D,GAAa/D,GAAQA,EAAM8C,KAG3CtD,EAAOuE,EAAY,IAAMC,EAAM7I,MAGhC,GAAuB,IAAlB6E,EAAK5O,YAAoBoO,GAAQQ,IAASpP,EAAO,CACrDkT,EAAYhP,IAAWyF,EAASwJ,EAAWvE,EAC3C,YAKI,IAAKyE,IAAarF,GAAShO,EAAMoD,KAAcpD,EAAMoD,QAAkBc,KAAW8J,EAAM,KAAOrE,EACrGiF,EAAOZ,EAAM,OAKb,OAASoB,IAAS+D,GAAa/D,GAAQA,EAAM8C,KAC3CtD,EAAOuE,EAAY,IAAMC,EAAM7I,MAEhC,IAAO0I,EAAS7D,EAAKxI,SAASC,gBAAkBjE,EAAyB,IAAlBwM,EAAK5O,aAAsBoO,IAE5EyE,KACHjE,EAAMhM,KAAcgM,EAAMhM,QAAkBc,IAAWyF,EAASiF,IAG7DQ,IAASpP,GACb,KAQJ,OADA4O,IAAQ1M,EACD0M,IAAS5M,GAA4B,IAAjB4M,EAAO5M,GAAe4M,EAAO5M,GAAS,KAKrE4J,OAAU,SAAU2H,EAAQrE,GAK3B,GAAIvN,GACH/C,EAAKkK,EAAKgC,QAASyI,IAAYzK,EAAK0K,WAAYD,EAAO1M,gBACtD+F,GAAOhI,MAAO,uBAAyB2O,EAKzC,OAAK3U,GAAIwE,GACDxE,EAAIsQ,GAIPtQ,EAAGuB,OAAS,GAChBwB,GAAS4R,EAAQA,EAAQ,GAAIrE,GACtBpG,EAAK0K,WAAWjV,eAAgBgV,EAAO1M,eAC7CsH,GAAa,SAAUtB,EAAMrD,GAC5B,GAAIiK,GACHC,EAAU9U,EAAIiO,EAAMqC,GACpB/M,EAAIuR,EAAQvT,MACb,OAAQgC,IACPsR,EAAMtV,EAAQ+C,KAAM2L,EAAM6G,EAAQvR,IAClC0K,EAAM4G,KAAWjK,EAASiK,GAAQC,EAAQvR,MAG5C,SAAUnC,GACT,MAAOpB,GAAIoB,EAAM,EAAG2B,KAIhB/C,IAITkM,SAEC6I,IAAOxF,GAAa,SAAUzP,GAI7B,GAAI0R,MACHnJ,KACA2M,EAAU3K,EAASvK,EAAS6E,QAASwH,EAAO,MAE7C,OAAO6I,GAASxQ,GACf+K,GAAa,SAAUtB,EAAMrD,EAAS7K,EAASgH,GAC9C,GAAI3F,GACH6T,EAAYD,EAAS/G,EAAM,KAAMlH,MACjCxD,EAAI0K,EAAK1M,MAGV,OAAQgC,KACDnC,EAAO6T,EAAU1R,MACtB0K,EAAK1K,KAAOqH,EAAQrH,GAAKnC,MAI5B,SAAUA,EAAMrB,EAASgH,GAGxB,MAFAyK,GAAM,GAAKpQ,EACX4T,EAASxD,EAAO,KAAMzK,EAAKsB,IACnBA,EAAQsD,SAInBuJ,IAAO3F,GAAa,SAAUzP,GAC7B,MAAO,UAAUsB,GAChB,MAAO4M,IAAQlO,EAAUsB,GAAOG,OAAS,KAI3CsJ,SAAY0E,GAAa,SAAU7H,GAClC,MAAO,UAAUtG,GAChB,OAASA,EAAK4R,aAAe5R,EAAK+T,WAAahL,EAAS/I,IAAS7B,QAASmI,GAAS,MAWrF0N,KAAQ7F,GAAc,SAAU6F,GAM/B,MAJM1I,GAAY5K,KAAKsT,GAAQ,KAC9BpH,GAAOhI,MAAO,qBAAuBoP,GAEtCA,EAAOA,EAAKzQ,QAAS6I,GAAWC,IAAYxF,cACrC,SAAU7G,GAChB,GAAIiU,EACJ,GACC,IAAMA,EAAW5K,EAChBrJ,EAAKgU,KACLhU,EAAKuN,aAAa,aAAevN,EAAKuN,aAAa,QAGnD,MADA0G,GAAWA,EAASpN,cACboN,IAAaD,GAA2C,IAAnCC,EAAS9V,QAAS6V,EAAO,YAE5ChU,EAAOA,EAAKe,aAAiC,IAAlBf,EAAKQ,SAC3C,QAAO,KAKTyC,OAAU,SAAUjD,GACnB,GAAIkU,GAAOtX,EAAOK,UAAYL,EAAOK,SAASiX,IAC9C,OAAOA,IAAQA,EAAKjW,MAAO,KAAQ+B,EAAKmN,IAGzCgH,KAAQ,SAAUnU,GACjB,MAAOA,KAAS7C,GAGjBiX,MAAS,SAAUpU,GAClB,MAAOA,KAAS9C,EAASmX,iBAAmBnX,EAASoX,UAAYpX,EAASoX,gBAAkBtU,EAAKkE,MAAQlE,EAAKuU,OAASvU,EAAKwU,WAI7HC,QAAW,SAAUzU,GACpB,MAAOA,GAAK0U,YAAa,GAG1BA,SAAY,SAAU1U,GACrB,MAAOA,GAAK0U,YAAa,GAG1BC,QAAW,SAAU3U,GAGpB,GAAI4G,GAAW5G,EAAK4G,SAASC,aAC7B,OAAqB,UAAbD,KAA0B5G,EAAK2U,SAA0B,WAAb/N,KAA2B5G,EAAK4U,UAGrFA,SAAY,SAAU5U,GAOrB,MAJKA,GAAKe,YACTf,EAAKe,WAAW8T,cAGV7U,EAAK4U,YAAa,GAI1BE,MAAS,SAAU9U,GAMlB,IAAMA,EAAOA,EAAK6P,WAAY7P,EAAMA,EAAOA,EAAK8O,YAC/C,GAAK9O,EAAK4G,SAAW,KAAyB,IAAlB5G,EAAKQ,UAAoC,IAAlBR,EAAKQ,SACvD,OAAO,CAGT,QAAO,GAGR8O,OAAU,SAAUtP,GACnB,OAAQ8I,EAAKgC,QAAe,MAAG9K,IAIhC+U,OAAU,SAAU/U,GACnB,MAAOkM,IAAQxL,KAAMV,EAAK4G,WAG3BwJ,MAAS,SAAUpQ,GAClB,MAAOiM,GAAQvL,KAAMV,EAAK4G,WAG3BoO,OAAU,SAAUhV,GACnB,GAAI4C,GAAO5C,EAAK4G,SAASC,aACzB,OAAgB,UAATjE,GAAkC,WAAd5C,EAAKkE,MAA8B,WAATtB,GAGtD0D,KAAQ,SAAUtG,GACjB,GAAIa,EAGJ,OAAuC,UAAhCb,EAAK4G,SAASC,eACN,SAAd7G,EAAKkE,OACmC,OAArCrD,EAAOb,EAAKuN,aAAa,UAAoB1M,EAAKgG,gBAAkB7G,EAAKkE,OAI9ElC,MAASiN,GAAuB,WAC/B,OAAS,KAGV/M,KAAQ+M,GAAuB,SAAUE,EAAchP,GACtD,OAASA,EAAS,KAGnB8B,GAAMgN,GAAuB,SAAUE,EAAchP,EAAQ+O,GAC5D,OAAoB,EAAXA,EAAeA,EAAW/O,EAAS+O,KAG7C+F,KAAQhG,GAAuB,SAAUE,EAAchP,GACtD,GAAIgC,GAAI,CACR,MAAYhC,EAAJgC,EAAYA,GAAK,EACxBgN,EAAapR,KAAMoE,EAEpB,OAAOgN,KAGR+F,IAAOjG,GAAuB,SAAUE,EAAchP,GACrD,GAAIgC,GAAI,CACR,MAAYhC,EAAJgC,EAAYA,GAAK,EACxBgN,EAAapR,KAAMoE,EAEpB,OAAOgN,KAGRgG,GAAMlG,GAAuB,SAAUE,EAAchP,EAAQ+O,GAC5D,GAAI/M,GAAe,EAAX+M,EAAeA,EAAW/O,EAAS+O,CAC3C,QAAU/M,GAAK,GACdgN,EAAapR,KAAMoE,EAEpB,OAAOgN,KAGRiG,GAAMnG,GAAuB,SAAUE,EAAchP,EAAQ+O,GAC5D,GAAI/M,GAAe,EAAX+M,EAAeA,EAAW/O,EAAS+O,CAC3C,MAAc/O,IAAJgC,GACTgN,EAAapR,KAAMoE,EAEpB,OAAOgN,OAKVrG,EAAKgC,QAAa,IAAIhC,EAAKgC,QAAY,EAGvC,KAAM3I,KAAOkT,OAAO,EAAMC,UAAU,EAAMC,MAAM,EAAMC,UAAU,EAAMC,OAAO,GAC5E3M,EAAKgC,QAAS3I,GAAM4M,GAAmB5M,EAExC,KAAMA,KAAOuT,QAAQ,EAAMC,OAAO,GACjC7M,EAAKgC,QAAS3I,GAAM6M,GAAoB7M,EAIzC,SAASqR,OACTA,GAAW5T,UAAYkJ,EAAK8M,QAAU9M,EAAKgC,QAC3ChC,EAAK0K,WAAa,GAAIA,GAEtB,SAASlG,IAAU5O,EAAUmX,GAC5B,GAAInC,GAAS3T,EAAO+V,EAAQ5R,EAC3B6R,EAAOhJ,EAAQiJ,EACfC,EAASnM,EAAYpL,EAAW,IAEjC,IAAKuX,EACJ,MAAOJ,GAAY,EAAII,EAAOhY,MAAO,EAGtC8X,GAAQrX,EACRqO,KACAiJ,EAAalN,EAAKwJ,SAElB,OAAQyD,EAAQ,GAGTrC,IAAY3T,EAAQkL,EAAO7K,KAAM2V,OACjChW,IAEJgW,EAAQA,EAAM9X,MAAO8B,EAAM,GAAGI,SAAY4V,GAE3ChJ,EAAOhP,KAAM+X,OAGdpC,GAAU,GAGJ3T,EAAQmL,EAAa9K,KAAM2V,MAChCrC,EAAU3T,EAAMmO,QAChB4H,EAAO/X,MACN+I,MAAO4M,EAEPxP,KAAMnE,EAAM,GAAGwD,QAASwH,EAAO,OAEhCgL,EAAQA,EAAM9X,MAAOyV,EAAQvT,QAI9B,KAAM+D,IAAQ4E,GAAKkH,SACZjQ,EAAQwL,EAAWrH,GAAO9D,KAAM2V,KAAcC,EAAY9R,MAC9DnE,EAAQiW,EAAY9R,GAAQnE,MAC7B2T,EAAU3T,EAAMmO,QAChB4H,EAAO/X,MACN+I,MAAO4M,EACPxP,KAAMA,EACNsF,QAASzJ,IAEVgW,EAAQA,EAAM9X,MAAOyV,EAAQvT,QAI/B,KAAMuT,EACL,MAOF,MAAOmC,GACNE,EAAM5V,OACN4V,EACCnJ,GAAOhI,MAAOlG,GAEdoL,EAAYpL,EAAUqO,GAAS9O,MAAO,GAGzC,QAASwP,IAAYqI,GACpB,GAAI3T,GAAI,EACPC,EAAM0T,EAAO3V,OACbzB,EAAW,EACZ,MAAY0D,EAAJD,EAASA,IAChBzD,GAAYoX,EAAO3T,GAAG2E,KAEvB,OAAOpI,GAGR,QAASwX,IAAetC,EAASuC,EAAYC,GAC5C,GAAIlE,GAAMiE,EAAWjE,IACpBmE,EAAmBD,GAAgB,eAARlE,EAC3BoE,EAAWzU,GAEZ,OAAOsU,GAAWnU,MAEjB,SAAUhC,EAAMrB,EAASgH,GACxB,MAAS3F,EAAOA,EAAMkS,GACrB,GAAuB,IAAlBlS,EAAKQ,UAAkB6V,EAC3B,MAAOzC,GAAS5T,EAAMrB,EAASgH,IAMlC,SAAU3F,EAAMrB,EAASgH,GACxB,GAAIZ,GAAMiJ,EAAOkF,EAChBqD,EAAS5M,EAAU,IAAM2M,CAG1B,IAAK3Q,GACJ,MAAS3F,EAAOA,EAAMkS,GACrB,IAAuB,IAAlBlS,EAAKQ,UAAkB6V,IACtBzC,EAAS5T,EAAMrB,EAASgH,GAC5B,OAAO,MAKV,OAAS3F,EAAOA,EAAMkS,GACrB,GAAuB,IAAlBlS,EAAKQ,UAAkB6V,EAE3B,GADAnD,EAAalT,EAAMoD,KAAcpD,EAAMoD,QACjC4K,EAAQkF,EAAYhB,KAAUlE,EAAM,KAAOuI,GAChD,IAAMxR,EAAOiJ,EAAM,OAAQ,GAAQjJ,IAAS8D,EAC3C,MAAO9D,MAAS,MAKjB,IAFAiJ,EAAQkF,EAAYhB,IAAUqE,GAC9BvI,EAAM,GAAK4F,EAAS5T,EAAMrB,EAASgH,IAASkD,EACvCmF,EAAM,MAAO,EACjB,OAAO,GASf,QAASwI,IAAgBC,GACxB,MAAOA,GAAStW,OAAS,EACxB,SAAUH,EAAMrB,EAASgH,GACxB,GAAIxD,GAAIsU,EAAStW,MACjB,OAAQgC,IACP,IAAMsU,EAAStU,GAAInC,EAAMrB,EAASgH,GACjC,OAAO,CAGT,QAAO,GAER8Q,EAAS,GAGX,QAASC,IAAU7C,EAAWvR,EAAK0N,EAAQrR,EAASgH,GACnD,GAAI3F,GACH2W,KACAxU,EAAI,EACJC,EAAMyR,EAAU1T,OAChByW,EAAgB,MAAPtU,CAEV,MAAYF,EAAJD,EAASA,KACVnC,EAAO6T,EAAU1R,OAChB6N,GAAUA,EAAQhQ,EAAMrB,EAASgH,MACtCgR,EAAa5Y,KAAMiC,GACd4W,GACJtU,EAAIvE,KAAMoE,GAMd,OAAOwU,GAGR,QAASE,IAAYvE,EAAW5T,EAAUkV,EAASkD,EAAYC,EAAYC,GAO1E,MANKF,KAAeA,EAAY1T,KAC/B0T,EAAaD,GAAYC,IAErBC,IAAeA,EAAY3T,KAC/B2T,EAAaF,GAAYE,EAAYC,IAE/B7I,GAAa,SAAUtB,EAAM5F,EAAStI,EAASgH,GACrD,GAAIsR,GAAM9U,EAAGnC,EACZkX,KACAC,KACAC,EAAcnQ,EAAQ9G,OAGtBmB,EAAQuL,GAAQwK,GAAkB3Y,GAAY,IAAKC,EAAQ6B,UAAa7B,GAAYA,MAGpF2Y,GAAYhF,IAAezF,GAASnO,EAEnC4C,EADAoV,GAAUpV,EAAO4V,EAAQ5E,EAAW3T,EAASgH,GAG9C4R,EAAa3D,EAEZmD,IAAgBlK,EAAOyF,EAAY8E,GAAeN,MAMjD7P,EACDqQ,CAQF,IALK1D,GACJA,EAAS0D,EAAWC,EAAY5Y,EAASgH,GAIrCmR,EAAa,CACjBG,EAAOP,GAAUa,EAAYJ,GAC7BL,EAAYG,KAAUtY,EAASgH,GAG/BxD,EAAI8U,EAAK9W,MACT,OAAQgC,KACDnC,EAAOiX,EAAK9U,MACjBoV,EAAYJ,EAAQhV,MAASmV,EAAWH,EAAQhV,IAAOnC,IAK1D,GAAK6M,GACJ,GAAKkK,GAAczE,EAAY,CAC9B,GAAKyE,EAAa,CAEjBE,KACA9U,EAAIoV,EAAWpX,MACf,OAAQgC,KACDnC,EAAOuX,EAAWpV,KAEvB8U,EAAKlZ,KAAOuZ,EAAUnV,GAAKnC,EAG7B+W,GAAY,KAAOQ,KAAkBN,EAAMtR,GAI5CxD,EAAIoV,EAAWpX,MACf,OAAQgC,KACDnC,EAAOuX,EAAWpV,MACtB8U,EAAOF,EAAa5Y,EAAQ+C,KAAM2L,EAAM7M,GAASkX,EAAO/U,IAAM,KAE/D0K,EAAKoK,KAAUhQ,EAAQgQ,GAAQjX,SAOlCuX,GAAab,GACZa,IAAetQ,EACdsQ,EAAW9U,OAAQ2U,EAAaG,EAAWpX,QAC3CoX,GAEGR,EACJA,EAAY,KAAM9P,EAASsQ,EAAY5R,GAEvC5H,EAAK+D,MAAOmF,EAASsQ,KAMzB,QAASC,IAAmB1B,GAC3B,GAAI2B,GAAc7D,EAASvR,EAC1BD,EAAM0T,EAAO3V,OACbuX,EAAkB5O,EAAKkJ,SAAU8D,EAAO,GAAG5R,MAC3CyT,EAAmBD,GAAmB5O,EAAKkJ,SAAS,KACpD7P,EAAIuV,EAAkB,EAAI,EAG1BE,EAAe1B,GAAe,SAAUlW,GACvC,MAAOA,KAASyX,GACdE,GAAkB,GACrBE,EAAkB3B,GAAe,SAAUlW,GAC1C,MAAO7B,GAAQ+C,KAAMuW,EAAczX,GAAS,IAC1C2X,GAAkB,GACrBlB,GAAa,SAAUzW,EAAMrB,EAASgH,GACrC,OAAU+R,IAAqB/R,GAAOhH,IAAYuK,MAChDuO,EAAe9Y,GAAS6B,SACxBoX,EAAc5X,EAAMrB,EAASgH,GAC7BkS,EAAiB7X,EAAMrB,EAASgH,KAGpC,MAAYvD,EAAJD,EAASA,IAChB,GAAMyR,EAAU9K,EAAKkJ,SAAU8D,EAAO3T,GAAG+B,MACxCuS,GAAaP,GAAcM,GAAgBC,GAAY7C,QACjD,CAIN,GAHAA,EAAU9K,EAAKkH,OAAQ8F,EAAO3T,GAAG+B,MAAOpC,MAAO,KAAMgU,EAAO3T,GAAGqH,SAG1DoK,EAASxQ,GAAY,CAGzB,IADAf,IAAMF,EACMC,EAAJC,EAASA,IAChB,GAAKyG,EAAKkJ,SAAU8D,EAAOzT,GAAG6B,MAC7B,KAGF,OAAO2S,IACN1U,EAAI,GAAKqU,GAAgBC,GACzBtU,EAAI,GAAKsL,GAERqI,EAAO7X,MAAO,EAAGkE,EAAI,GAAItE,QAASiJ,MAAgC,MAAzBgP,EAAQ3T,EAAI,GAAI+B,KAAe,IAAM,MAC7EX,QAASwH,EAAO,MAClB6I,EACIvR,EAAJF,GAASqV,GAAmB1B,EAAO7X,MAAOkE,EAAGE,IACzCD,EAAJC,GAAWmV,GAAoB1B,EAASA,EAAO7X,MAAOoE,IAClDD,EAAJC,GAAWoL,GAAYqI,IAGzBW,EAAS1Y,KAAM6V,GAIjB,MAAO4C,IAAgBC,GAGxB,QAASqB,IAA0BC,EAAiBC,GAEnD,GAAIC,GAAoB,EACvBC,EAAQF,EAAY7X,OAAS,EAC7BgY,EAAYJ,EAAgB5X,OAAS,EACrCiY,EAAe,SAAUvL,EAAMlO,EAASgH,EAAKsB,EAASoR,GACrD,GAAIrY,GAAMqC,EAAGuR,EACZ0E,KACAC,EAAe,EACfpW,EAAI,IACJ0R,EAAYhH,MACZ2L,EAA6B,MAAjBH,EACZI,EAAgBvP,EAEhB5H,EAAQuL,GAAQsL,GAAarP,EAAKzI,KAAU,IAAG,IAAKgY,GAAiB1Z,EAAQoC,YAAcpC,GAE3F+Z,EAAiB/O,GAA4B,MAAjB8O,EAAwB,EAAIpV,KAAKC,UAAY,EAS1E,KAPKkV,IACJtP,EAAmBvK,IAAYzB,GAAYyB,EAC3CkK,EAAaoP,GAKe,OAApBjY,EAAOsB,EAAMa,IAAaA,IAAM,CACxC,GAAKgW,GAAanY,EAAO,CACxBqC,EAAI,CACJ,OAASuR,EAAUmE,EAAgB1V,KAClC,GAAKuR,EAAS5T,EAAMrB,EAASgH,GAAQ,CACpCsB,EAAQlJ,KAAMiC,EACd,OAGGwY,IACJ7O,EAAU+O,EACV7P,IAAeoP,GAKZC,KAEElY,GAAQ4T,GAAW5T,IACxBuY,IAII1L,GACJgH,EAAU9V,KAAMiC,IAOnB,GADAuY,GAAgBpW,EACX+V,GAAS/V,IAAMoW,EAAe,CAClClW,EAAI,CACJ,OAASuR,EAAUoE,EAAY3V,KAC9BuR,EAASC,EAAWyE,EAAY3Z,EAASgH,EAG1C,IAAKkH,EAAO,CAEX,GAAK0L,EAAe,EACnB,MAAQpW,IACA0R,EAAU1R,IAAMmW,EAAWnW,KACjCmW,EAAWnW,GAAKoI,EAAIrJ,KAAM+F,GAM7BqR,GAAa5B,GAAU4B,GAIxBva,EAAK+D,MAAOmF,EAASqR,GAGhBE,IAAc3L,GAAQyL,EAAWnY,OAAS,GAC5CoY,EAAeP,EAAY7X,OAAW,GAExCyM,GAAO4E,WAAYvK,GAUrB,MALKuR,KACJ7O,EAAU+O,EACVxP,EAAmBuP,GAGb5E,EAGT,OAAOqE,GACN/J,GAAciK,GACdA,EAGFnP,EAAU2D,GAAO3D,QAAU,SAAUvK,EAAUia,GAC9C,GAAIxW,GACH6V,KACAD,KACA9B,EAASlM,EAAerL,EAAW,IAEpC,KAAMuX,EAAS,CAER0C,IACLA,EAAQrL,GAAU5O,IAEnByD,EAAIwW,EAAMxY,MACV,OAAQgC,IACP8T,EAASuB,GAAmBmB,EAAMxW,IAC7B8T,EAAQ7S,GACZ4U,EAAYja,KAAMkY,GAElB8B,EAAgBha,KAAMkY,EAKxBA,GAASlM,EAAerL,EAAUoZ,GAA0BC,EAAiBC,IAE9E,MAAO/B,GAGR,SAASoB,IAAkB3Y,EAAUka,EAAU3R,GAC9C,GAAI9E,GAAI,EACPC,EAAMwW,EAASzY,MAChB,MAAYiC,EAAJD,EAASA,IAChByK,GAAQlO,EAAUka,EAASzW,GAAI8E,EAEhC,OAAOA,GAGR,QAAS6G,IAAQpP,EAAUC,EAASsI,EAAS4F,GAC5C,GAAI1K,GAAG2T,EAAQ+C,EAAO3U,EAAM7D,EAC3BN,EAAQuN,GAAU5O,EAEnB,KAAMmO,GAEiB,IAAjB9M,EAAMI,OAAe,CAIzB,GADA2V,EAAS/V,EAAM,GAAKA,EAAM,GAAG9B,MAAO,GAC/B6X,EAAO3V,OAAS,GAAkC,QAA5B0Y,EAAQ/C,EAAO,IAAI5R,MAC5C0E,EAAQkH,SAAgC,IAArBnR,EAAQ6B,UAAkB6I,GAC7CP,EAAKkJ,SAAU8D,EAAO,GAAG5R,MAAS,CAGnC,GADAvF,GAAYmK,EAAKzI,KAAS,GAAGwY,EAAMrP,QAAQ,GAAGjG,QAAQ6I,GAAWC,IAAY1N,QAAkB,IACzFA,EACL,MAAOsI,EAERvI,GAAWA,EAAST,MAAO6X,EAAO5H,QAAQpH,MAAM3G,QAIjDgC,EAAIoJ,EAAwB,aAAE7K,KAAMhC,GAAa,EAAIoX,EAAO3V,MAC5D,OAAQgC,IAAM,CAIb,GAHA0W,EAAQ/C,EAAO3T,GAGV2G,EAAKkJ,SAAW9N,EAAO2U,EAAM3U,MACjC,KAED,KAAM7D,EAAOyI,EAAKzI,KAAM6D,MAEjB2I,EAAOxM,EACZwY,EAAMrP,QAAQ,GAAGjG,QAAS6I,GAAWC,IACrClB,EAASzK,KAAMoV,EAAO,GAAG5R,OAAUvF,EAAQoC,YAAcpC,IACrD,CAKJ,GAFAmX,EAAOrT,OAAQN,EAAG,GAClBzD,EAAWmO,EAAK1M,QAAUsN,GAAYqI,IAChCpX,EAEL,MADAX,GAAK+D,MAAOmF,EAAS4F,GACd5F,CAGR,SAgBL,MAPAgC,GAASvK,EAAUqB,GAClB8M,EACAlO,GACC0K,EACDpC,EACAkE,EAASzK,KAAMhC,IAETuI,EAMR2B,EAAQ+I,WAAavO,EAAQuF,MAAM,IAAInG,KAAMyH,GAAYyD,KAAK,MAAQtK,EAItEwF,EAAQ8I,iBAAmB1H,EAG3BZ,IAIAR,EAAQmI,aAAe3C,GAAO,SAAU0K,GAEvC,MAAuE,GAAhEA,EAAKnI,wBAAyBzT,EAASiI,cAAc,UAMvDiJ,GAAO,SAAUC,GAEtB,MADAA,GAAIuB,UAAY,mBAC+B,MAAxCvB,EAAIwB,WAAWtC,aAAa,WAEnCe,GAAW,yBAA0B,SAAUtO,EAAM4C,EAAMoG,GAC1D,MAAMA,GAAN,UACQhJ,EAAKuN,aAAc3K,EAA6B,SAAvBA,EAAKiE,cAA2B,EAAI,KAOjE+B,EAAQiC,YAAeuD,GAAO,SAAUC,GAG7C,MAFAA,GAAIuB,UAAY,WAChBvB,EAAIwB,WAAWrC,aAAc,QAAS,IACY,KAA3Ca,EAAIwB,WAAWtC,aAAc,YAEpCe,GAAW,QAAS,SAAUtO,EAAM4C,EAAMoG,GACzC,MAAMA,IAAyC,UAAhChJ,EAAK4G,SAASC,cAA7B,UACQ7G,EAAK+Y,eAOT3K,GAAO,SAAUC,GACtB,MAAuC,OAAhCA,EAAId,aAAa,eAExBe,GAAW7D,EAAU,SAAUzK,EAAM4C,EAAMoG,GAC1C,GAAIsI,EACJ,OAAMtI,GAAN,WACSsI,EAAMtR,EAAKkQ,iBAAkBtN,KAAW0O,EAAIC,UACnDD,EAAIxK,MACJ9G,EAAM4C,MAAW,EAAOA,EAAKiE,cAAgB,OAKjDvJ,EAAO+C,KAAOuM,GACdtP,EAAO8T,KAAOxE,GAAOkF,UACrBxU,EAAO8T,KAAK,KAAO9T,EAAO8T,KAAKtG,QAC/BxN,EAAO0b,OAASpM,GAAO4E,WACvBlU,EAAOgJ,KAAOsG,GAAO7D,QACrBzL,EAAO2b,SAAWrM,GAAO5D,MACzB1L,EAAOmM,SAAWmD,GAAOnD,UAGrB7M,EAEJ,IAAIsc,KAGJ,SAASC,GAAexW,GACvB,GAAIyW,GAASF,EAAcvW,KAI3B,OAHArF,GAAOmE,KAAMkB,EAAQ5C,MAAOf,OAAwB,SAAUsN,EAAG+M,GAChED,EAAQC,IAAS,IAEXD,EAyBR9b,EAAOgc,UAAY,SAAU3W,GAI5BA,EAA6B,gBAAZA,GACduW,EAAcvW,IAAawW,EAAexW,GAC5CrF,EAAOoF,UAAYC,EAEpB,IACC4W,GAEAC,EAEAC,EAEAC,EAEAC,EAEAC,EAEAC,KAEAC,GAASnX,EAAQoX,SAEjBC,EAAO,SAAUjV,GAOhB,IANAwU,EAAS5W,EAAQ4W,QAAUxU,EAC3ByU,GAAQ,EACRI,EAAcF,GAAe,EAC7BA,EAAc,EACdC,EAAeE,EAAK1Z,OACpBsZ,GAAS,EACDI,GAAsBF,EAAdC,EAA4BA,IAC3C,GAAKC,EAAMD,GAAc9X,MAAOiD,EAAM,GAAKA,EAAM,OAAU,GAASpC,EAAQsX,YAAc,CACzFV,GAAS,CACT,OAGFE,GAAS,EACJI,IACCC,EACCA,EAAM3Z,QACV6Z,EAAMF,EAAM5L,SAEFqL,EACXM,KAEAK,EAAKC,YAKRD,GAECE,IAAK,WACJ,GAAKP,EAAO,CAEX,GAAIzG,GAAQyG,EAAK1Z,QACjB,QAAUia,GAAKzY,GACdrE,EAAOmE,KAAME,EAAM,SAAU2K,EAAG7E,GAC/B,GAAIvD,GAAO5G,EAAO4G,KAAMuD,EACV,cAATvD,EACEvB,EAAQqW,QAAWkB,EAAKpG,IAAKrM,IAClCoS,EAAK9b,KAAM0J,GAEDA,GAAOA,EAAItH,QAAmB,WAAT+D,GAEhCkW,EAAK3S,OAGJ1F,WAGC0X,EACJE,EAAeE,EAAK1Z,OAGToZ,IACXG,EAActG,EACd4G,EAAMT,IAGR,MAAOtZ,OAGRoF,OAAQ,WAkBP,MAjBKwU,IACJvc,EAAOmE,KAAMM,UAAW,SAAUuK,EAAG7E,GACpC,GAAI4S,EACJ,QAASA,EAAQ/c,EAAO6J,QAASM,EAAKoS,EAAMQ,IAAY,GACvDR,EAAKpX,OAAQ4X,EAAO,GAEfZ,IACUE,GAATU,GACJV,IAEaC,GAATS,GACJT,OAME3Z,MAIR6T,IAAK,SAAUlV,GACd,MAAOA,GAAKtB,EAAO6J,QAASvI,EAAIib,GAAS,MAASA,IAAQA,EAAK1Z,SAGhE2U,MAAO,WAGN,MAFA+E,MACAF,EAAe,EACR1Z,MAGRka,QAAS,WAER,MADAN,GAAOC,EAAQP,EAAS1c,UACjBoD,MAGRyU,SAAU,WACT,OAAQmF,GAGTS,KAAM,WAKL,MAJAR,GAAQjd,UACF0c,GACLW,EAAKC,UAECla,MAGRsa,OAAQ,WACP,OAAQT,GAGTU,SAAU,SAAU7b,EAASgD,GAU5B,OATKkY,GAAWL,IAASM,IACxBnY,EAAOA,MACPA,GAAShD,EAASgD,EAAK1D,MAAQ0D,EAAK1D,QAAU0D,GACzC8X,EACJK,EAAM/b,KAAM4D,GAEZqY,EAAMrY,IAGD1B,MAGR+Z,KAAM,WAEL,MADAE,GAAKM,SAAUva,KAAM8B,WACd9B,MAGRuZ,MAAO,WACN,QAASA,GAIZ,OAAOU,IAER5c,EAAOoF,QAEN6F,SAAU,SAAUkS,GACnB,GAAIC,KAEA,UAAW,OAAQpd,EAAOgc,UAAU,eAAgB,aACpD,SAAU,OAAQhc,EAAOgc,UAAU,eAAgB,aACnD,SAAU,WAAYhc,EAAOgc,UAAU,YAE1CqB,EAAQ,UACR/Y,GACC+Y,MAAO,WACN,MAAOA,IAERC,OAAQ,WAEP,MADAC,GAAShZ,KAAME,WAAY+Y,KAAM/Y,WAC1B9B,MAER8a,KAAM,WACL,GAAIC,GAAMjZ,SACV,OAAOzE,GAAOiL,SAAS,SAAU0S,GAChC3d,EAAOmE,KAAMiZ,EAAQ,SAAUvY,EAAG+Y,GACjC,GAAIC,GAASD,EAAO,GACnBtc,EAAKtB,EAAOsD,WAAYoa,EAAK7Y,KAAS6Y,EAAK7Y,EAE5C0Y,GAAUK,EAAM,IAAK,WACpB,GAAIE,GAAWxc,GAAMA,EAAGkD,MAAO7B,KAAM8B,UAChCqZ,IAAY9d,EAAOsD,WAAYwa,EAASxZ,SAC5CwZ,EAASxZ,UACPC,KAAMoZ,EAASI,SACfP,KAAMG,EAASK,QACfC,SAAUN,EAASO,QAErBP,EAAUE,EAAS,QAAUlb,OAAS2B,EAAUqZ,EAASrZ,UAAY3B,KAAMrB,GAAOwc,GAAarZ,eAIlGiZ,EAAM,OACJpZ,WAIJA,QAAS,SAAUqC,GAClB,MAAc,OAAPA,EAAc3G,EAAOoF,OAAQuB,EAAKrC,GAAYA,IAGvDiZ,IAwCD,OArCAjZ,GAAQ6Z,KAAO7Z,EAAQmZ,KAGvBzd,EAAOmE,KAAMiZ,EAAQ,SAAUvY,EAAG+Y,GACjC,GAAIrB,GAAOqB,EAAO,GACjBQ,EAAcR,EAAO,EAGtBtZ,GAASsZ,EAAM,IAAOrB,EAAKO,IAGtBsB,GACJ7B,EAAKO,IAAI,WAERO,EAAQe,GAGNhB,EAAY,EAAJvY,GAAS,GAAIgY,QAASO,EAAQ,GAAK,GAAIJ,MAInDO,EAAUK,EAAM,IAAO,WAEtB,MADAL,GAAUK,EAAM,GAAK,QAAUjb,OAAS4a,EAAWjZ,EAAU3B,KAAM8B,WAC5D9B,MAER4a,EAAUK,EAAM,GAAK,QAAWrB,EAAKW,WAItC5Y,EAAQA,QAASiZ,GAGZJ,GACJA,EAAKvZ,KAAM2Z,EAAUA,GAIfA,GAIRc,KAAM,SAAUC,GACf,GAAIzZ,GAAI,EACP0Z,EAAgB7d,EAAWkD,KAAMa,WACjC5B,EAAS0b,EAAc1b,OAGvB2b,EAAuB,IAAX3b,GAAkByb,GAAete,EAAOsD,WAAYgb,EAAYha,SAAczB,EAAS,EAGnG0a,EAAyB,IAAdiB,EAAkBF,EAActe,EAAOiL,WAGlDwT,EAAa,SAAU5Z,EAAGyW,EAAUoD,GACnC,MAAO,UAAUlV,GAChB8R,EAAUzW,GAAMlC,KAChB+b,EAAQ7Z,GAAMJ,UAAU5B,OAAS,EAAInC,EAAWkD,KAAMa,WAAc+E,EAChEkV,IAAWC,EACdpB,EAASqB,WAAYtD,EAAUoD,KACfF,GAChBjB,EAAS/W,YAAa8U,EAAUoD,KAKnCC,EAAgBE,EAAkBC,CAGnC,IAAKjc,EAAS,EAIb,IAHA8b,EAAqB9X,MAAOhE,GAC5Bgc,EAAuBhY,MAAOhE,GAC9Bic,EAAsBjY,MAAOhE,GACjBA,EAAJgC,EAAYA,IACd0Z,EAAe1Z,IAAO7E,EAAOsD,WAAYib,EAAe1Z,GAAIP,SAChEia,EAAe1Z,GAAIP,UACjBC,KAAMka,EAAY5Z,EAAGia,EAAiBP,IACtCf,KAAMD,EAASS,QACfC,SAAUQ,EAAY5Z,EAAGga,EAAkBF,MAE3CH,CAUL,OAJMA,IACLjB,EAAS/W,YAAasY,EAAiBP,GAGjChB,EAASjZ,aAGlBtE,EAAOsL,QAAU,SAAWA,GAC3B,GAAIwH,GAAQlT,EAASiI,cAAc,SAClCkX,EAAWnf,EAASof,yBACpBjO,EAAMnR,EAASiI,cAAc,OAC7B2I,EAAS5Q,EAASiI,cAAc,UAChCoX,EAAMzO,EAAOtH,YAAatJ,EAASiI,cAAc,UAGlD,OAAMiL,GAAMlM,MAIZkM,EAAMlM,KAAO,WAIb0E,EAAQ4T,QAA0B,KAAhBpM,EAAMtJ,MAIxB8B,EAAQ6T,YAAcF,EAAI3H,SAG1BhM,EAAQ8T,qBAAsB,EAC9B9T,EAAQ+T,mBAAoB,EAC5B/T,EAAQgU,eAAgB,EAIxBxM,EAAMuE,SAAU,EAChB/L,EAAQiU,eAAiBzM,EAAM0M,WAAW,GAAOnI,QAIjD7G,EAAO4G,UAAW,EAClB9L,EAAQmU,aAAeR,EAAI7H,SAI3BtE,EAAQlT,EAASiI,cAAc,SAC/BiL,EAAMtJ,MAAQ,IACdsJ,EAAMlM,KAAO,QACb0E,EAAQoU,WAA6B,MAAhB5M,EAAMtJ,MAG3BsJ,EAAM5C,aAAc,UAAW,KAC/B4C,EAAM5C,aAAc,OAAQ,KAE5B6O,EAAS7V,YAAa4J,GAItBxH,EAAQqU,WAAaZ,EAASS,WAAW,GAAOA,WAAW,GAAOxJ,UAAUqB,QAI5E/L,EAAQsU,eAAiB,aAAetgB,GAExCyR,EAAI/F,MAAM6U,eAAiB,cAC3B9O,EAAIyO,WAAW,GAAOxU,MAAM6U,eAAiB,GAC7CvU,EAAQwU,gBAA+C,gBAA7B/O,EAAI/F,MAAM6U,eAGpC7f,EAAO,WACN,GAAI+f,GAAWC,EAEdC,EAAW,8HACXC,EAAOtgB,EAAS6I,qBAAqB,QAAS,EAEzCyX,KAKNH,EAAYngB,EAASiI,cAAc,OACnCkY,EAAU/U,MAAMmV,QAAU,gFAG1BD,EAAKhX,YAAa6W,GAAY7W,YAAa6H,GAC3CA,EAAIuB,UAAY,GAEhBvB,EAAI/F,MAAMmV,QAAU,uKAIpBngB,EAAO8K,KAAMoV,EAAyB,MAAnBA,EAAKlV,MAAMoV,MAAiBA,KAAM,MAAU,WAC9D9U,EAAQ+U,UAAgC,IAApBtP,EAAIuP,cAIpBhhB,EAAOihB,mBACXjV,EAAQgU,cAAuE,QAArDhgB,EAAOihB,iBAAkBxP,EAAK,WAAeoB,IACvE7G,EAAQ+T,kBAA2F,SAArE/f,EAAOihB,iBAAkBxP,EAAK,QAAYyP,MAAO,QAAUA,MAMzFR,EAAYjP,EAAI7H,YAAatJ,EAASiI,cAAc,QACpDmY,EAAUhV,MAAMmV,QAAUpP,EAAI/F,MAAMmV,QAAUF,EAC9CD,EAAUhV,MAAMyV,YAAcT,EAAUhV,MAAMwV,MAAQ,IACtDzP,EAAI/F,MAAMwV,MAAQ,MAElBlV,EAAQ8T,qBACNnY,YAAc3H,EAAOihB,iBAAkBP,EAAW,WAAeS,cAGpEP,EAAK/W,YAAa4W,MAGZzU,GArGCA,MAmHT,IAAIoV,GAAWC,EACdC,EAAS,+BACTC,EAAa,UAEd,SAASC,KAIRlX,OAAOmX,eAAgBpe,KAAK+N,SAAY,GACvC7M,IAAK,WACJ,YAIFlB,KAAKmD,QAAU9F,EAAO8F,QAAUC,KAAKC,SAGtC8a,EAAKE,IAAM,EAEXF,EAAKG,QAAU,SAAUC,GAOxB,MAAOA,GAAMhe,SACO,IAAnBge,EAAMhe,UAAqC,IAAnBge,EAAMhe,UAAiB,GAGjD4d,EAAKxe,WACJiI,IAAK,SAAU2W,GAId,IAAMJ,EAAKG,QAASC,GACnB,MAAO,EAGR,IAAIC,MAEHC,EAASF,EAAOve,KAAKmD,QAGtB,KAAMsb,EAAS,CACdA,EAASN,EAAKE,KAGd,KACCG,EAAYxe,KAAKmD,UAAc0D,MAAO4X,GACtCxX,OAAOyX,iBAAkBH,EAAOC,GAI/B,MAAQ/Z,GACT+Z,EAAYxe,KAAKmD,SAAYsb,EAC7BphB,EAAOoF,OAAQ8b,EAAOC,IASxB,MAJMxe,MAAK+N,MAAO0Q,KACjBze,KAAK+N,MAAO0Q,OAGNA,GAERE,IAAK,SAAUJ,EAAOzZ,EAAM+B,GAC3B,GAAI+X,GAIHH,EAASze,KAAK4H,IAAK2W,GACnBxQ,EAAQ/N,KAAK+N,MAAO0Q,EAGrB,IAAqB,gBAAT3Z,GACXiJ,EAAOjJ,GAAS+B,MAKhB,IAAKxJ,EAAOqH,cAAeqJ,GAC1B1Q,EAAOoF,OAAQzC,KAAK+N,MAAO0Q,GAAU3Z,OAGrC,KAAM8Z,IAAQ9Z,GACbiJ,EAAO6Q,GAAS9Z,EAAM8Z,EAIzB,OAAO7Q,IAER7M,IAAK,SAAUqd,EAAO3W,GAKrB,GAAImG,GAAQ/N,KAAK+N,MAAO/N,KAAK4H,IAAK2W,GAElC,OAAO3W,KAAQhL,UACdmR,EAAQA,EAAOnG,IAEjBD,OAAQ,SAAU4W,EAAO3W,EAAKf,GAC7B,GAAIgY,EAYJ,OAAKjX,KAAQhL,WACTgL,GAAsB,gBAARA,IAAqBf,IAAUjK,WAEhDiiB,EAAS7e,KAAKkB,IAAKqd,EAAO3W,GAEnBiX,IAAWjiB,UACjBiiB,EAAS7e,KAAKkB,IAAKqd,EAAOlhB,EAAOoJ,UAAUmB,MAS7C5H,KAAK2e,IAAKJ,EAAO3W,EAAKf,GAIfA,IAAUjK,UAAYiK,EAAQe,IAEtCxC,OAAQ,SAAUmZ,EAAO3W,GACxB,GAAI1F,GAAGS,EAAMmc,EACZL,EAASze,KAAK4H,IAAK2W,GACnBxQ,EAAQ/N,KAAK+N,MAAO0Q,EAErB,IAAK7W,IAAQhL,UACZoD,KAAK+N,MAAO0Q,UAEN,CAEDphB,EAAO6F,QAAS0E,GAOpBjF,EAAOiF,EAAIhK,OAAQgK,EAAIvF,IAAKhF,EAAOoJ,aAEnCqY,EAAQzhB,EAAOoJ,UAAWmB,GAErBA,IAAOmG,GACXpL,GAASiF,EAAKkX,IAIdnc,EAAOmc,EACPnc,EAAOA,IAAQoL,IACZpL,GAAWA,EAAK7C,MAAOf,SAI5BmD,EAAIS,EAAKzC,MACT,OAAQgC,UACA6L,GAAOpL,EAAMT,MAIvB6c,QAAS,SAAUR,GAClB,OAAQlhB,EAAOqH,cACd1E,KAAK+N,MAAOwQ,EAAOve,KAAKmD,gBAG1B6b,QAAS,SAAUT,GACbA,EAAOve,KAAKmD,gBACTnD,MAAK+N,MAAOwQ,EAAOve,KAAKmD,YAMlC4a,EAAY,GAAII,GAChBH,EAAY,GAAIG,GAGhB9gB,EAAOoF,QACNwc,WAAYd,EAAKG,QAEjBS,QAAS,SAAUhf,GAClB,MAAOge,GAAUgB,QAAShf,IAAUie,EAAUe,QAAShf,IAGxD+E,KAAM,SAAU/E,EAAM4C,EAAMmC,GAC3B,MAAOiZ,GAAUpW,OAAQ5H,EAAM4C,EAAMmC,IAGtCoa,WAAY,SAAUnf,EAAM4C,GAC3Bob,EAAU3Y,OAAQrF,EAAM4C,IAKzBwc,MAAO,SAAUpf,EAAM4C,EAAMmC,GAC5B,MAAOkZ,GAAUrW,OAAQ5H,EAAM4C,EAAMmC,IAGtCsa,YAAa,SAAUrf,EAAM4C,GAC5Bqb,EAAU5Y,OAAQrF,EAAM4C,MAI1BtF,EAAOsB,GAAG8D,QACTqC,KAAM,SAAU8C,EAAKf,GACpB,GAAIyH,GAAO3L,EACV5C,EAAOC,KAAM,GACbkC,EAAI,EACJ4C,EAAO,IAGR,IAAK8C,IAAQhL,UAAY,CACxB,GAAKoD,KAAKE,SACT4E,EAAOiZ,EAAU7c,IAAKnB,GAEC,IAAlBA,EAAKQ,WAAmByd,EAAU9c,IAAKnB,EAAM,iBAAmB,CAEpE,IADAuO,EAAQvO,EAAK6K,WACD0D,EAAMpO,OAAVgC,EAAkBA,IACzBS,EAAO2L,EAAOpM,GAAIS,KAEe,IAA5BA,EAAKzE,QAAS,WAClByE,EAAOtF,EAAOoJ,UAAW9D,EAAK3E,MAAM,IACpCqhB,EAAUtf,EAAM4C,EAAMmC,EAAMnC,IAG9Bqb,GAAUW,IAAK5e,EAAM,gBAAgB,GAIvC,MAAO+E,GAIR,MAAoB,gBAAR8C,GACJ5H,KAAKwB,KAAK,WAChBuc,EAAUY,IAAK3e,KAAM4H,KAIhBvK,EAAOsK,OAAQ3H,KAAM,SAAU6G,GACrC,GAAI/B,GACHwa,EAAWjiB,EAAOoJ,UAAWmB,EAO9B,IAAK7H,GAAQ8G,IAAUjK,UAAvB,CAIC,GADAkI,EAAOiZ,EAAU7c,IAAKnB,EAAM6H,GACvB9C,IAASlI,UACb,MAAOkI,EAMR,IADAA,EAAOiZ,EAAU7c,IAAKnB,EAAMuf,GACvBxa,IAASlI,UACb,MAAOkI,EAMR,IADAA,EAAOua,EAAUtf,EAAMuf,EAAU1iB,WAC5BkI,IAASlI,UACb,MAAOkI,OAQT9E,MAAKwB,KAAK,WAGT,GAAIsD,GAAOiZ,EAAU7c,IAAKlB,KAAMsf,EAKhCvB,GAAUY,IAAK3e,KAAMsf,EAAUzY,GAKL,KAArBe,EAAI1J,QAAQ,MAAe4G,IAASlI,WACxCmhB,EAAUY,IAAK3e,KAAM4H,EAAKf,MAG1B,KAAMA,EAAO/E,UAAU5B,OAAS,EAAG,MAAM,IAG7Cgf,WAAY,SAAUtX,GACrB,MAAO5H,MAAKwB,KAAK,WAChBuc,EAAU3Y,OAAQpF,KAAM4H,OAK3B,SAASyX,GAAUtf,EAAM6H,EAAK9C,GAC7B,GAAInC,EAIJ,IAAKmC,IAASlI,WAA+B,IAAlBmD,EAAKQ,SAI/B,GAHAoC,EAAO,QAAUiF,EAAItE,QAAS4a,EAAY,OAAQtX,cAClD9B,EAAO/E,EAAKuN,aAAc3K,GAEL,gBAATmC,GAAoB,CAC/B,IACCA,EAAgB,SAATA,GAAkB,EACf,UAATA,GAAmB,EACV,SAATA,EAAkB,MAEjBA,EAAO,KAAOA,GAAQA,EACvBmZ,EAAOxd,KAAMqE,GAASS,KAAKC,MAAOV,GAClCA,EACA,MAAOL,IAGTsZ,EAAUY,IAAK5e,EAAM6H,EAAK9C,OAE1BA,GAAOlI,SAGT,OAAOkI,GAERzH,EAAOoF,QACN8c,MAAO,SAAUxf,EAAMkE,EAAMa,GAC5B,GAAIya,EAEJ,OAAKxf,IACJkE,GAASA,GAAQ,MAAS,QAC1Bsb,EAAQvB,EAAU9c,IAAKnB,EAAMkE,GAGxBa,KACEya,GAASliB,EAAO6F,QAAS4B,GAC9Bya,EAAQvB,EAAUrW,OAAQ5H,EAAMkE,EAAM5G,EAAO0D,UAAU+D,IAEvDya,EAAMzhB,KAAMgH,IAGPya,OAZR,WAgBDC,QAAS,SAAUzf,EAAMkE,GACxBA,EAAOA,GAAQ,IAEf,IAAIsb,GAAQliB,EAAOkiB,MAAOxf,EAAMkE,GAC/Bwb,EAAcF,EAAMrf,OACpBvB,EAAK4gB,EAAMtR,QACXyR,EAAQriB,EAAOsiB,YAAa5f,EAAMkE,GAClC2b,EAAO,WACNviB,EAAOmiB,QAASzf,EAAMkE;CAIZ,gBAAPtF,IACJA,EAAK4gB,EAAMtR,QACXwR,KAGI9gB,IAIU,OAATsF,GACJsb,EAAMrO,QAAS,oBAITwO,GAAMG,KACblhB,EAAGsC,KAAMlB,EAAM6f,EAAMF,KAGhBD,GAAeC,GACpBA,EAAM7K,MAAMkF,QAKd4F,YAAa,SAAU5f,EAAMkE,GAC5B,GAAI2D,GAAM3D,EAAO,YACjB,OAAO+Z,GAAU9c,IAAKnB,EAAM6H,IAASoW,EAAUrW,OAAQ5H,EAAM6H,GAC5DiN,MAAOxX,EAAOgc,UAAU,eAAec,IAAI,WAC1C6D,EAAU5Y,OAAQrF,GAAQkE,EAAO,QAAS2D,WAM9CvK,EAAOsB,GAAG8D,QACT8c,MAAO,SAAUtb,EAAMa,GACtB,GAAIgb,GAAS,CAQb,OANqB,gBAAT7b,KACXa,EAAOb,EACPA,EAAO,KACP6b,KAGuBA,EAAnBhe,UAAU5B,OACP7C,EAAOkiB,MAAOvf,KAAK,GAAIiE,GAGxBa,IAASlI,UACfoD,KACAA,KAAKwB,KAAK,WACT,GAAI+d,GAAQliB,EAAOkiB,MAAOvf,KAAMiE,EAAMa,EAGtCzH,GAAOsiB,YAAa3f,KAAMiE,GAEZ,OAATA,GAA8B,eAAbsb,EAAM,IAC3BliB,EAAOmiB,QAASxf,KAAMiE,MAI1Bub,QAAS,SAAUvb,GAClB,MAAOjE,MAAKwB,KAAK,WAChBnE,EAAOmiB,QAASxf,KAAMiE,MAKxB8b,MAAO,SAAUC,EAAM/b,GAItB,MAHA+b,GAAO3iB,EAAO4iB,GAAK5iB,EAAO4iB,GAAGC,OAAQF,IAAUA,EAAOA,EACtD/b,EAAOA,GAAQ,KAERjE,KAAKuf,MAAOtb,EAAM,SAAU2b,EAAMF,GACxC,GAAIS,GAAU3X,WAAYoX,EAAMI,EAChCN,GAAMG,KAAO,WACZO,aAAcD,OAIjBE,WAAY,SAAUpc,GACrB,MAAOjE,MAAKuf,MAAOtb,GAAQ,UAI5BtC,QAAS,SAAUsC,EAAMD,GACxB,GAAI2B,GACH2a,EAAQ,EACRC,EAAQljB,EAAOiL,WACf8I,EAAWpR,KACXkC,EAAIlC,KAAKE,OACTkb,EAAU,aACCkF,GACTC,EAAM1c,YAAauN,GAAYA,IAIb,iBAATnN,KACXD,EAAMC,EACNA,EAAOrH,WAERqH,EAAOA,GAAQ,IAEf,OAAO/B,IACNyD,EAAMqY,EAAU9c,IAAKkQ,EAAUlP,GAAK+B,EAAO,cACtC0B,GAAOA,EAAIkP,QACfyL,IACA3a,EAAIkP,MAAMsF,IAAKiB,GAIjB,OADAA,KACOmF,EAAM5e,QAASqC,KAGxB,IAAIwc,GAAUC,EACbC,EAAS,cACTC,EAAU,MACVC,EAAa,qCAEdvjB,GAAOsB,GAAG8D,QACT7B,KAAM,SAAU+B,EAAMkE,GACrB,MAAOxJ,GAAOsK,OAAQ3H,KAAM3C,EAAOuD,KAAM+B,EAAMkE,EAAO/E,UAAU5B,OAAS,IAG1E2gB,WAAY,SAAUle,GACrB,MAAO3C,MAAKwB,KAAK,WAChBnE,EAAOwjB,WAAY7gB,KAAM2C,MAI3Bic,KAAM,SAAUjc,EAAMkE,GACrB,MAAOxJ,GAAOsK,OAAQ3H,KAAM3C,EAAOuhB,KAAMjc,EAAMkE,EAAO/E,UAAU5B,OAAS,IAG1E4gB,WAAY,SAAUne,GACrB,MAAO3C,MAAKwB,KAAK,iBACTxB,MAAM3C,EAAO0jB,QAASpe,IAAUA,MAIzCqe,SAAU,SAAUna,GACnB,GAAIoa,GAASlhB,EAAM2O,EAAKwS,EAAO9e,EAC9BF,EAAI,EACJC,EAAMnC,KAAKE,OACXihB,EAA2B,gBAAVta,IAAsBA,CAExC,IAAKxJ,EAAOsD,WAAYkG,GACvB,MAAO7G,MAAKwB,KAAK,SAAUY,GAC1B/E,EAAQ2C,MAAOghB,SAAUna,EAAM5F,KAAMjB,KAAMoC,EAAGpC,KAAKyP,aAIrD,IAAK0R,EAIJ,IAFAF,GAAYpa,GAAS,IAAK/G,MAAOf,OAErBoD,EAAJD,EAASA,IAOhB,GANAnC,EAAOC,KAAMkC,GACbwM,EAAwB,IAAlB3O,EAAKQ,WAAoBR,EAAK0P,WACjC,IAAM1P,EAAK0P,UAAY,KAAMnM,QAASod,EAAQ,KAChD,KAGU,CACVte,EAAI,CACJ,OAAS8e,EAAQD,EAAQ7e,KACgB,EAAnCsM,EAAIxQ,QAAS,IAAMgjB,EAAQ,OAC/BxS,GAAOwS,EAAQ,IAGjBnhB,GAAK0P,UAAYpS,EAAOmB,KAAMkQ,GAMjC,MAAO1O,OAGRohB,YAAa,SAAUva,GACtB,GAAIoa,GAASlhB,EAAM2O,EAAKwS,EAAO9e,EAC9BF,EAAI,EACJC,EAAMnC,KAAKE,OACXihB,EAA+B,IAArBrf,UAAU5B,QAAiC,gBAAV2G,IAAsBA,CAElE,IAAKxJ,EAAOsD,WAAYkG,GACvB,MAAO7G,MAAKwB,KAAK,SAAUY,GAC1B/E,EAAQ2C,MAAOohB,YAAava,EAAM5F,KAAMjB,KAAMoC,EAAGpC,KAAKyP,aAGxD,IAAK0R,EAGJ,IAFAF,GAAYpa,GAAS,IAAK/G,MAAOf,OAErBoD,EAAJD,EAASA,IAQhB,GAPAnC,EAAOC,KAAMkC,GAEbwM,EAAwB,IAAlB3O,EAAKQ,WAAoBR,EAAK0P,WACjC,IAAM1P,EAAK0P,UAAY,KAAMnM,QAASod,EAAQ,KAChD,IAGU,CACVte,EAAI,CACJ,OAAS8e,EAAQD,EAAQ7e,KAExB,MAAQsM,EAAIxQ,QAAS,IAAMgjB,EAAQ,MAAS,EAC3CxS,EAAMA,EAAIpL,QAAS,IAAM4d,EAAQ,IAAK,IAGxCnhB,GAAK0P,UAAY5I,EAAQxJ,EAAOmB,KAAMkQ,GAAQ,GAKjD,MAAO1O,OAGRqhB,YAAa,SAAUxa,EAAOya,GAC7B,GAAIrd,SAAc4C,EAElB,OAAyB,iBAAbya,IAAmC,WAATrd,EAC9Bqd,EAAWthB,KAAKghB,SAAUna,GAAU7G,KAAKohB,YAAava,GAGzDxJ,EAAOsD,WAAYkG,GAChB7G,KAAKwB,KAAK,SAAUU,GAC1B7E,EAAQ2C,MAAOqhB,YAAaxa,EAAM5F,KAAKjB,KAAMkC,EAAGlC,KAAKyP,UAAW6R,GAAWA,KAItEthB,KAAKwB,KAAK,WAChB,GAAc,WAATyC,EAAoB,CAExB,GAAIwL,GACHvN,EAAI,EACJ+X,EAAO5c,EAAQ2C,MACfuhB,EAAa1a,EAAM/G,MAAOf,MAE3B,OAAS0Q,EAAY8R,EAAYrf,KAE3B+X,EAAKuH,SAAU/R,GACnBwK,EAAKmH,YAAa3R,GAElBwK,EAAK+G,SAAUvR,QAKNxL,IAASlH,GAA8B,YAATkH,KACpCjE,KAAKyP,WAETuO,EAAUW,IAAK3e,KAAM,gBAAiBA,KAAKyP,WAO5CzP,KAAKyP,UAAYzP,KAAKyP,WAAa5I,KAAU,EAAQ,GAAKmX,EAAU9c,IAAKlB,KAAM,kBAAqB,OAKvGwhB,SAAU,SAAU/iB,GACnB,GAAIgR,GAAY,IAAMhR,EAAW,IAChCyD,EAAI,EACJkF,EAAIpH,KAAKE,MACV,MAAYkH,EAAJlF,EAAOA,IACd,GAA0B,IAArBlC,KAAKkC,GAAG3B,WAAmB,IAAMP,KAAKkC,GAAGuN,UAAY,KAAKnM,QAAQod,EAAQ,KAAKxiB,QAASuR,IAAe,EAC3G,OAAO,CAIT,QAAO,GAGR4B,IAAK,SAAUxK,GACd,GAAI6Y,GAAOpe,EAAKX,EACfZ,EAAOC,KAAK,EAEb,EAAA,GAAM8B,UAAU5B,OAsBhB,MAFAS,GAAatD,EAAOsD,WAAYkG,GAEzB7G,KAAKwB,KAAK,SAAUU,GAC1B,GAAImP,EAEmB,KAAlBrR,KAAKO,WAKT8Q,EADI1Q,EACEkG,EAAM5F,KAAMjB,KAAMkC,EAAG7E,EAAQ2C,MAAOqR,OAEpCxK,EAIK,MAAPwK,EACJA,EAAM,GACoB,gBAARA,GAClBA,GAAO,GACIhU,EAAO6F,QAASmO,KAC3BA,EAAMhU,EAAOgF,IAAIgP,EAAK,SAAWxK,GAChC,MAAgB,OAATA,EAAgB,GAAKA,EAAQ,MAItC6Y,EAAQriB,EAAOokB,SAAUzhB,KAAKiE,OAAU5G,EAAOokB,SAAUzhB,KAAK2G,SAASC,eAGjE8Y,GAAW,OAASA,IAAUA,EAAMf,IAAK3e,KAAMqR,EAAK,WAAczU,YACvEoD,KAAK6G,MAAQwK,KAjDd,IAAKtR,EAGJ,MAFA2f,GAAQriB,EAAOokB,SAAU1hB,EAAKkE,OAAU5G,EAAOokB,SAAU1hB,EAAK4G,SAASC,eAElE8Y,GAAS,OAASA,KAAUpe,EAAMoe,EAAMxe,IAAKnB,EAAM,YAAenD,UAC/D0E,GAGRA,EAAMvB,EAAK8G,MAEW,gBAARvF,GAEbA,EAAIgC,QAAQqd,EAAS,IAEd,MAAPrf,EAAc,GAAKA,OA0CxBjE,EAAOoF,QACNgf,UACCC,QACCxgB,IAAK,SAAUnB,GAGd,GAAIsR,GAAMtR,EAAK6K,WAAW/D,KAC1B,QAAQwK,GAAOA,EAAIC,UAAYvR,EAAK8G,MAAQ9G,EAAKsG,OAGnDwH,QACC3M,IAAK,SAAUnB,GACd,GAAI8G,GAAO6a,EACVhf,EAAU3C,EAAK2C,QACf0X,EAAQra,EAAK6U,cACb+M,EAAoB,eAAd5hB,EAAKkE,MAAiC,EAARmW,EACpC2B,EAAS4F,EAAM,QACfC,EAAMD,EAAMvH,EAAQ,EAAI1X,EAAQxC,OAChCgC,EAAY,EAARkY,EACHwH,EACAD,EAAMvH,EAAQ,CAGhB,MAAYwH,EAAJ1f,EAASA,IAIhB,GAHAwf,EAAShf,EAASR,MAGXwf,EAAO/M,UAAYzS,IAAMkY,IAE5B/c,EAAOsL,QAAQmU,YAAe4E,EAAOjN,SAA+C,OAApCiN,EAAOpU,aAAa,cACnEoU,EAAO5gB,WAAW2T,UAAapX,EAAOsJ,SAAU+a,EAAO5gB,WAAY,aAAiB,CAMxF,GAHA+F,EAAQxJ,EAAQqkB,GAASrQ,MAGpBsQ,EACJ,MAAO9a,EAIRkV,GAAOje,KAAM+I,GAIf,MAAOkV,IAGR4C,IAAK,SAAU5e,EAAM8G,GACpB,GAAIgb,GAAWH,EACdhf,EAAU3C,EAAK2C,QACfqZ,EAAS1e,EAAO0D,UAAW8F,GAC3B3E,EAAIQ,EAAQxC,MAEb,OAAQgC,IACPwf,EAAShf,EAASR,IACZwf,EAAO/M,SAAWtX,EAAO6J,QAAS7J,EAAOqkB,GAAQrQ,MAAO0K,IAAY,KACzE8F,GAAY,EAQd,OAHMA,KACL9hB,EAAK6U,cAAgB,IAEfmH,KAKVnb,KAAM,SAAUb,EAAM4C,EAAMkE,GAC3B,GAAI6Y,GAAOpe,EACVwgB,EAAQ/hB,EAAKQ,QAGd,IAAMR,GAAkB,IAAV+hB,GAAyB,IAAVA,GAAyB,IAAVA,EAK5C,aAAY/hB,GAAKuN,eAAiBvQ,EAC1BM,EAAOuhB,KAAM7e,EAAM4C,EAAMkE,IAKlB,IAAVib,GAAgBzkB,EAAO2b,SAAUjZ,KACrC4C,EAAOA,EAAKiE,cACZ8Y,EAAQriB,EAAO0kB,UAAWpf,KACvBtF,EAAO8T,KAAKrR,MAAM+L,KAAKpL,KAAMkC,GAAS8d,EAAWD,IAGhD3Z,IAAUjK,UAaH8iB,GAAS,OAASA,IAA6C,QAAnCpe,EAAMoe,EAAMxe,IAAKnB,EAAM4C,IACvDrB,GAGPA,EAAMjE,EAAO+C,KAAKQ,KAAMb,EAAM4C,GAGhB,MAAPrB,EACN1E,UACA0E,GApBc,OAAVuF,EAGO6Y,GAAS,OAASA,KAAUpe,EAAMoe,EAAMf,IAAK5e,EAAM8G,EAAOlE,MAAY/F,UAC1E0E,GAGPvB,EAAKwN,aAAc5K,EAAMkE,EAAQ,IAC1BA,IAPPxJ,EAAOwjB,WAAY9gB,EAAM4C,GAAzBtF,aAuBHwjB,WAAY,SAAU9gB,EAAM8G,GAC3B,GAAIlE,GAAMqf,EACT9f,EAAI,EACJ+f,EAAYpb,GAASA,EAAM/G,MAAOf,EAEnC,IAAKkjB,GAA+B,IAAlBliB,EAAKQ,SACtB,MAASoC,EAAOsf,EAAU/f,KACzB8f,EAAW3kB,EAAO0jB,QAASpe,IAAUA,EAGhCtF,EAAO8T,KAAKrR,MAAM+L,KAAKpL,KAAMkC,KAEjC5C,EAAMiiB,IAAa,GAGpBjiB,EAAK6N,gBAAiBjL,IAKzBof,WACC9d,MACC0a,IAAK,SAAU5e,EAAM8G,GACpB,IAAMxJ,EAAOsL,QAAQoU,YAAwB,UAAVlW,GAAqBxJ,EAAOsJ,SAAS5G,EAAM,SAAW,CAGxF,GAAIsR,GAAMtR,EAAK8G,KAKf,OAJA9G,GAAKwN,aAAc,OAAQ1G,GACtBwK,IACJtR,EAAK8G,MAAQwK,GAEPxK,MAMXka,SACCmB,MAAO,UACPC,QAAS,aAGVvD,KAAM,SAAU7e,EAAM4C,EAAMkE,GAC3B,GAAIvF,GAAKoe,EAAO0C,EACfN,EAAQ/hB,EAAKQ,QAGd,IAAMR,GAAkB,IAAV+hB,GAAyB,IAAVA,GAAyB,IAAVA,EAY5C,MARAM,GAAmB,IAAVN,IAAgBzkB,EAAO2b,SAAUjZ,GAErCqiB,IAEJzf,EAAOtF,EAAO0jB,QAASpe,IAAUA,EACjC+c,EAAQriB,EAAOglB,UAAW1f,IAGtBkE,IAAUjK,UACP8iB,GAAS,OAASA,KAAUpe,EAAMoe,EAAMf,IAAK5e,EAAM8G,EAAOlE,MAAY/F,UAC5E0E,EACEvB,EAAM4C,GAASkE,EAGX6Y,GAAS,OAASA,IAA6C,QAAnCpe,EAAMoe,EAAMxe,IAAKnB,EAAM4C,IACzDrB,EACAvB,EAAM4C,IAIT0f,WACC9N,UACCrT,IAAK,SAAUnB,GACd,MAAOA,GAAKuiB,aAAc,aAAgB1B,EAAWngB,KAAMV,EAAK4G,WAAc5G,EAAKuU,KAClFvU,EAAKwU,SACL,QAOLkM,GACC9B,IAAK,SAAU5e,EAAM8G,EAAOlE,GAO3B,MANKkE,MAAU,EAEdxJ,EAAOwjB,WAAY9gB,EAAM4C,GAEzB5C,EAAKwN,aAAc5K,EAAMA,GAEnBA,IAGTtF,EAAOmE,KAAMnE,EAAO8T,KAAKrR,MAAM+L,KAAK/M,OAAOgB,MAAO,QAAU,SAAUoC,EAAGS,GACxE,GAAI4f,GAASllB,EAAO8T,KAAK3C,WAAY7L,IAAUtF,EAAO+C,KAAKQ,IAE3DvD,GAAO8T,KAAK3C,WAAY7L,GAAS,SAAU5C,EAAM4C,EAAMoG,GACtD,GAAIpK,GAAKtB,EAAO8T,KAAK3C,WAAY7L,GAChCrB,EAAMyH,EACLnM,WAGCS,EAAO8T,KAAK3C,WAAY7L,GAAS/F,YACjC2lB,EAAQxiB,EAAM4C,EAAMoG,GAEpBpG,EAAKiE,cACL,IAKH,OAFAvJ,GAAO8T,KAAK3C,WAAY7L,GAAShE,EAE1B2C,KAMHjE,EAAOsL,QAAQ6T,cACpBnf,EAAOglB,UAAU1N,UAChBzT,IAAK,SAAUnB,GACd,GAAIsP,GAAStP,EAAKe,UAIlB,OAHKuO,IAAUA,EAAOvO,YACrBuO,EAAOvO,WAAW8T,cAEZ,QAKVvX,EAAOmE,MACN,WACA,WACA,YACA,cACA,cACA,UACA,UACA,SACA,cACA,mBACE,WACFnE,EAAO0jB,QAAS/gB,KAAK4G,eAAkB5G,OAIxC3C,EAAOmE,MAAO,QAAS,YAAc,WACpCnE,EAAOokB,SAAUzhB,OAChB2e,IAAK,SAAU5e,EAAM8G,GACpB,MAAKxJ,GAAO6F,QAAS2D,GACX9G,EAAK2U,QAAUrX,EAAO6J,QAAS7J,EAAO0C,GAAMsR,MAAOxK,IAAW,EADxE,YAKIxJ,EAAOsL,QAAQ4T,UACpBlf,EAAOokB,SAAUzhB,MAAOkB,IAAM,SAAUnB,GAGvC,MAAsC,QAA/BA,EAAKuN,aAAa,SAAoB,KAAOvN,EAAK8G,SAI5D,IAAI2b,GAAY,OACfC,EAAc,+BACdC,EAAc,kCACdC,EAAiB,sBAElB,SAASC,KACR,OAAO,EAGR,QAASC,KACR,OAAO,EAGR,QAASC,KACR,IACC,MAAO7lB,GAASmX,cACf,MAAQ2O,KAOX1lB,EAAO2lB,OAENC,UAEA9I,IAAK,SAAUpa,EAAMmjB,EAAO3U,EAASzJ,EAAMrG,GAE1C,GAAI0kB,GAAaC,EAAazd,EAC7B0d,EAAQC,EAAGC,EACXC,EAASC,EAAUxf,EAAMyf,EAAYC,EACrCC,EAAW5F,EAAU9c,IAAKnB,EAG3B,IAAM6jB,EAAN,CAKKrV,EAAQA,UACZ4U,EAAc5U,EACdA,EAAU4U,EAAY5U,QACtB9P,EAAW0kB,EAAY1kB,UAIlB8P,EAAQ9G,OACb8G,EAAQ9G,KAAOpK,EAAOoK,SAIhB4b,EAASO,EAASP,UACxBA,EAASO,EAASP,YAEZD,EAAcQ,EAASC,UAC7BT,EAAcQ,EAASC,OAAS,SAAUpf,GAGzC,aAAcpH,KAAWN,GAAuB0H,GAAKpH,EAAO2lB,MAAMc,YAAcrf,EAAER,KAEjFrH,UADAS,EAAO2lB,MAAMe,SAASliB,MAAOuhB,EAAYrjB,KAAM+B,YAIjDshB,EAAYrjB,KAAOA,GAIpBmjB,GAAUA,GAAS,IAAKpjB,MAAOf,KAAqB,IACpDukB,EAAIJ,EAAMhjB,MACV,OAAQojB,IACP3d,EAAMgd,EAAexiB,KAAM+iB,EAAMI,QACjCrf,EAAO0f,EAAWhe,EAAI,GACtB+d,GAAe/d,EAAI,IAAM,IAAK+C,MAAO,KAAMnG,OAGrC0B,IAKNuf,EAAUnmB,EAAO2lB,MAAMQ,QAASvf,OAGhCA,GAASxF,EAAW+kB,EAAQQ,aAAeR,EAAQS,WAAchgB,EAGjEuf,EAAUnmB,EAAO2lB,MAAMQ,QAASvf,OAGhCsf,EAAYlmB,EAAOoF,QAClBwB,KAAMA,EACN0f,SAAUA,EACV7e,KAAMA,EACNyJ,QAASA,EACT9G,KAAM8G,EAAQ9G,KACdhJ,SAAUA,EACVqN,aAAcrN,GAAYpB,EAAO8T,KAAKrR,MAAMgM,aAAarL,KAAMhC,GAC/DylB,UAAWR,EAAWjW,KAAK,MACzB0V,IAGIM,EAAWJ,EAAQpf,MACzBwf,EAAWJ,EAAQpf,MACnBwf,EAASU,cAAgB,EAGnBX,EAAQY,OAASZ,EAAQY,MAAMnjB,KAAMlB,EAAM+E,EAAM4e,EAAYN,MAAkB,GAC/ErjB,EAAK0I,kBACT1I,EAAK0I,iBAAkBxE,EAAMmf,GAAa,IAKxCI,EAAQrJ,MACZqJ,EAAQrJ,IAAIlZ,KAAMlB,EAAMwjB,GAElBA,EAAUhV,QAAQ9G,OACvB8b,EAAUhV,QAAQ9G,KAAO8G,EAAQ9G,OAK9BhJ,EACJglB,EAASjhB,OAAQihB,EAASU,gBAAiB,EAAGZ,GAE9CE,EAAS3lB,KAAMylB,GAIhBlmB,EAAO2lB,MAAMC,OAAQhf,IAAS,EAI/BlE,GAAO,OAIRqF,OAAQ,SAAUrF,EAAMmjB,EAAO3U,EAAS9P,EAAU4lB,GAEjD,GAAIjiB,GAAGkiB,EAAW3e,EACjB0d,EAAQC,EAAGC,EACXC,EAASC,EAAUxf,EAAMyf,EAAYC,EACrCC,EAAW5F,EAAUe,QAAShf,IAAUie,EAAU9c,IAAKnB,EAExD,IAAM6jB,IAAcP,EAASO,EAASP,QAAtC,CAKAH,GAAUA,GAAS,IAAKpjB,MAAOf,KAAqB,IACpDukB,EAAIJ,EAAMhjB,MACV,OAAQojB,IAMP,GALA3d,EAAMgd,EAAexiB,KAAM+iB,EAAMI,QACjCrf,EAAO0f,EAAWhe,EAAI,GACtB+d,GAAe/d,EAAI,IAAM,IAAK+C,MAAO,KAAMnG,OAGrC0B,EAAN,CAOAuf,EAAUnmB,EAAO2lB,MAAMQ,QAASvf,OAChCA,GAASxF,EAAW+kB,EAAQQ,aAAeR,EAAQS,WAAchgB,EACjEwf,EAAWJ,EAAQpf,OACnB0B,EAAMA,EAAI,IAAUoF,OAAQ,UAAY2Y,EAAWjW,KAAK,iBAAmB,WAG3E6W,EAAYliB,EAAIqhB,EAASvjB,MACzB,OAAQkC,IACPmhB,EAAYE,EAAUrhB,IAEfiiB,GAAeV,IAAaJ,EAAUI,UACzCpV,GAAWA,EAAQ9G,OAAS8b,EAAU9b,MACtC9B,IAAOA,EAAIlF,KAAM8iB,EAAUW,YAC3BzlB,GAAYA,IAAa8kB,EAAU9kB,WAAyB,OAAbA,IAAqB8kB,EAAU9kB,YACjFglB,EAASjhB,OAAQJ,EAAG,GAEfmhB,EAAU9kB,UACdglB,EAASU,gBAELX,EAAQpe,QACZoe,EAAQpe,OAAOnE,KAAMlB,EAAMwjB,GAOzBe,KAAcb,EAASvjB,SACrBsjB,EAAQe,UAAYf,EAAQe,SAAStjB,KAAMlB,EAAM2jB,EAAYE,EAASC,WAAa,GACxFxmB,EAAOmnB,YAAazkB,EAAMkE,EAAM2f,EAASC,cAGnCR,GAAQpf,QAtCf,KAAMA,IAAQof,GACbhmB,EAAO2lB,MAAM5d,OAAQrF,EAAMkE,EAAOif,EAAOI,GAAK/U,EAAS9P,GAAU,EA0C/DpB,GAAOqH,cAAe2e,WACnBO,GAASC,OAChB7F,EAAU5Y,OAAQrF,EAAM,aAI1B+D,QAAS,SAAUkf,EAAOle,EAAM/E,EAAM0kB,GAErC,GAAIviB,GAAGwM,EAAK/I,EAAK+e,EAAYC,EAAQd,EAAQL,EAC5CoB,GAAc7kB,GAAQ9C,GACtBgH,EAAO5F,EAAY4C,KAAM+hB,EAAO,QAAWA,EAAM/e,KAAO+e,EACxDU,EAAarlB,EAAY4C,KAAM+hB,EAAO,aAAgBA,EAAMkB,UAAUxb,MAAM,OAK7E,IAHAgG,EAAM/I,EAAM5F,EAAOA,GAAQ9C,EAGJ,IAAlB8C,EAAKQ,UAAoC,IAAlBR,EAAKQ,WAK5BmiB,EAAYjiB,KAAMwD,EAAO5G,EAAO2lB,MAAMc,aAItC7f,EAAK/F,QAAQ,MAAQ,IAEzBwlB,EAAazf,EAAKyE,MAAM,KACxBzE,EAAOyf,EAAWzV,QAClByV,EAAWnhB,QAEZoiB,EAA6B,EAApB1gB,EAAK/F,QAAQ,MAAY,KAAO+F,EAGzC+e,EAAQA,EAAO3lB,EAAO8F,SACrB6f,EACA,GAAI3lB,GAAOwnB,MAAO5gB,EAAuB,gBAAV+e,IAAsBA,GAGtDA,EAAM8B,UAAYL,EAAe,EAAI,EACrCzB,EAAMkB,UAAYR,EAAWjW,KAAK,KAClCuV,EAAM+B,aAAe/B,EAAMkB,UACtBnZ,OAAQ,UAAY2Y,EAAWjW,KAAK,iBAAmB,WAC3D,KAGDuV,EAAMpQ,OAAShW,UACTomB,EAAMhgB,SACXggB,EAAMhgB,OAASjD,GAIhB+E,EAAe,MAARA,GACJke,GACF3lB,EAAO0D,UAAW+D,GAAQke,IAG3BQ,EAAUnmB,EAAO2lB,MAAMQ,QAASvf,OAC1BwgB,IAAgBjB,EAAQ1f,SAAW0f,EAAQ1f,QAAQjC,MAAO9B,EAAM+E,MAAW,GAAjF,CAMA,IAAM2f,IAAiBjB,EAAQwB,WAAa3nB,EAAO8G,SAAUpE,GAAS,CAMrE,IAJA2kB,EAAalB,EAAQQ,cAAgB/f,EAC/Bye,EAAYjiB,KAAMikB,EAAazgB,KACpCyK,EAAMA,EAAI5N,YAEH4N,EAAKA,EAAMA,EAAI5N,WACtB8jB,EAAU9mB,KAAM4Q,GAChB/I,EAAM+I,CAIF/I,MAAS5F,EAAKS,eAAiBvD,IACnC2nB,EAAU9mB,KAAM6H,EAAI2J,aAAe3J,EAAIsf,cAAgBtoB,GAKzDuF,EAAI,CACJ,QAASwM,EAAMkW,EAAU1iB,QAAU8gB,EAAMkC,uBAExClC,EAAM/e,KAAO/B,EAAI,EAChBwiB,EACAlB,EAAQS,UAAYhgB,EAGrB4f,GAAW7F,EAAU9c,IAAKwN,EAAK,eAAoBsU,EAAM/e,OAAU+Z,EAAU9c,IAAKwN,EAAK,UAClFmV,GACJA,EAAOhiB,MAAO6M,EAAK5J,GAIpB+e,EAASc,GAAUjW,EAAKiW,GACnBd,GAAUxmB,EAAO4hB,WAAYvQ,IAASmV,EAAOhiB,OAASgiB,EAAOhiB,MAAO6M,EAAK5J,MAAW,GACxFke,EAAMmC,gBAkCR,OA/BAnC,GAAM/e,KAAOA,EAGPwgB,GAAiBzB,EAAMoC,sBAErB5B,EAAQ6B,UAAY7B,EAAQ6B,SAASxjB,MAAO+iB,EAAUta,MAAOxF,MAAW,IAC9EzH,EAAO4hB,WAAYlf,IAId4kB,GAAUtnB,EAAOsD,WAAYZ,EAAMkE,MAAa5G,EAAO8G,SAAUpE,KAGrE4F,EAAM5F,EAAM4kB,GAEPhf,IACJ5F,EAAM4kB,GAAW,MAIlBtnB,EAAO2lB,MAAMc,UAAY7f,EACzBlE,EAAMkE,KACN5G,EAAO2lB,MAAMc,UAAYlnB,UAEpB+I,IACJ5F,EAAM4kB,GAAWhf,IAMdqd,EAAMpQ,SAGdmR,SAAU,SAAUf,GAGnBA,EAAQ3lB,EAAO2lB,MAAMsC,IAAKtC,EAE1B,IAAI9gB,GAAGE,EAAGd,EAAKmS,EAAS8P,EACvBgC,KACA7jB,EAAO3D,EAAWkD,KAAMa,WACxB2hB,GAAazF,EAAU9c,IAAKlB,KAAM,eAAoBgjB,EAAM/e,UAC5Duf,EAAUnmB,EAAO2lB,MAAMQ,QAASR,EAAM/e,SAOvC,IAJAvC,EAAK,GAAKshB,EACVA,EAAMwC,eAAiBxlB,MAGlBwjB,EAAQiC,aAAejC,EAAQiC,YAAYxkB,KAAMjB,KAAMgjB,MAAY,EAAxE,CAKAuC,EAAeloB,EAAO2lB,MAAMS,SAASxiB,KAAMjB,KAAMgjB,EAAOS,GAGxDvhB,EAAI,CACJ,QAASuR,EAAU8R,EAAcrjB,QAAW8gB,EAAMkC,uBAAyB,CAC1ElC,EAAM0C,cAAgBjS,EAAQ1T,KAE9BqC,EAAI,CACJ,QAASmhB,EAAY9P,EAAQgQ,SAAUrhB,QAAW4gB,EAAM2C,kCAIjD3C,EAAM+B,cAAgB/B,EAAM+B,aAAatkB,KAAM8iB,EAAUW,cAE9DlB,EAAMO,UAAYA,EAClBP,EAAMle,KAAOye,EAAUze,KAEvBxD,IAASjE,EAAO2lB,MAAMQ,QAASD,EAAUI,eAAkBE,QAAUN,EAAUhV,SAC5E1M,MAAO4R,EAAQ1T,KAAM2B,GAEnBJ,IAAQ1E,YACNomB,EAAMpQ,OAAStR,MAAS,IAC7B0hB,EAAMmC,iBACNnC,EAAM4C,oBAYX,MAJKpC,GAAQqC,cACZrC,EAAQqC,aAAa5kB,KAAMjB,KAAMgjB,GAG3BA,EAAMpQ,SAGd6Q,SAAU,SAAUT,EAAOS,GAC1B,GAAIvhB,GAAGqH,EAASuc,EAAKvC,EACpBgC,KACApB,EAAgBV,EAASU,cACzBzV,EAAMsU,EAAMhgB,MAKb,IAAKmhB,GAAiBzV,EAAInO,YAAcyiB,EAAMjO,QAAyB,UAAfiO,EAAM/e,MAE7D,KAAQyK,IAAQ1O,KAAM0O,EAAMA,EAAI5N,YAAcd,KAG7C,GAAK0O,EAAI+F,YAAa,GAAuB,UAAfuO,EAAM/e,KAAmB,CAEtD,IADAsF,KACMrH,EAAI,EAAOiiB,EAAJjiB,EAAmBA,IAC/BqhB,EAAYE,EAAUvhB,GAGtB4jB,EAAMvC,EAAU9kB,SAAW,IAEtB8K,EAASuc,KAAUlpB,YACvB2M,EAASuc,GAAQvC,EAAUzX,aAC1BzO,EAAQyoB,EAAK9lB,MAAOoa,MAAO1L,IAAS,EACpCrR,EAAO+C,KAAM0lB,EAAK9lB,KAAM,MAAQ0O,IAAQxO,QAErCqJ,EAASuc,IACbvc,EAAQzL,KAAMylB,EAGXha,GAAQrJ,QACZqlB,EAAaznB,MAAOiC,KAAM2O,EAAK+U,SAAUla,IAW7C,MAJqBka,GAASvjB,OAAzBikB,GACJoB,EAAaznB,MAAOiC,KAAMC,KAAMyjB,SAAUA,EAASzlB,MAAOmmB,KAGpDoB,GAIRQ,MAAO,wHAAwHrd,MAAM,KAErIsd,YAEAC,UACCF,MAAO,4BAA4Brd,MAAM,KACzCqH,OAAQ,SAAUiT,EAAOkD,GAOxB,MAJoB,OAAflD,EAAMmD,QACVnD,EAAMmD,MAA6B,MAArBD,EAASE,SAAmBF,EAASE,SAAWF,EAASG,SAGjErD,IAITsD,YACCP,MAAO,uFAAuFrd,MAAM,KACpGqH,OAAQ,SAAUiT,EAAOkD,GACxB,GAAIK,GAAUnX,EAAKmO,EAClBxI,EAASmR,EAASnR,MAkBnB,OAfoB,OAAfiO,EAAMwD,OAAqC,MAApBN,EAASO,UACpCF,EAAWvD,EAAMhgB,OAAOxC,eAAiBvD,EACzCmS,EAAMmX,EAASppB,gBACfogB,EAAOgJ,EAAShJ,KAEhByF,EAAMwD,MAAQN,EAASO,SAAYrX,GAAOA,EAAIsX,YAAcnJ,GAAQA,EAAKmJ,YAAc,IAAQtX,GAAOA,EAAIuX,YAAcpJ,GAAQA,EAAKoJ,YAAc,GACnJ3D,EAAM4D,MAAQV,EAASW,SAAYzX,GAAOA,EAAI0X,WAAcvJ,GAAQA,EAAKuJ,WAAc,IAAQ1X,GAAOA,EAAI2X,WAAcxJ,GAAQA,EAAKwJ,WAAc,IAK9I/D,EAAMmD,OAASpR,IAAWnY,YAC/BomB,EAAMmD,MAAmB,EAATpR,EAAa,EAAe,EAATA,EAAa,EAAe,EAATA,EAAa,EAAI,GAGjEiO,IAITsC,IAAK,SAAUtC,GACd,GAAKA,EAAO3lB,EAAO8F,SAClB,MAAO6f,EAIR,IAAI9gB,GAAG0c,EAAM/b,EACZoB,EAAO+e,EAAM/e,KACb+iB,EAAgBhE,EAChBiE,EAAUjnB,KAAKgmB,SAAU/hB,EAEpBgjB,KACLjnB,KAAKgmB,SAAU/hB,GAASgjB,EACvBxE,EAAYhiB,KAAMwD,GAASjE,KAAKsmB,WAChC9D,EAAU/hB,KAAMwD,GAASjE,KAAKimB,aAGhCpjB,EAAOokB,EAAQlB,MAAQ/lB,KAAK+lB,MAAMnoB,OAAQqpB,EAAQlB,OAAU/lB,KAAK+lB,MAEjE/C,EAAQ,GAAI3lB,GAAOwnB,MAAOmC,GAE1B9kB,EAAIW,EAAK3C,MACT,OAAQgC,IACP0c,EAAO/b,EAAMX,GACb8gB,EAAOpE,GAASoI,EAAepI,EAehC,OAVMoE,GAAMhgB,SACXggB,EAAMhgB,OAAS/F,GAKe,IAA1B+lB,EAAMhgB,OAAOzC,WACjByiB,EAAMhgB,OAASggB,EAAMhgB,OAAOlC,YAGtBmmB,EAAQlX,OAAQkX,EAAQlX,OAAQiT,EAAOgE,GAAkBhE,GAGjEQ,SACC0D,MAEClC,UAAU,GAEX7Q,OAECrQ,QAAS,WACR,MAAK9D,QAAS8iB,KAAuB9iB,KAAKmU,OACzCnU,KAAKmU,SACE,GAFR,WAKD6P,aAAc,WAEfmD,MACCrjB,QAAS,WACR,MAAK9D,QAAS8iB,KAAuB9iB,KAAKmnB,MACzCnnB,KAAKmnB,QACE,GAFR,WAKDnD,aAAc,YAEfoD,OAECtjB,QAAS,WACR,MAAmB,aAAd9D,KAAKiE,MAAuBjE,KAAKonB,OAAS/pB,EAAOsJ,SAAU3G,KAAM,UACrEA,KAAKonB,SACE,GAFR,WAOD/B,SAAU,SAAUrC,GACnB,MAAO3lB,GAAOsJ,SAAUqc,EAAMhgB,OAAQ,OAIxCqkB,cACCxB,aAAc,SAAU7C,GAIlBA,EAAMpQ,SAAWhW,YACrBomB,EAAMgE,cAAcM,YAActE,EAAMpQ,WAM5C2U,SAAU,SAAUtjB,EAAMlE,EAAMijB,EAAOwE,GAItC,GAAI/iB,GAAIpH,EAAOoF,OACd,GAAIpF,GAAOwnB,MACX7B,GAEC/e,KAAMA,EACNwjB,aAAa,EACbT,kBAGGQ,GACJnqB,EAAO2lB,MAAMlf,QAASW,EAAG,KAAM1E,GAE/B1C,EAAO2lB,MAAMe,SAAS9iB,KAAMlB,EAAM0E,GAE9BA,EAAE2gB,sBACNpC,EAAMmC,mBAKT9nB,EAAOmnB,YAAc,SAAUzkB,EAAMkE,EAAM4f,GACrC9jB,EAAKN,qBACTM,EAAKN,oBAAqBwE,EAAM4f,GAAQ,IAI1CxmB,EAAOwnB,MAAQ,SAAUjiB,EAAKmjB,GAE7B,MAAO/lB,gBAAgB3C,GAAOwnB,OAKzBjiB,GAAOA,EAAIqB,MACfjE,KAAKgnB,cAAgBpkB,EACrB5C,KAAKiE,KAAOrB,EAAIqB,KAIhBjE,KAAKolB,mBAAuBxiB,EAAI8kB,kBAC/B9kB,EAAI+kB,mBAAqB/kB,EAAI+kB,oBAAwB/E,EAAaC,GAInE7iB,KAAKiE,KAAOrB,EAIRmjB,GACJ1oB,EAAOoF,OAAQzC,KAAM+lB,GAItB/lB,KAAK4nB,UAAYhlB,GAAOA,EAAIglB,WAAavqB,EAAO4K,MAGhDjI,KAAM3C,EAAO8F,UAAY,EAvBzB,WAJQ,GAAI9F,GAAOwnB,MAAOjiB,EAAKmjB,IAgChC1oB,EAAOwnB,MAAMllB,WACZylB,mBAAoBvC,EACpBqC,qBAAsBrC,EACtB8C,8BAA+B9C,EAE/BsC,eAAgB,WACf,GAAI1gB,GAAIzE,KAAKgnB,aAEbhnB,MAAKolB,mBAAqBxC,EAErBne,GAAKA,EAAE0gB,gBACX1gB,EAAE0gB,kBAGJS,gBAAiB,WAChB,GAAInhB,GAAIzE,KAAKgnB,aAEbhnB,MAAKklB,qBAAuBtC,EAEvBne,GAAKA,EAAEmhB,iBACXnhB,EAAEmhB,mBAGJiC,yBAA0B,WACzB7nB,KAAK2lB,8BAAgC/C,EACrC5iB,KAAK4lB,oBAMPvoB,EAAOmE,MACNsmB,WAAY,YACZC,WAAY,YACV,SAAUC,EAAM1C,GAClBjoB,EAAO2lB,MAAMQ,QAASwE,IACrBhE,aAAcsB,EACdrB,SAAUqB,EAEVzB,OAAQ,SAAUb,GACjB,GAAI1hB,GACH0B,EAAShD,KACTioB,EAAUjF,EAAMkF,cAChB3E,EAAYP,EAAMO,SASnB,SALM0E,GAAYA,IAAYjlB,IAAW3F,EAAOmM,SAAUxG,EAAQilB,MACjEjF,EAAM/e,KAAOsf,EAAUI,SACvBriB,EAAMiiB,EAAUhV,QAAQ1M,MAAO7B,KAAM8B,WACrCkhB,EAAM/e,KAAOqhB,GAEPhkB,MAOJjE,EAAOsL,QAAQsU,gBACpB5f,EAAOmE,MAAO2S,MAAO,UAAWgT,KAAM,YAAc,SAAUa,EAAM1C,GAGnE,GAAI6C,GAAW,EACd5Z,EAAU,SAAUyU,GACnB3lB,EAAO2lB,MAAMuE,SAAUjC,EAAKtC,EAAMhgB,OAAQ3F,EAAO2lB,MAAMsC,IAAKtC,IAAS,GAGvE3lB,GAAO2lB,MAAMQ,QAAS8B,IACrBlB,MAAO,WACc,IAAf+D,KACJlrB,EAASwL,iBAAkBuf,EAAMzZ,GAAS,IAG5CgW,SAAU,WACW,MAAb4D,GACNlrB,EAASwC,oBAAqBuoB,EAAMzZ,GAAS,OAOlDlR,EAAOsB,GAAG8D,QAET2lB,GAAI,SAAUlF,EAAOzkB,EAAUqG,EAAMnG,EAAiBgjB,GACrD,GAAI0G,GAAQpkB,CAGZ,IAAsB,gBAAVif,GAAqB,CAEP,gBAAbzkB,KAEXqG,EAAOA,GAAQrG,EACfA,EAAW7B,UAEZ,KAAMqH,IAAQif,GACbljB,KAAKooB,GAAInkB,EAAMxF,EAAUqG,EAAMoe,EAAOjf,GAAQ0d,EAE/C,OAAO3hB,MAmBR,GAhBa,MAAR8E,GAAsB,MAANnG,GAEpBA,EAAKF,EACLqG,EAAOrG,EAAW7B,WACD,MAAN+B,IACc,gBAAbF,IAEXE,EAAKmG,EACLA,EAAOlI,YAGP+B,EAAKmG,EACLA,EAAOrG,EACPA,EAAW7B,YAGR+B,KAAO,EACXA,EAAKkkB,MACC,KAAMlkB,EACZ,MAAOqB,KAaR,OAVa,KAAR2hB,IACJ0G,EAAS1pB,EACTA,EAAK,SAAUqkB,GAGd,MADA3lB,KAAS0G,IAAKif,GACPqF,EAAOxmB,MAAO7B,KAAM8B,YAG5BnD,EAAG8I,KAAO4gB,EAAO5gB,OAAU4gB,EAAO5gB,KAAOpK,EAAOoK,SAE1CzH,KAAKwB,KAAM,WACjBnE,EAAO2lB,MAAM7I,IAAKna,KAAMkjB,EAAOvkB,EAAImG,EAAMrG,MAG3CkjB,IAAK,SAAUuB,EAAOzkB,EAAUqG,EAAMnG,GACrC,MAAOqB,MAAKooB,GAAIlF,EAAOzkB,EAAUqG,EAAMnG,EAAI,IAE5CoF,IAAK,SAAUmf,EAAOzkB,EAAUE,GAC/B,GAAI4kB,GAAWtf,CACf,IAAKif,GAASA,EAAMiC,gBAAkBjC,EAAMK,UAQ3C,MANAA,GAAYL,EAAMK,UAClBlmB,EAAQ6lB,EAAMsC,gBAAiBzhB,IAC9Bwf,EAAUW,UAAYX,EAAUI,SAAW,IAAMJ,EAAUW,UAAYX,EAAUI,SACjFJ,EAAU9kB,SACV8kB,EAAUhV,SAEJvO,IAER,IAAsB,gBAAVkjB,GAAqB,CAEhC,IAAMjf,IAAQif,GACbljB,KAAK+D,IAAKE,EAAMxF,EAAUykB,EAAOjf,GAElC,OAAOjE,MAUR,OARKvB,KAAa,GAA6B,kBAAbA,MAEjCE,EAAKF,EACLA,EAAW7B,WAEP+B,KAAO,IACXA,EAAKkkB,GAEC7iB,KAAKwB,KAAK,WAChBnE,EAAO2lB,MAAM5d,OAAQpF,KAAMkjB,EAAOvkB,EAAIF,MAIxCqF,QAAS,SAAUG,EAAMa,GACxB,MAAO9E,MAAKwB,KAAK,WAChBnE,EAAO2lB,MAAMlf,QAASG,EAAMa,EAAM9E,SAGpCsoB,eAAgB,SAAUrkB,EAAMa,GAC/B,GAAI/E,GAAOC,KAAK,EAChB,OAAKD,GACG1C,EAAO2lB,MAAMlf,QAASG,EAAMa,EAAM/E,GAAM,GADhD,YAKF,IAAIwoB,GAAW,iBACdC,EAAe,iCACfC,EAAgBprB,EAAO8T,KAAKrR,MAAMgM,aAElC4c,GACCC,UAAU,EACVC,UAAU,EACVhJ,MAAM,EACNiJ,MAAM,EAGRxrB,GAAOsB,GAAG8D,QACTrC,KAAM,SAAU3B,GACf,GAAIyD,GACHZ,KACA2Y,EAAOja,KACPmC,EAAM8X,EAAK/Z,MAEZ,IAAyB,gBAAbzB,GACX,MAAOuB,MAAKoB,UAAW/D,EAAQoB,GAAWsR,OAAO,WAChD,IAAM7N,EAAI,EAAOC,EAAJD,EAASA,IACrB,GAAK7E,EAAOmM,SAAUyQ,EAAM/X,GAAKlC,MAChC,OAAO,IAMX,KAAMkC,EAAI,EAAOC,EAAJD,EAASA,IACrB7E,EAAO+C,KAAM3B,EAAUwb,EAAM/X,GAAKZ,EAMnC,OAFAA,GAAMtB,KAAKoB,UAAWe,EAAM,EAAI9E,EAAO0b,OAAQzX,GAAQA,GACvDA,EAAI7C,SAAWuB,KAAKvB,SAAWuB,KAAKvB,SAAW,IAAMA,EAAWA,EACzD6C,GAGRuS,IAAK,SAAU7Q,GACd,GAAI8lB,GAAUzrB,EAAQ2F,EAAQhD,MAC7BoH,EAAI0hB,EAAQ5oB,MAEb,OAAOF,MAAK+P,OAAO,WAClB,GAAI7N,GAAI,CACR,MAAYkF,EAAJlF,EAAOA,IACd,GAAK7E,EAAOmM,SAAUxJ,KAAM8oB,EAAQ5mB,IACnC,OAAO,KAMXwR,IAAK,SAAUjV,GACd,MAAOuB,MAAKoB,UAAW2nB,GAAO/oB,KAAMvB,OAAgB,KAGrDsR,OAAQ,SAAUtR,GACjB,MAAOuB,MAAKoB,UAAW2nB,GAAO/oB,KAAMvB,OAAgB,KAGrDuqB,GAAI,SAAUvqB,GACb,QAASsqB,GACR/oB,KAIoB,gBAAbvB,IAAyBgqB,EAAchoB,KAAMhC,GACnDpB,EAAQoB,GACRA,OACD,GACCyB,QAGH+oB,QAAS,SAAUpX,EAAWnT,GAC7B,GAAIgQ,GACHxM,EAAI,EACJkF,EAAIpH,KAAKE,OACTuT,KACAyV,EAAQT,EAAchoB,KAAMoR,IAAoC,gBAAdA,GACjDxU,EAAQwU,EAAWnT,GAAWsB,KAAKtB,SACnC,CAEF,MAAY0I,EAAJlF,EAAOA,IACd,IAAMwM,EAAM1O,KAAKkC,GAAIwM,GAAOA,IAAQhQ,EAASgQ,EAAMA,EAAI5N,WAEtD,GAAoB,GAAf4N,EAAInO,WAAkB2oB,EAC1BA,EAAI9O,MAAM1L,GAAO,GAGA,IAAjBA,EAAInO,UACHlD,EAAO+C,KAAKgQ,gBAAgB1B,EAAKmD,IAAc,CAEhDnD,EAAM+E,EAAQ3V,KAAM4Q,EACpB,OAKH,MAAO1O,MAAKoB,UAAWqS,EAAQvT,OAAS,EAAI7C,EAAO0b,OAAQtF,GAAYA,IAKxE2G,MAAO,SAAUra,GAGhB,MAAMA,GAKe,gBAATA,GACJ9B,EAAagD,KAAM5D,EAAQ0C,GAAQC,KAAM,IAI1C/B,EAAagD,KAAMjB,KAGzBD,EAAKH,OAASG,EAAM,GAAMA,GAZjBC,KAAM,IAAOA,KAAM,GAAIc,WAAed,KAAK+B,QAAQonB,UAAUjpB,OAAS,IAgBjFia,IAAK,SAAU1b,EAAUC,GACxB,GAAIigB,GAA0B,gBAAblgB,GACfpB,EAAQoB,EAAUC,GAClBrB,EAAO0D,UAAWtC,GAAYA,EAAS8B,UAAa9B,GAAaA,GAClEY,EAAMhC,EAAOgD,MAAOL,KAAKkB,MAAOyd,EAEjC,OAAO3e,MAAKoB,UAAW/D,EAAO0b,OAAO1Z,KAGtC+pB,QAAS,SAAU3qB,GAClB,MAAOuB,MAAKma,IAAiB,MAAZ1b,EAChBuB,KAAKuB,WAAavB,KAAKuB,WAAWwO,OAAOtR,MAK5C,SAAS4qB,GAAS3a,EAAKuD,GACtB,OAASvD,EAAMA,EAAIuD,KAA0B,IAAjBvD,EAAInO,UAEhC,MAAOmO,GAGRrR,EAAOmE,MACN6N,OAAQ,SAAUtP,GACjB,GAAIsP,GAAStP,EAAKe,UAClB,OAAOuO,IAA8B,KAApBA,EAAO9O,SAAkB8O,EAAS,MAEpDia,QAAS,SAAUvpB,GAClB,MAAO1C,GAAO4U,IAAKlS,EAAM,eAE1BwpB,aAAc,SAAUxpB,EAAMmC,EAAGsnB,GAChC,MAAOnsB,GAAO4U,IAAKlS,EAAM,aAAcypB,IAExC5J,KAAM,SAAU7f,GACf,MAAOspB,GAAStpB,EAAM,gBAEvB8oB,KAAM,SAAU9oB,GACf,MAAOspB,GAAStpB,EAAM,oBAEvB0pB,QAAS,SAAU1pB,GAClB,MAAO1C,GAAO4U,IAAKlS,EAAM,gBAE1BopB,QAAS,SAAUppB,GAClB,MAAO1C,GAAO4U,IAAKlS,EAAM,oBAE1B2pB,UAAW,SAAU3pB,EAAMmC,EAAGsnB,GAC7B,MAAOnsB,GAAO4U,IAAKlS,EAAM,cAAeypB,IAEzCG,UAAW,SAAU5pB,EAAMmC,EAAGsnB,GAC7B,MAAOnsB,GAAO4U,IAAKlS,EAAM,kBAAmBypB,IAE7CI,SAAU,SAAU7pB,GACnB,MAAO1C,GAAOgsB,SAAWtpB,EAAKe,gBAAmB8O,WAAY7P,IAE9D4oB,SAAU,SAAU5oB,GACnB,MAAO1C,GAAOgsB,QAAStpB,EAAK6P,aAE7BgZ,SAAU,SAAU7oB,GACnB,MAAOA,GAAK8pB,iBAAmBxsB,EAAOgD,SAAWN,EAAKsF,cAErD,SAAU1C,EAAMhE,GAClBtB,EAAOsB,GAAIgE,GAAS,SAAU6mB,EAAO/qB,GACpC,GAAIgV,GAAUpW,EAAOgF,IAAKrC,KAAMrB,EAAI6qB,EAsBpC,OApB0B,UAArB7mB,EAAK3E,MAAO,MAChBS,EAAW+qB,GAGP/qB,GAAgC,gBAAbA,KACvBgV,EAAUpW,EAAO0S,OAAQtR,EAAUgV,IAG/BzT,KAAKE,OAAS,IAEZwoB,EAAkB/lB,IACvBtF,EAAO0b,OAAQtF,GAIX+U,EAAa/nB,KAAMkC,IACvB8Q,EAAQqW,WAIH9pB,KAAKoB,UAAWqS,MAIzBpW,EAAOoF,QACNsN,OAAQ,SAAUoB,EAAM9P,EAAOqS,GAC9B,GAAI3T,GAAOsB,EAAO,EAMlB,OAJKqS,KACJvC,EAAO,QAAUA,EAAO,KAGD,IAAjB9P,EAAMnB,QAAkC,IAAlBH,EAAKQ,SACjClD,EAAO+C,KAAKgQ,gBAAiBrQ,EAAMoR,IAAWpR,MAC9C1C,EAAO+C,KAAKmJ,QAAS4H,EAAM9T,EAAOgK,KAAMhG,EAAO,SAAUtB,GACxD,MAAyB,KAAlBA,EAAKQ,aAIf0R,IAAK,SAAUlS,EAAMkS,EAAKuX,GACzB,GAAI/V,MACHsW,EAAWP,IAAU5sB,SAEtB,QAASmD,EAAOA,EAAMkS,KAA4B,IAAlBlS,EAAKQ,SACpC,GAAuB,IAAlBR,EAAKQ,SAAiB,CAC1B,GAAKwpB,GAAY1sB,EAAQ0C,GAAOipB,GAAIQ,GACnC,KAED/V,GAAQ3V,KAAMiC,GAGhB,MAAO0T,IAGR4V,QAAS,SAAUW,EAAGjqB,GACrB,GAAI0T,KAEJ,MAAQuW,EAAGA,EAAIA,EAAEnb,YACI,IAAfmb,EAAEzpB,UAAkBypB,IAAMjqB,GAC9B0T,EAAQ3V,KAAMksB,EAIhB,OAAOvW,KAKT,SAASsV,IAAQ3X,EAAU6Y,EAAWvW,GACrC,GAAKrW,EAAOsD,WAAYspB,GACvB,MAAO5sB,GAAOgK,KAAM+J,EAAU,SAAUrR,EAAMmC,GAE7C,QAAS+nB,EAAUhpB,KAAMlB,EAAMmC,EAAGnC,KAAW2T,GAK/C,IAAKuW,EAAU1pB,SACd,MAAOlD,GAAOgK,KAAM+J,EAAU,SAAUrR,GACvC,MAASA,KAASkqB,IAAgBvW,GAKpC,IAA0B,gBAAduW,GAAyB,CACpC,GAAK1B,EAAS9nB,KAAMwpB,GACnB,MAAO5sB,GAAO0S,OAAQka,EAAW7Y,EAAUsC,EAG5CuW,GAAY5sB,EAAO0S,OAAQka,EAAW7Y,GAGvC,MAAO/T,GAAOgK,KAAM+J,EAAU,SAAUrR,GACvC,MAAS9B,GAAagD,KAAMgpB,EAAWlqB,IAAU,IAAQ2T,IAG3D,GAAIwW,IAAY,0EACfC,GAAW,YACXC,GAAQ,YACRC,GAAe,0BACfC,GAA8B,wBAE9BC,GAAW,oCACXC,GAAc,4BACdC,GAAoB,cACpBC,GAAe,2CAGfC,IAGCjJ,QAAU,EAAG,+BAAgC,aAE7CkJ,OAAS,EAAG,UAAW,YACvBC,KAAO,EAAG,oBAAqB,uBAC/BC,IAAM,EAAG,iBAAkB,oBAC3BC,IAAM,EAAG,qBAAsB,yBAE/B1F,UAAY,EAAG,GAAI,IAIrBsF,IAAQK,SAAWL,GAAQjJ,OAE3BiJ,GAAQM,MAAQN,GAAQO,MAAQP,GAAQQ,SAAWR,GAAQS,QAAUT,GAAQC,MAC7ED,GAAQU,GAAKV,GAAQI,GAErB1tB,EAAOsB,GAAG8D,QACT4D,KAAM,SAAUQ,GACf,MAAOxJ,GAAOsK,OAAQ3H,KAAM,SAAU6G,GACrC,MAAOA,KAAUjK,UAChBS,EAAOgJ,KAAMrG,MACbA,KAAK6U,QAAQyW,QAAUtrB,KAAM,IAAOA,KAAM,GAAIQ,eAAiBvD,GAAWsuB,eAAgB1kB,KACzF,KAAMA,EAAO/E,UAAU5B,SAG3BorB,OAAQ,WACP,MAAOtrB,MAAKwrB,SAAU1pB,UAAW,SAAU/B,GAC1C,GAAuB,IAAlBC,KAAKO,UAAoC,KAAlBP,KAAKO,UAAqC,IAAlBP,KAAKO,SAAiB,CACzE,GAAIyC,GAASyoB,GAAoBzrB,KAAMD,EACvCiD,GAAOuD,YAAaxG,OAKvB2rB,QAAS,WACR,MAAO1rB,MAAKwrB,SAAU1pB,UAAW,SAAU/B,GAC1C,GAAuB,IAAlBC,KAAKO,UAAoC,KAAlBP,KAAKO,UAAqC,IAAlBP,KAAKO,SAAiB,CACzE,GAAIyC,GAASyoB,GAAoBzrB,KAAMD,EACvCiD,GAAO2oB,aAAc5rB,EAAMiD,EAAO4M,gBAKrCgc,OAAQ,WACP,MAAO5rB,MAAKwrB,SAAU1pB,UAAW,SAAU/B,GACrCC,KAAKc,YACTd,KAAKc,WAAW6qB,aAAc5rB,EAAMC,SAKvC6rB,MAAO,WACN,MAAO7rB,MAAKwrB,SAAU1pB,UAAW,SAAU/B,GACrCC,KAAKc,YACTd,KAAKc,WAAW6qB,aAAc5rB,EAAMC,KAAK6O,gBAM5CzJ,OAAQ,SAAU3G,EAAUqtB,GAC3B,GAAI/rB,GACHsB,EAAQ5C,EAAWpB,EAAO0S,OAAQtR,EAAUuB,MAASA,KACrDkC,EAAI,CAEL,MAA6B,OAApBnC,EAAOsB,EAAMa,IAAaA,IAC5B4pB,GAA8B,IAAlB/rB,EAAKQ,UACtBlD,EAAO0uB,UAAWC,GAAQjsB,IAGtBA,EAAKe,aACJgrB,GAAYzuB,EAAOmM,SAAUzJ,EAAKS,cAAeT,IACrDksB,GAAeD,GAAQjsB,EAAM,WAE9BA,EAAKe,WAAW0F,YAAazG,GAI/B,OAAOC,OAGR6U,MAAO,WACN,GAAI9U,GACHmC,EAAI,CAEL,MAA4B,OAAnBnC,EAAOC,KAAKkC,IAAaA,IACV,IAAlBnC,EAAKQ,WAGTlD,EAAO0uB,UAAWC,GAAQjsB,GAAM,IAGhCA,EAAK4R,YAAc,GAIrB,OAAO3R,OAGR+C,MAAO,SAAUmpB,EAAeC,GAI/B,MAHAD,GAAiC,MAAjBA,GAAwB,EAAQA,EAChDC,EAAyC,MAArBA,EAA4BD,EAAgBC,EAEzDnsB,KAAKqC,IAAK,WAChB,MAAOhF,GAAO0F,MAAO/C,KAAMksB,EAAeC,MAI5CC,KAAM,SAAUvlB,GACf,MAAOxJ,GAAOsK,OAAQ3H,KAAM,SAAU6G,GACrC,GAAI9G,GAAOC,KAAM,OAChBkC,EAAI,EACJkF,EAAIpH,KAAKE,MAEV,IAAK2G,IAAUjK,WAA+B,IAAlBmD,EAAKQ,SAChC,MAAOR,GAAK4P,SAIb,IAAsB,gBAAV9I,KAAuBwjB,GAAa5pB,KAAMoG,KACpD8jB,IAAWR,GAAShqB,KAAM0G,KAAa,GAAI,KAAQ,GAAID,eAAkB,CAE1EC,EAAQA,EAAMvD,QAAS4mB,GAAW,YAElC,KACC,KAAY9iB,EAAJlF,EAAOA,IACdnC,EAAOC,KAAMkC,OAGU,IAAlBnC,EAAKQ,WACTlD,EAAO0uB,UAAWC,GAAQjsB,GAAM,IAChCA,EAAK4P,UAAY9I,EAInB9G,GAAO,EAGN,MAAO0E,KAGL1E,GACJC,KAAK6U,QAAQyW,OAAQzkB,IAEpB,KAAMA,EAAO/E,UAAU5B,SAG3BmsB,YAAa,WACZ,GAEC3qB,GAAOrE,EAAOgF,IAAKrC,KAAM,SAAUD,GAClC,OAASA,EAAK8O,YAAa9O,EAAKe,cAEjCoB,EAAI,CAmBL,OAhBAlC,MAAKwrB,SAAU1pB,UAAW,SAAU/B,GACnC,GAAI6f,GAAOle,EAAMQ,KAChBmN,EAAS3N,EAAMQ,IAEXmN,KAECuQ,GAAQA,EAAK9e,aAAeuO,IAChCuQ,EAAO5f,KAAK6O,aAEbxR,EAAQ2C,MAAOoF,SACfiK,EAAOsc,aAAc5rB,EAAM6f,MAG1B,GAGI1d,EAAIlC,KAAOA,KAAKoF,UAGxBknB,OAAQ,SAAU7tB,GACjB,MAAOuB,MAAKoF,OAAQ3G,GAAU,IAG/B+sB,SAAU,SAAU9pB,EAAMD,EAAU8qB,GAGnC7qB,EAAO/D,EAAYkE,SAAWH,EAE9B,IAAI0a,GAAUra,EAAOkD,EAASunB,EAAYrd,EAAMC,EAC/ClN,EAAI,EACJkF,EAAIpH,KAAKE,OACTye,EAAM3e,KACNysB,EAAWrlB,EAAI,EACfP,EAAQnF,EAAM,GACdf,EAAatD,EAAOsD,WAAYkG,EAGjC,IAAKlG,KAAsB,GAALyG,GAA2B,gBAAVP,IAAsBxJ,EAAOsL,QAAQqU,aAAeuN,GAAS9pB,KAAMoG,GACzG,MAAO7G,MAAKwB,KAAK,SAAU4Y,GAC1B,GAAIH,GAAO0E,EAAI3c,GAAIoY,EACdzZ,KACJe,EAAM,GAAMmF,EAAM5F,KAAMjB,KAAMoa,EAAOH,EAAKmS,SAE3CnS,EAAKuR,SAAU9pB,EAAMD,EAAU8qB,IAIjC,IAAKnlB,IACJgV,EAAW/e,EAAO8H,cAAezD,EAAM1B,KAAM,GAAIQ,eAAe,GAAQ+rB,GAAqBvsB,MAC7F+B,EAAQqa,EAASxM,WAEmB,IAA/BwM,EAAS/W,WAAWnF,SACxBkc,EAAWra,GAGPA,GAAQ,CAMZ,IALAkD,EAAU5H,EAAOgF,IAAK2pB,GAAQ5P,EAAU,UAAYsQ,IACpDF,EAAavnB,EAAQ/E,OAITkH,EAAJlF,EAAOA,IACdiN,EAAOiN,EAEFla,IAAMuqB,IACVtd,EAAO9R,EAAO0F,MAAOoM,GAAM,GAAM,GAG5Bqd,GAGJnvB,EAAOgD,MAAO4E,EAAS+mB,GAAQ7c,EAAM,YAIvC1N,EAASR,KAAMjB,KAAMkC,GAAKiN,EAAMjN,EAGjC,IAAKsqB,EAOJ,IANApd,EAAMnK,EAASA,EAAQ/E,OAAS,GAAIM,cAGpCnD,EAAOgF,IAAK4C,EAAS0nB,IAGfzqB,EAAI,EAAOsqB,EAAJtqB,EAAgBA,IAC5BiN,EAAOlK,EAAS/C,GACXsoB,GAAY/pB,KAAM0O,EAAKlL,MAAQ,MAClC+Z,EAAUrW,OAAQwH,EAAM,eAAkB9R,EAAOmM,SAAU4F,EAAKD,KAE5DA,EAAKvM,IAETvF,EAAOuvB,SAAUzd,EAAKvM,KAEtBvF,EAAO2I,WAAYmJ,EAAKwC,YAAYrO,QAASonB,GAAc,MAQjE,MAAO1qB,SAIT3C,EAAOmE,MACNqrB,SAAU,SACVC,UAAW,UACXnB,aAAc,SACdoB,YAAa,QACbC,WAAY,eACV,SAAUrqB,EAAMujB,GAClB7oB,EAAOsB,GAAIgE,GAAS,SAAUlE,GAC7B,GAAI4C,GACHC,KACA2rB,EAAS5vB,EAAQoB,GACjBwD,EAAOgrB,EAAO/sB,OAAS,EACvBgC,EAAI,CAEL,MAAaD,GAALC,EAAWA,IAClBb,EAAQa,IAAMD,EAAOjC,KAAOA,KAAK+C,OAAO,GACxC1F,EAAQ4vB,EAAQ/qB,IAAOgkB,GAAY7kB,GAInCxD,EAAUgE,MAAOP,EAAKD,EAAMH,MAG7B,OAAOlB,MAAKoB,UAAWE,MAIzBjE,EAAOoF,QACNM,MAAO,SAAUhD,EAAMmsB,EAAeC,GACrC,GAAIjqB,GAAGkF,EAAG8lB,EAAaC,EACtBpqB,EAAQhD,EAAK8c,WAAW,GACxBuQ,EAAS/vB,EAAOmM,SAAUzJ,EAAKS,cAAeT,EAI/C,MAAM1C,EAAOsL,QAAQiU,gBAAsC,IAAlB7c,EAAKQ,UAAoC,KAAlBR,EAAKQ,UAAsBlD,EAAO2b,SAAUjZ,IAM3G,IAHAotB,EAAenB,GAAQjpB,GACvBmqB,EAAclB,GAAQjsB,GAEhBmC,EAAI,EAAGkF,EAAI8lB,EAAYhtB,OAAYkH,EAAJlF,EAAOA,IAC3CmrB,GAAUH,EAAahrB,GAAKirB,EAAcjrB,GAK5C,IAAKgqB,EACJ,GAAKC,EAIJ,IAHAe,EAAcA,GAAelB,GAAQjsB,GACrCotB,EAAeA,GAAgBnB,GAAQjpB,GAEjCb,EAAI,EAAGkF,EAAI8lB,EAAYhtB,OAAYkH,EAAJlF,EAAOA,IAC3CorB,GAAgBJ,EAAahrB,GAAKirB,EAAcjrB,QAGjDorB,IAAgBvtB,EAAMgD,EAWxB,OANAoqB,GAAenB,GAAQjpB,EAAO,UACzBoqB,EAAajtB,OAAS,GAC1B+rB,GAAekB,GAAeC,GAAUpB,GAAQjsB,EAAM,WAIhDgD,GAGRoC,cAAe,SAAU9D,EAAO3C,EAASuG,EAASsoB,GACjD,GAAIxtB,GAAM4F,EAAKuK,EAAKsd,EAAMhkB,EAAUpH,EACnCF,EAAI,EACJkF,EAAI/F,EAAMnB,OACVkc,EAAW1d,EAAQ2d,yBACnBoR,IAED,MAAYrmB,EAAJlF,EAAOA,IAGd,GAFAnC,EAAOsB,EAAOa,GAETnC,GAAiB,IAATA,EAGZ,GAA6B,WAAxB1C,EAAO4G,KAAMlE,GAGjB1C,EAAOgD,MAAOotB,EAAO1tB,EAAKQ,UAAaR,GAASA,OAG1C,IAAMqqB,GAAM3pB,KAAMV,GAIlB,CACN4F,EAAMA,GAAOyW,EAAS7V,YAAa7H,EAAQwG,cAAc,QAGzDgL,GAAQia,GAAShqB,KAAMJ,KAAW,GAAI,KAAO,GAAI6G,cACjD4mB,EAAO7C,GAASza,IAASya,GAAQtF,SACjC1f,EAAIgK,UAAY6d,EAAM,GAAMztB,EAAKuD,QAAS4mB,GAAW,aAAgBsD,EAAM,GAG3EprB,EAAIorB,EAAM,EACV,OAAQprB,IACPuD,EAAMA,EAAI0N,SAKXhW,GAAOgD,MAAOotB,EAAO9nB,EAAIN,YAGzBM,EAAMyW,EAASxM,WAIfjK,EAAIgM,YAAc,OA1BlB8b,GAAM3vB,KAAMY,EAAQ6sB,eAAgBxrB,GAgCvCqc,GAASzK,YAAc,GAEvBzP,EAAI,CACJ,OAASnC,EAAO0tB,EAAOvrB,KAItB,KAAKqrB,GAAmD,KAAtClwB,EAAO6J,QAASnH,EAAMwtB,MAIxC/jB,EAAWnM,EAAOmM,SAAUzJ,EAAKS,cAAeT,GAGhD4F,EAAMqmB,GAAQ5P,EAAS7V,YAAaxG,GAAQ,UAGvCyJ,GACJyiB,GAAetmB,GAIXV,GAAU,CACd7C,EAAI,CACJ,OAASrC,EAAO4F,EAAKvD,KACfooB,GAAY/pB,KAAMV,EAAKkE,MAAQ,KACnCgB,EAAQnH,KAAMiC,GAMlB,MAAOqc,IAGR2P,UAAW,SAAU1qB,GACpB,GAAIyD,GAAM/E,EAAMsjB,EAAQpf,EAAM2D,EAAKxF,EAClCohB,EAAUnmB,EAAO2lB,MAAMQ,QACvBthB,EAAI,CAEL,OAASnC,EAAOsB,EAAOa,MAAStF,UAAWsF,IAAM,CAChD,GAAKic,EAAKG,QAASve,KAClB6H,EAAM7H,EAAMie,EAAU7a,SAEjByE,IAAQ9C,EAAOkZ,EAAUjQ,MAAOnG,KAAS,CAE7C,GADAyb,EAASpc,OAAO6G,KAAMhJ,EAAKue,YACtBA,EAAOnjB,OACX,IAAMkC,EAAI,GAAI6B,EAAOof,EAAOjhB,MAAQxF,UAAWwF,IACzCohB,EAASvf,GACb5G,EAAO2lB,MAAM5d,OAAQrF,EAAMkE,GAI3B5G,EAAOmnB,YAAazkB,EAAMkE,EAAMa,EAAK+e,OAInC7F,GAAUjQ,MAAOnG,UAEdoW,GAAUjQ,MAAOnG,SAKpBmW,GAAUhQ,MAAOhO,EAAMge,EAAU5a,YAI1CypB,SAAU,SAAUc,GACnB,MAAOrwB,GAAOswB,MACbD,IAAKA,EACLzpB,KAAM,MACN2pB,SAAU,SACVC,OAAO,EACP5K,QAAQ,EACR6K,UAAU,MAOb,SAASrC,IAAoB1rB,EAAMguB,GAClC,MAAO1wB,GAAOsJ,SAAU5G,EAAM,UAC7B1C,EAAOsJ,SAA+B,IAArBonB,EAAQxtB,SAAiBwtB,EAAUA,EAAQne,WAAY,MAExE7P,EAAK+F,qBAAqB,SAAS,IAClC/F,EAAKwG,YAAaxG,EAAKS,cAAc0E,cAAc,UACpDnF,EAIF,QAAS2sB,IAAe3sB,GAEvB,MADAA,GAAKkE,MAAsC,OAA9BlE,EAAKuN,aAAa,SAAoB,IAAMvN,EAAKkE,KACvDlE,EAER,QAAS4sB,IAAe5sB,GACvB,GAAID,GAAQ2qB,GAAkBtqB,KAAMJ,EAAKkE,KAQzC,OANKnE,GACJC,EAAKkE,KAAOnE,EAAO,GAEnBC,EAAK6N,gBAAgB,QAGf7N,EAIR,QAASksB,IAAe5qB,EAAO2sB,GAC9B,GAAI5mB,GAAI/F,EAAMnB,OACbgC,EAAI,CAEL,MAAYkF,EAAJlF,EAAOA,IACd8b,EAAUW,IACTtd,EAAOa,GAAK,cAAe8rB,GAAehQ,EAAU9c,IAAK8sB,EAAa9rB,GAAK,eAK9E,QAASorB,IAAgB1qB,EAAKqrB,GAC7B,GAAI/rB,GAAGkF,EAAGnD,EAAMiqB,EAAUC,EAAUC,EAAUC,EAAUhL,CAExD,IAAuB,IAAlB4K,EAAK1tB,SAAV,CAKA,GAAKyd,EAAUe,QAASnc,KACvBsrB,EAAWlQ,EAAUrW,OAAQ/E,GAC7BurB,EAAWnQ,EAAUW,IAAKsP,EAAMC,GAChC7K,EAAS6K,EAAS7K,QAEJ,OACN8K,GAAStK,OAChBsK,EAAS9K,SAET,KAAMpf,IAAQof,GACb,IAAMnhB,EAAI,EAAGkF,EAAIic,EAAQpf,GAAO/D,OAAYkH,EAAJlF,EAAOA,IAC9C7E,EAAO2lB,MAAM7I,IAAK8T,EAAMhqB,EAAMof,EAAQpf,GAAQ/B,IAO7C6b,EAAUgB,QAASnc,KACvBwrB,EAAWrQ,EAAUpW,OAAQ/E,GAC7ByrB,EAAWhxB,EAAOoF,UAAY2rB,GAE9BrQ,EAAUY,IAAKsP,EAAMI,KAKvB,QAASrC,IAAQttB,EAASwR,GACzB,GAAI5O,GAAM5C,EAAQoH,qBAAuBpH,EAAQoH,qBAAsBoK,GAAO,KAC5ExR,EAAQgP,iBAAmBhP,EAAQgP,iBAAkBwC,GAAO,OAG9D,OAAOA,KAAQtT,WAAasT,GAAO7S,EAAOsJ,SAAUjI,EAASwR,GAC5D7S,EAAOgD,OAAS3B,GAAW4C,GAC3BA,EAIF,QAAS+rB,IAAUzqB,EAAKqrB,GACvB,GAAItnB,GAAWsnB,EAAKtnB,SAASC,aAGX,WAAbD,GAAwB2jB,GAA4B7pB,KAAMmC,EAAIqB,MAClEgqB,EAAKvZ,QAAU9R,EAAI8R,SAGK,UAAb/N,GAAqC,aAAbA,KACnCsnB,EAAKnV,aAAelW,EAAIkW,cAG1Bzb,EAAOsB,GAAG8D,QACT6rB,QAAS,SAAUlC,GAClB,GAAIoB,EAEJ,OAAKnwB,GAAOsD,WAAYyrB,GAChBpsB,KAAKwB,KAAK,SAAUU,GAC1B7E,EAAQ2C,MAAOsuB,QAASlC,EAAKnrB,KAAKjB,KAAMkC,OAIrClC,KAAM,KAGVwtB,EAAOnwB,EAAQ+uB,EAAMpsB,KAAM,GAAIQ,eAAgBwB,GAAI,GAAIe,OAAO,GAEzD/C,KAAM,GAAIc,YACd0sB,EAAK7B,aAAc3rB,KAAM,IAG1BwtB,EAAKnrB,IAAI,WACR,GAAItC,GAAOC,IAEX,OAAQD,EAAKwuB,kBACZxuB,EAAOA,EAAKwuB,iBAGb,OAAOxuB,KACLurB,OAAQtrB,OAGLA,OAGRwuB,UAAW,SAAUpC,GACpB,MAAK/uB,GAAOsD,WAAYyrB,GAChBpsB,KAAKwB,KAAK,SAAUU,GAC1B7E,EAAQ2C,MAAOwuB,UAAWpC,EAAKnrB,KAAKjB,KAAMkC,MAIrClC,KAAKwB,KAAK,WAChB,GAAIyY,GAAO5c,EAAQ2C,MAClB4oB,EAAW3O,EAAK2O,UAEZA,GAAS1oB,OACb0oB,EAAS0F,QAASlC,GAGlBnS,EAAKqR,OAAQc,MAKhBoB,KAAM,SAAUpB,GACf,GAAIzrB,GAAatD,EAAOsD,WAAYyrB,EAEpC,OAAOpsB,MAAKwB,KAAK,SAAUU,GAC1B7E,EAAQ2C,MAAOsuB,QAAS3tB,EAAayrB,EAAKnrB,KAAKjB,KAAMkC,GAAKkqB,MAI5DqC,OAAQ,WACP,MAAOzuB,MAAKqP,SAAS7N,KAAK,WACnBnE,EAAOsJ,SAAU3G,KAAM,SAC5B3C,EAAQ2C,MAAOqsB,YAAarsB,KAAKqF,cAEhC/C,QAGL,IAAIosB,IAAQC,GAGXC,GAAe,4BACfC,GAAU,UACVC,GAAgB/jB,OAAQ,KAAOlM,EAAY,SAAU,KACrDkwB,GAAgBhkB,OAAQ,KAAOlM,EAAY,kBAAmB,KAC9DmwB,GAAcjkB,OAAQ,YAAclM,EAAY,IAAK,KACrDowB,IAAgBC,KAAM,SAEtBC,IAAYC,SAAU,WAAYC,WAAY,SAAUC,QAAS,SACjEC,IACCC,cAAe,EACfC,WAAY,KAGbC,IAAc,MAAO,QAAS,SAAU,QACxCC,IAAgB,SAAU,IAAK,MAAO,KAGvC,SAASC,IAAgBvnB,EAAO1F,GAG/B,GAAKA,IAAQ0F,GACZ,MAAO1F,EAIR,IAAIktB,GAAUltB,EAAK1C,OAAO,GAAGV,cAAgBoD,EAAK3E,MAAM,GACvD8xB,EAAWntB,EACXT,EAAIytB,GAAYzvB,MAEjB,OAAQgC,IAEP,GADAS,EAAOgtB,GAAaztB,GAAM2tB,EACrBltB,IAAQ0F,GACZ,MAAO1F,EAIT,OAAOmtB,GAGR,QAASC,IAAUhwB,EAAMiwB,GAIxB,MADAjwB,GAAOiwB,GAAMjwB,EAC4B,SAAlC1C,EAAO4yB,IAAKlwB,EAAM,aAA2B1C,EAAOmM,SAAUzJ,EAAKS,cAAeT,GAK1F,QAASmwB,IAAWnwB,GACnB,MAAOpD,GAAOihB,iBAAkB7d,EAAM,MAGvC,QAASowB,IAAU/e,EAAUgf,GAC5B,GAAId,GAASvvB,EAAMswB,EAClBtU,KACA3B,EAAQ,EACRla,EAASkR,EAASlR,MAEnB,MAAgBA,EAARka,EAAgBA,IACvBra,EAAOqR,EAAUgJ,GACXra,EAAKsI,QAIX0T,EAAQ3B,GAAU4D,EAAU9c,IAAKnB,EAAM,cACvCuvB,EAAUvvB,EAAKsI,MAAMinB,QAChBc,GAGErU,EAAQ3B,IAAuB,SAAZkV,IACxBvvB,EAAKsI,MAAMinB,QAAU,IAMM,KAAvBvvB,EAAKsI,MAAMinB,SAAkBS,GAAUhwB,KAC3Cgc,EAAQ3B,GAAU4D,EAAUrW,OAAQ5H,EAAM,aAAcuwB,GAAmBvwB,EAAK4G,aAI3EoV,EAAQ3B,KACbiW,EAASN,GAAUhwB,IAEduvB,GAAuB,SAAZA,IAAuBe,IACtCrS,EAAUW,IAAK5e,EAAM,aAAcswB,EAASf,EAAUjyB,EAAO4yB,IAAIlwB,EAAM,aAQ3E,KAAMqa,EAAQ,EAAWla,EAARka,EAAgBA,IAChCra,EAAOqR,EAAUgJ,GACXra,EAAKsI,QAGL+nB,GAA+B,SAAvBrwB,EAAKsI,MAAMinB,SAA6C,KAAvBvvB,EAAKsI,MAAMinB,UACzDvvB,EAAKsI,MAAMinB,QAAUc,EAAOrU,EAAQ3B,IAAW,GAAK,QAItD,OAAOhJ,GAGR/T,EAAOsB,GAAG8D,QACTwtB,IAAK,SAAUttB,EAAMkE,GACpB,MAAOxJ,GAAOsK,OAAQ3H,KAAM,SAAUD,EAAM4C,EAAMkE,GACjD,GAAI0pB,GAAQpuB,EACXE,KACAH,EAAI,CAEL,IAAK7E,EAAO6F,QAASP,GAAS,CAI7B,IAHA4tB,EAASL,GAAWnwB,GACpBoC,EAAMQ,EAAKzC,OAECiC,EAAJD,EAASA,IAChBG,EAAKM,EAAMT,IAAQ7E,EAAO4yB,IAAKlwB,EAAM4C,EAAMT,IAAK,EAAOquB,EAGxD,OAAOluB,GAGR,MAAOwE,KAAUjK,UAChBS,EAAOgL,MAAOtI,EAAM4C,EAAMkE,GAC1BxJ,EAAO4yB,IAAKlwB,EAAM4C,IACjBA,EAAMkE,EAAO/E,UAAU5B,OAAS,IAEpCkwB,KAAM,WACL,MAAOD,IAAUnwB,MAAM,IAExBwwB,KAAM,WACL,MAAOL,IAAUnwB,OAElBywB,OAAQ,SAAU/V,GACjB,MAAsB,iBAAVA,GACJA,EAAQ1a,KAAKowB,OAASpwB,KAAKwwB,OAG5BxwB,KAAKwB,KAAK,WACXuuB,GAAU/vB,MACd3C,EAAQ2C,MAAOowB,OAEf/yB,EAAQ2C,MAAOwwB,YAMnBnzB,EAAOoF,QAGNiuB,UACCC,SACCzvB,IAAK,SAAUnB,EAAM6wB,GACpB,GAAKA,EAAW,CAEf,GAAItvB,GAAMotB,GAAQ3uB,EAAM,UACxB,OAAe,KAARuB,EAAa,IAAMA,MAO9BuvB,WACCC,aAAe,EACfC,aAAe,EACftB,YAAc,EACduB,YAAc,EACdL,SAAW,EACXM,OAAS,EACTC,SAAW,EACXC,QAAU,EACVC,QAAU,EACV3T,MAAQ,GAKT4T,UAECC,QAAS,YAIVjpB,MAAO,SAAUtI,EAAM4C,EAAMkE,EAAO0qB,GAEnC,GAAMxxB,GAA0B,IAAlBA,EAAKQ,UAAoC,IAAlBR,EAAKQ,UAAmBR,EAAKsI,MAAlE,CAKA,GAAI/G,GAAK2C,EAAMyb,EACdoQ,EAAWzyB,EAAOoJ,UAAW9D,GAC7B0F,EAAQtI,EAAKsI,KASd,OAPA1F,GAAOtF,EAAOg0B,SAAUvB,KAAgBzyB,EAAOg0B,SAAUvB,GAAaF,GAAgBvnB,EAAOynB,IAI7FpQ,EAAQriB,EAAOqzB,SAAU/tB,IAAUtF,EAAOqzB,SAAUZ,GAG/CjpB,IAAUjK,UAiCT8iB,GAAS,OAASA,KAAUpe,EAAMoe,EAAMxe,IAAKnB,GAAM,EAAOwxB,MAAa30B,UACpE0E,EAID+G,EAAO1F,IArCdsB,QAAc4C,GAGA,WAAT5C,IAAsB3C,EAAM0tB,GAAQ7uB,KAAM0G,MAC9CA,GAAUvF,EAAI,GAAK,GAAMA,EAAI,GAAKgD,WAAYjH,EAAO4yB,IAAKlwB,EAAM4C,IAEhEsB,EAAO,UAIM,MAAT4C,GAA0B,WAAT5C,GAAqBI,MAAOwC,KAKpC,WAAT5C,GAAsB5G,EAAOwzB,UAAWf,KAC5CjpB,GAAS,MAKJxJ,EAAOsL,QAAQwU,iBAA6B,KAAVtW,GAA+C,IAA/BlE,EAAKzE,QAAQ,gBACpEmK,EAAO1F,GAAS,WAIX+c,GAAW,OAASA,KAAW7Y,EAAQ6Y,EAAMf,IAAK5e,EAAM8G,EAAO0qB,MAAa30B,YACjFyL,EAAO1F,GAASkE,IAjBjB,aA+BFopB,IAAK,SAAUlwB,EAAM4C,EAAM4uB,EAAOhB,GACjC,GAAIlf,GAAKlQ,EAAKue,EACboQ,EAAWzyB,EAAOoJ,UAAW9D,EAyB9B,OAtBAA,GAAOtF,EAAOg0B,SAAUvB,KAAgBzyB,EAAOg0B,SAAUvB,GAAaF,GAAgB7vB,EAAKsI,MAAOynB,IAIlGpQ,EAAQriB,EAAOqzB,SAAU/tB,IAAUtF,EAAOqzB,SAAUZ,GAG/CpQ,GAAS,OAASA,KACtBrO,EAAMqO,EAAMxe,IAAKnB,GAAM,EAAMwxB,IAIzBlgB,IAAQzU,YACZyU,EAAMqd,GAAQ3uB,EAAM4C,EAAM4tB,IAId,WAARlf,GAAoB1O,IAAQ4sB,MAChCle,EAAMke,GAAoB5sB,IAIZ,KAAV4uB,GAAgBA,GACpBpwB,EAAMmD,WAAY+M,GACXkgB,KAAU,GAAQl0B,EAAO+G,UAAWjD,GAAQA,GAAO,EAAIkQ,GAExDA,KAITqd,GAAS,SAAU3uB,EAAM4C,EAAM6uB,GAC9B,GAAI3T,GAAO4T,EAAUC,EACpBd,EAAWY,GAAatB,GAAWnwB,GAInCuB,EAAMsvB,EAAWA,EAASe,iBAAkBhvB,IAAUiuB,EAAUjuB,GAAS/F,UACzEyL,EAAQtI,EAAKsI,KA8Bd,OA5BKuoB,KAES,KAARtvB,GAAejE,EAAOmM,SAAUzJ,EAAKS,cAAeT,KACxDuB,EAAMjE,EAAOgL,MAAOtI,EAAM4C,IAOtBosB,GAAUtuB,KAAMa,IAASutB,GAAQpuB,KAAMkC,KAG3Ckb,EAAQxV,EAAMwV,MACd4T,EAAWppB,EAAMopB,SACjBC,EAAWrpB,EAAMqpB,SAGjBrpB,EAAMopB,SAAWppB,EAAMqpB,SAAWrpB,EAAMwV,MAAQvc,EAChDA,EAAMsvB,EAAS/S,MAGfxV,EAAMwV,MAAQA,EACdxV,EAAMopB,SAAWA,EACjBppB,EAAMqpB,SAAWA,IAIZpwB,EAIR,SAASswB,IAAmB7xB,EAAM8G,EAAOgrB,GACxC,GAAItoB,GAAUulB,GAAU3uB,KAAM0G,EAC9B,OAAO0C,GAENnG,KAAKwe,IAAK,EAAGrY,EAAS,IAAQsoB,GAAY,KAAUtoB,EAAS,IAAO,MACpE1C,EAGF,QAASirB,IAAsB/xB,EAAM4C,EAAM4uB,EAAOQ,EAAaxB,GAC9D,GAAIruB,GAAIqvB,KAAYQ,EAAc,SAAW,WAE5C,EAES,UAATpvB,EAAmB,EAAI,EAEvB0O,EAAM,CAEP,MAAY,EAAJnP,EAAOA,GAAK,EAEJ,WAAVqvB,IACJlgB,GAAOhU,EAAO4yB,IAAKlwB,EAAMwxB,EAAQ7B,GAAWxtB,IAAK,EAAMquB,IAGnDwB,GAEW,YAAVR,IACJlgB,GAAOhU,EAAO4yB,IAAKlwB,EAAM,UAAY2vB,GAAWxtB,IAAK,EAAMquB,IAI7C,WAAVgB,IACJlgB,GAAOhU,EAAO4yB,IAAKlwB,EAAM,SAAW2vB,GAAWxtB,GAAM,SAAS,EAAMquB,MAIrElf,GAAOhU,EAAO4yB,IAAKlwB,EAAM,UAAY2vB,GAAWxtB,IAAK,EAAMquB,GAG5C,YAAVgB,IACJlgB,GAAOhU,EAAO4yB,IAAKlwB,EAAM,SAAW2vB,GAAWxtB,GAAM,SAAS,EAAMquB,IAKvE,OAAOlf,GAGR,QAAS2gB,IAAkBjyB,EAAM4C,EAAM4uB,GAGtC,GAAIU,IAAmB,EACtB5gB,EAAe,UAAT1O,EAAmB5C,EAAK4d,YAAc5d,EAAKmyB,aACjD3B,EAASL,GAAWnwB,GACpBgyB,EAAc10B,EAAOsL,QAAQ+U,WAAgE,eAAnDrgB,EAAO4yB,IAAKlwB,EAAM,aAAa,EAAOwwB,EAKjF,IAAY,GAAPlf,GAAmB,MAAPA,EAAc,CAQ9B,GANAA,EAAMqd,GAAQ3uB,EAAM4C,EAAM4tB,IACf,EAANlf,GAAkB,MAAPA,KACfA,EAAMtR,EAAKsI,MAAO1F,IAIdosB,GAAUtuB,KAAK4Q,GACnB,MAAOA,EAKR4gB,GAAmBF,IAAiB10B,EAAOsL,QAAQ+T,mBAAqBrL,IAAQtR,EAAKsI,MAAO1F,IAG5F0O,EAAM/M,WAAY+M,IAAS,EAI5B,MAASA,GACRygB,GACC/xB,EACA4C,EACA4uB,IAAWQ,EAAc,SAAW,WACpCE,EACA1B,GAEE,KAIL,QAASD,IAAoB3pB,GAC5B,GAAIyI,GAAMnS,EACTqyB,EAAUL,GAAatoB,EA0BxB,OAxBM2oB,KACLA,EAAU6C,GAAexrB,EAAUyI,GAGlB,SAAZkgB,GAAuBA,IAE3BX,IAAWA,IACVtxB,EAAO,kDACN4yB,IAAK,UAAW,6BAChBpD,SAAUzd,EAAIjS,iBAGhBiS,GAAQuf,GAAO,GAAGyD,eAAiBzD,GAAO,GAAG9E,iBAAkB5sB,SAC/DmS,EAAIijB,MAAM,+BACVjjB,EAAIkjB,QAEJhD,EAAU6C,GAAexrB,EAAUyI,GACnCuf,GAAOrC,UAIR2C,GAAatoB,GAAa2oB,GAGpBA,EAIR,QAAS6C,IAAexvB,EAAMyM,GAC7B,GAAIrP,GAAO1C,EAAQ+R,EAAIlK,cAAevC,IAASkqB,SAAUzd,EAAImO,MAC5D+R,EAAUjyB,EAAO4yB,IAAKlwB,EAAK,GAAI,UAEhC,OADAA,GAAKqF,SACEkqB,EAGRjyB,EAAOmE,MAAO,SAAU,SAAW,SAAUU,EAAGS,GAC/CtF,EAAOqzB,SAAU/tB,IAChBzB,IAAK,SAAUnB,EAAM6wB,EAAUW,GAC9B,MAAKX,GAGwB,IAArB7wB,EAAK4d,aAAqBiR,GAAanuB,KAAMpD,EAAO4yB,IAAKlwB,EAAM,YACrE1C,EAAO8K,KAAMpI,EAAMovB,GAAS,WAC3B,MAAO6C,IAAkBjyB,EAAM4C,EAAM4uB,KAEtCS,GAAkBjyB,EAAM4C,EAAM4uB,GAPhC,WAWD5S,IAAK,SAAU5e,EAAM8G,EAAO0qB,GAC3B,GAAIhB,GAASgB,GAASrB,GAAWnwB,EACjC,OAAO6xB,IAAmB7xB,EAAM8G,EAAO0qB,EACtCO,GACC/xB,EACA4C,EACA4uB,EACAl0B,EAAOsL,QAAQ+U,WAAgE,eAAnDrgB,EAAO4yB,IAAKlwB,EAAM,aAAa,EAAOwwB,GAClEA,GACG,OAQRlzB,EAAO,WAEAA,EAAOsL,QAAQ8T,sBACpBpf,EAAOqzB,SAAS5S,aACf5c,IAAK,SAAUnB,EAAM6wB,GACpB,MAAKA,GAIGvzB,EAAO8K,KAAMpI,GAAQuvB,QAAW,gBACtCZ,IAAU3uB,EAAM,gBALlB,cAcG1C,EAAOsL,QAAQgU,eAAiBtf,EAAOsB,GAAGywB,UAC/C/xB,EAAOmE,MAAQ,MAAO,QAAU,SAAUU,EAAG0c,GAC5CvhB,EAAOqzB,SAAU9R,IAChB1d,IAAK,SAAUnB,EAAM6wB,GACpB,MAAKA,IACJA,EAAWlC,GAAQ3uB,EAAM6e,GAElBmQ,GAAUtuB,KAAMmwB,GACtBvzB,EAAQ0C,GAAOqvB,WAAYxQ,GAAS,KACpCgS,GALF,gBAcAvzB,EAAO8T,MAAQ9T,EAAO8T,KAAKwE,UAC/BtY,EAAO8T,KAAKwE,QAAQ0a,OAAS,SAAUtwB,GAGtC,MAA2B,IAApBA,EAAK4d,aAAyC,GAArB5d,EAAKmyB,cAGtC70B,EAAO8T,KAAKwE,QAAQ4c,QAAU,SAAUxyB,GACvC,OAAQ1C,EAAO8T,KAAKwE,QAAQ0a,OAAQtwB,KAKtC1C,EAAOmE,MACNgxB,OAAQ,GACRC,QAAS,GACTC,OAAQ,SACN,SAAUC,EAAQC,GACpBv1B,EAAOqzB,SAAUiC,EAASC,IACzBC,OAAQ,SAAUhsB,GACjB,GAAI3E,GAAI,EACP4wB,KAGAC,EAAyB,gBAAVlsB,GAAqBA,EAAM6B,MAAM,MAAS7B,EAE1D,MAAY,EAAJ3E,EAAOA,IACd4wB,EAAUH,EAASjD,GAAWxtB,GAAM0wB,GACnCG,EAAO7wB,IAAO6wB,EAAO7wB,EAAI,IAAO6wB,EAAO,EAGzC,OAAOD,KAIHjE,GAAQpuB,KAAMkyB,KACnBt1B,EAAOqzB,SAAUiC,EAASC,GAASjU,IAAMiT,KAG3C,IAAIoB,IAAM,OACTC,GAAW,QACXC,GAAQ,SACRC,GAAkB,wCAClBC,GAAe,oCAEhB/1B,GAAOsB,GAAG8D,QACT4wB,UAAW,WACV,MAAOh2B,GAAOi2B,MAAOtzB,KAAKuzB,mBAE3BA,eAAgB,WACf,MAAOvzB,MAAKqC,IAAI,WAEf,GAAI+O,GAAW/T,EAAOuhB,KAAM5e,KAAM,WAClC,OAAOoR,GAAW/T,EAAO0D,UAAWqQ,GAAapR,OAEjD+P,OAAO,WACP,GAAI9L,GAAOjE,KAAKiE,IAEhB,OAAOjE,MAAK2C,OAAStF,EAAQ2C,MAAOgpB,GAAI,cACvCoK,GAAa3yB,KAAMT,KAAK2G,YAAewsB,GAAgB1yB,KAAMwD,KAC3DjE,KAAK0U,UAAY4V,GAA4B7pB,KAAMwD,MAEtD5B,IAAI,SAAUH,EAAGnC,GACjB,GAAIsR,GAAMhU,EAAQ2C,MAAOqR,KAEzB,OAAc,OAAPA,EACN,KACAhU,EAAO6F,QAASmO,GACfhU,EAAOgF,IAAKgP,EAAK,SAAUA,GAC1B,OAAS1O,KAAM5C,EAAK4C,KAAMkE,MAAOwK,EAAI/N,QAAS4vB,GAAO,YAEpDvwB,KAAM5C,EAAK4C,KAAMkE,MAAOwK,EAAI/N,QAAS4vB,GAAO,WAC9ChyB,SAML7D,EAAOi2B,MAAQ,SAAUrpB,EAAGupB,GAC3B,GAAIb,GACHc,KACAtZ,EAAM,SAAUvS,EAAKf,GAEpBA,EAAQxJ,EAAOsD,WAAYkG,GAAUA,IAAqB,MAATA,EAAgB,GAAKA,EACtE4sB,EAAGA,EAAEvzB,QAAWwzB,mBAAoB9rB,GAAQ,IAAM8rB,mBAAoB7sB,GASxE,IALK2sB,IAAgB52B,YACpB42B,EAAcn2B,EAAOs2B,cAAgBt2B,EAAOs2B,aAAaH,aAIrDn2B,EAAO6F,QAAS+G,IAASA,EAAErK,SAAWvC,EAAOqD,cAAeuJ,GAEhE5M,EAAOmE,KAAMyI,EAAG,WACfkQ,EAAKna,KAAK2C,KAAM3C,KAAK6G,aAMtB,KAAM8rB,IAAU1oB,GACf2pB,GAAajB,EAAQ1oB,EAAG0oB,GAAUa,EAAarZ,EAKjD,OAAOsZ,GAAEhmB,KAAM,KAAMnK,QAAS0vB,GAAK,KAGpC,SAASY,IAAajB,EAAQ3uB,EAAKwvB,EAAarZ,GAC/C,GAAIxX,EAEJ,IAAKtF,EAAO6F,QAASc,GAEpB3G,EAAOmE,KAAMwC,EAAK,SAAU9B,EAAG2xB,GACzBL,GAAeP,GAASxyB,KAAMkyB,GAElCxY,EAAKwY,EAAQkB,GAIbD,GAAajB,EAAS,KAAqB,gBAANkB,GAAiB3xB,EAAI,IAAO,IAAK2xB,EAAGL,EAAarZ,SAIlF,IAAMqZ,GAAsC,WAAvBn2B,EAAO4G,KAAMD,GAQxCmW,EAAKwY,EAAQ3uB,OANb,KAAMrB,IAAQqB,GACb4vB,GAAajB,EAAS,IAAMhwB,EAAO,IAAKqB,EAAKrB,GAAQ6wB,EAAarZ,GAQrE9c,EAAOmE,KAAM,0MAEqDkH,MAAM,KAAM,SAAUxG,EAAGS,GAG1FtF,EAAOsB,GAAIgE,GAAS,SAAUmC,EAAMnG,GACnC,MAAOmD,WAAU5B,OAAS,EACzBF,KAAKooB,GAAIzlB,EAAM,KAAMmC,EAAMnG,GAC3BqB,KAAK8D,QAASnB,MAIjBtF,EAAOsB,GAAG8D,QACTqxB,MAAO,SAAUC,EAAQC,GACxB,MAAOh0B,MAAK8nB,WAAYiM,GAAShM,WAAYiM,GAASD,IAGvDE,KAAM,SAAU/Q,EAAOpe,EAAMnG,GAC5B,MAAOqB,MAAKooB,GAAIlF,EAAO,KAAMpe,EAAMnG,IAEpCu1B,OAAQ,SAAUhR,EAAOvkB,GACxB,MAAOqB,MAAK+D,IAAKmf,EAAO,KAAMvkB;EAG/Bw1B,SAAU,SAAU11B,EAAUykB,EAAOpe,EAAMnG,GAC1C,MAAOqB,MAAKooB,GAAIlF,EAAOzkB,EAAUqG,EAAMnG,IAExCy1B,WAAY,SAAU31B,EAAUykB,EAAOvkB,GAEtC,MAA4B,KAArBmD,UAAU5B,OAAeF,KAAK+D,IAAKtF,EAAU,MAASuB,KAAK+D,IAAKmf,EAAOzkB,GAAY,KAAME,KAGlG,IAEC01B,IACAC,GAEAC,GAAal3B,EAAO4K,MAEpBusB,GAAc,KACdC,GAAQ,OACRC,GAAM,gBACNC,GAAW,6BAEXC,GAAiB,4DACjBC,GAAa,iBACbC,GAAY,QACZC,GAAO,8CAGPC,GAAQ33B,EAAOsB,GAAGuoB,KAWlB+N,MAOAC,MAGAC,GAAW,KAAKv3B,OAAO,IAIxB,KACC02B,GAAet3B,EAASsX,KACvB,MAAO7P,IAGR6vB,GAAer3B,EAASiI,cAAe,KACvCovB,GAAahgB,KAAO,GACpBggB,GAAeA,GAAahgB,KAI7B+f,GAAeU,GAAK50B,KAAMm0B,GAAa1tB,kBAGvC,SAASwuB,IAA6BC,GAGrC,MAAO,UAAUC,EAAoB9a,GAED,gBAAvB8a,KACX9a,EAAO8a,EACPA,EAAqB,IAGtB,IAAI1H,GACH1rB,EAAI,EACJqzB,EAAYD,EAAmB1uB,cAAc9G,MAAOf,MAErD,IAAK1B,EAAOsD,WAAY6Z,GAEvB,MAASoT,EAAW2H,EAAUrzB,KAER,MAAhB0rB,EAAS,IACbA,EAAWA,EAAS5vB,MAAO,IAAO,KACjCq3B,EAAWzH,GAAayH,EAAWzH,QAAkB1c,QAASsJ,KAI9D6a,EAAWzH,GAAayH,EAAWzH,QAAkB9vB,KAAM0c,IAQjE,QAASgb,IAA+BH,EAAW3yB,EAAS+yB,EAAiBC,GAE5E,GAAIC,MACHC,EAAqBP,IAAcH,EAEpC,SAASW,GAASjI,GACjB,GAAIjZ,EAYJ,OAXAghB,GAAW/H,IAAa,EACxBvwB,EAAOmE,KAAM6zB,EAAWzH,OAAkB,SAAUvhB,EAAGypB,GACtD,GAAIC,GAAsBD,EAAoBpzB,EAAS+yB,EAAiBC,EACxE,OAAmC,gBAAxBK,IAAqCH,GAAqBD,EAAWI,GAIpEH,IACDjhB,EAAWohB,GADf,WAHNrzB,EAAQ6yB,UAAUrkB,QAAS6kB,GAC3BF,EAASE,IACF,KAKFphB,EAGR,MAAOkhB,GAASnzB,EAAQ6yB,UAAW,MAAUI,EAAW,MAASE,EAAS,KAM3E,QAASG,IAAYhzB,EAAQJ,GAC5B,GAAIgF,GAAK3E,EACRgzB,EAAc54B,EAAOs2B,aAAasC,eAEnC,KAAMruB,IAAOhF,GACPA,EAAKgF,KAAUhL,aACjBq5B,EAAaruB,GAAQ5E,EAAWC,IAASA,OAAgB2E,GAAQhF,EAAKgF,GAO1E,OAJK3E,IACJ5F,EAAOoF,QAAQ,EAAMO,EAAQC,GAGvBD,EAGR3F,EAAOsB,GAAGuoB,KAAO,SAAUwG,EAAKwI,EAAQz0B,GACvC,GAAoB,gBAARisB,IAAoBsH,GAC/B,MAAOA,IAAMnzB,MAAO7B,KAAM8B,UAG3B,IAAIrD,GAAUwF,EAAMkyB,EACnBlc,EAAOja,KACP+D,EAAM2pB,EAAIxvB,QAAQ,IA+CnB,OA7CK6F,IAAO,IACXtF,EAAWivB,EAAI1vB,MAAO+F,GACtB2pB,EAAMA,EAAI1vB,MAAO,EAAG+F,IAIhB1G,EAAOsD,WAAYu1B,IAGvBz0B,EAAWy0B,EACXA,EAASt5B,WAGEs5B,GAA4B,gBAAXA,KAC5BjyB,EAAO,QAIHgW,EAAK/Z,OAAS,GAClB7C,EAAOswB,MACND,IAAKA,EAGLzpB,KAAMA,EACN2pB,SAAU,OACV9oB,KAAMoxB,IACJt0B,KAAK,SAAUw0B,GAGjBD,EAAWr0B,UAEXmY,EAAKmS,KAAM3tB,EAIVpB,EAAO,SAASiuB,OAAQjuB,EAAOiD,UAAW81B,IAAiBh2B,KAAM3B,GAGjE23B,KAECC,SAAU50B,GAAY,SAAUi0B,EAAOY,GACzCrc,EAAKzY,KAAMC,EAAU00B,IAAcT,EAAMU,aAAcE,EAAQZ,MAI1D11B,MAIR3C,EAAOmE,MAAQ,YAAa,WAAY,eAAgB,YAAa,cAAe,YAAc,SAAUU,EAAG+B,GAC9G5G,EAAOsB,GAAIsF,GAAS,SAAUtF,GAC7B,MAAOqB,MAAKooB,GAAInkB,EAAMtF,MAIxBtB,EAAOoF,QAGN8zB,OAAQ,EAGRC,gBACAC,QAEA9C,cACCjG,IAAK4G,GACLrwB,KAAM,MACNyyB,QAAS9B,GAAen0B,KAAM4zB,GAAc,IAC5CpR,QAAQ,EACR0T,aAAa,EACb9I,OAAO,EACP+I,YAAa,mDAabtY,SACCuY,IAAK1B,GACL9uB,KAAM,aACN+lB,KAAM,YACN1mB,IAAK,4BACLoxB,KAAM,qCAGPlO,UACCljB,IAAK,MACL0mB,KAAM,OACN0K,KAAM,QAGPC,gBACCrxB,IAAK,cACLW,KAAM,eACNywB,KAAM,gBAKPE,YAGCC,SAAUzyB,OAGV0yB,aAAa,EAGbC,YAAa95B,EAAOiI,UAGpB8xB,WAAY/5B,EAAOoI,UAOpBwwB,aACCvI,KAAK,EACLhvB,SAAS,IAOX24B,UAAW,SAAUr0B,EAAQs0B,GAC5B,MAAOA,GAGNtB,GAAYA,GAAYhzB,EAAQ3F,EAAOs2B,cAAgB2D,GAGvDtB,GAAY34B,EAAOs2B,aAAc3wB,IAGnCu0B,cAAenC,GAA6BH,IAC5CuC,cAAepC,GAA6BF,IAG5CvH,KAAM,SAAUD,EAAKhrB,GAGA,gBAARgrB,KACXhrB,EAAUgrB,EACVA,EAAM9wB,WAIP8F,EAAUA,KAEV,IAAI+0B,GAEHC,EAEAC,EACAC,EAEAC,EAEA9E,EAEA+E,EAEA51B,EAEAuxB,EAAIp2B,EAAOg6B,aAAe30B,GAE1Bq1B,EAAkBtE,EAAE/0B,SAAW+0B,EAE/BuE,EAAqBvE,EAAE/0B,UAAaq5B,EAAgBx3B,UAAYw3B,EAAgBn4B,QAC/EvC,EAAQ06B,GACR16B,EAAO2lB,MAERpI,EAAWvd,EAAOiL,WAClB2vB,EAAmB56B,EAAOgc,UAAU,eAEpC6e,EAAazE,EAAEyE,eAEfC,KACAC,KAEA1d,EAAQ,EAER2d,EAAW,WAEX3C,GACCntB,WAAY,EAGZ+vB,kBAAmB,SAAU1wB,GAC5B,GAAI9H,EACJ,IAAe,IAAV4a,EAAc,CAClB,IAAMkd,EAAkB,CACvBA,IACA,OAAS93B,EAAQ60B,GAASx0B,KAAMw3B,GAC/BC,EAAiB93B,EAAM,GAAG8G,eAAkB9G,EAAO,GAGrDA,EAAQ83B,EAAiBhwB,EAAIhB,eAE9B,MAAgB,OAAT9G,EAAgB,KAAOA,GAI/By4B,sBAAuB,WACtB,MAAiB,KAAV7d,EAAcid,EAAwB,MAI9Ca,iBAAkB,SAAU71B,EAAMkE,GACjC,GAAI4xB,GAAQ91B,EAAKiE,aAKjB,OAJM8T,KACL/X,EAAOy1B,EAAqBK,GAAUL,EAAqBK,IAAW91B,EACtEw1B,EAAgBx1B,GAASkE,GAEnB7G,MAIR04B,iBAAkB,SAAUz0B,GAI3B,MAHMyW,KACL+Y,EAAEkF,SAAW10B,GAEPjE,MAIRk4B,WAAY,SAAU71B,GACrB,GAAI4D,EACJ,IAAK5D,EACJ,GAAa,EAARqY,EACJ,IAAMzU,IAAQ5D,GAEb61B,EAAYjyB,IAAWiyB,EAAYjyB,GAAQ5D,EAAK4D,QAIjDyvB,GAAM/a,OAAQtY,EAAKqzB,EAAMY,QAG3B,OAAOt2B,OAIR44B,MAAO,SAAUC,GAChB,GAAIC,GAAYD,GAAcR,CAK9B,OAJKZ,IACJA,EAAUmB,MAAOE,GAElBl3B,EAAM,EAAGk3B,GACF94B,MAyCV,IApCA4a,EAASjZ,QAAS+zB,GAAQW,SAAW4B,EAAiB9d,IACtDub,EAAMqD,QAAUrD,EAAM9zB,KACtB8zB,EAAM/wB,MAAQ+wB,EAAM7a,KAMpB4Y,EAAE/F,MAAUA,GAAO+F,EAAE/F,KAAO4G,IAAiB,IAAKhxB,QAASmxB,GAAO,IAChEnxB,QAASwxB,GAAWT,GAAc,GAAM,MAG1CZ,EAAExvB,KAAOvB,EAAQs2B,QAAUt2B,EAAQuB,MAAQwvB,EAAEuF,QAAUvF,EAAExvB,KAGzDwvB,EAAE8B,UAAYl4B,EAAOmB,KAAMi1B,EAAE7F,UAAY,KAAMhnB,cAAc9G,MAAOf,KAAqB,IAGnE,MAAjB00B,EAAEwF,cACNlG,EAAQgC,GAAK50B,KAAMszB,EAAE/F,IAAI9mB,eACzB6sB,EAAEwF,eAAkBlG,GACjBA,EAAO,KAAQsB,GAAc,IAAOtB,EAAO,KAAQsB,GAAc,KAChEtB,EAAO,KAAwB,UAAfA,EAAO,GAAkB,KAAO,WAC/CsB,GAAc,KAA+B,UAAtBA,GAAc,GAAkB,KAAO,UAK/DZ,EAAE3uB,MAAQ2uB,EAAEkD,aAAiC,gBAAXlD,GAAE3uB,OACxC2uB,EAAE3uB,KAAOzH,EAAOi2B,MAAOG,EAAE3uB,KAAM2uB,EAAED,cAIlCgC,GAA+BP,GAAYxB,EAAG/wB,EAASgzB,GAGxC,IAAVhb,EACJ,MAAOgb,EAIRoC,GAAcrE,EAAExQ,OAGX6U,GAAmC,IAApBz6B,EAAOk5B,UAC1Bl5B,EAAO2lB,MAAMlf,QAAQ,aAItB2vB,EAAExvB,KAAOwvB,EAAExvB,KAAK1E,cAGhBk0B,EAAEyF,YAAcrE,GAAWp0B,KAAMgzB,EAAExvB,MAInCyzB,EAAWjE,EAAE/F,IAGP+F,EAAEyF,aAGFzF,EAAE3uB,OACN4yB,EAAajE,EAAE/F,MAAS8G,GAAY/zB,KAAMi3B,GAAa,IAAM,KAAQjE,EAAE3uB,WAEhE2uB,GAAE3uB,MAIL2uB,EAAE1lB,SAAU,IAChB0lB,EAAE/F,IAAMgH,GAAIj0B,KAAMi3B,GAGjBA,EAASp0B,QAASoxB,GAAK,OAASH,MAGhCmD,GAAalD,GAAY/zB,KAAMi3B,GAAa,IAAM,KAAQ,KAAOnD,OAK/Dd,EAAE0F,aACD97B,EAAOm5B,aAAckB,IACzBhC,EAAM8C,iBAAkB,oBAAqBn7B,EAAOm5B,aAAckB,IAE9Dr6B,EAAOo5B,KAAMiB,IACjBhC,EAAM8C,iBAAkB,gBAAiBn7B,EAAOo5B,KAAMiB,MAKnDjE,EAAE3uB,MAAQ2uB,EAAEyF,YAAczF,EAAEmD,eAAgB,GAASl0B,EAAQk0B,cACjElB,EAAM8C,iBAAkB,eAAgB/E,EAAEmD,aAI3ClB,EAAM8C,iBACL,SACA/E,EAAE8B,UAAW,IAAO9B,EAAEnV,QAASmV,EAAE8B,UAAU,IAC1C9B,EAAEnV,QAASmV,EAAE8B,UAAU,KAA8B,MAArB9B,EAAE8B,UAAW,GAAc,KAAOJ,GAAW,WAAa,IAC1F1B,EAAEnV,QAAS,KAIb,KAAMpc,IAAKuxB,GAAE2F,QACZ1D,EAAM8C,iBAAkBt2B,EAAGuxB,EAAE2F,QAASl3B,GAIvC,IAAKuxB,EAAE4F,aAAgB5F,EAAE4F,WAAWp4B,KAAM82B,EAAiBrC,EAAOjC,MAAQ,GAAmB,IAAV/Y,GAElF,MAAOgb,GAAMkD,OAIdP,GAAW,OAGX,KAAMn2B,KAAO62B,QAAS,EAAGp0B,MAAO,EAAG0xB,SAAU,GAC5CX,EAAOxzB,GAAKuxB,EAAGvxB,GAOhB,IAHAu1B,EAAYjC,GAA+BN,GAAYzB,EAAG/wB,EAASgzB,GAK5D,CACNA,EAAMntB,WAAa,EAGduvB,GACJE,EAAmBl0B,QAAS,YAAc4xB,EAAOjC,IAG7CA,EAAE5F,OAAS4F,EAAEtT,QAAU,IAC3B0X,EAAervB,WAAW,WACzBktB,EAAMkD,MAAM,YACVnF,EAAEtT,SAGN,KACCzF,EAAQ,EACR+c,EAAU6B,KAAMnB,EAAgBv2B,GAC/B,MAAQ6C,GAET,KAAa,EAARiW,GAIJ,KAAMjW,EAHN7C,GAAM,GAAI6C,QArBZ7C,GAAM,GAAI,eA8BX,SAASA,GAAM00B,EAAQiD,EAAkBC,EAAWJ,GACnD,GAAIK,GAAWV,EAASp0B,EAAOwxB,EAAUuD,EACxCb,EAAaU,CAGC,KAAV7e,IAKLA,EAAQ,EAGHmd,GACJzX,aAAcyX,GAKfJ,EAAY76B,UAGZ+6B,EAAwByB,GAAW,GAGnC1D,EAAMntB,WAAa+tB,EAAS,EAAI,EAAI,EAGpCmD,EAAYnD,GAAU,KAAgB,IAATA,GAA2B,MAAXA,EAGxCkD,IACJrD,EAAWwD,GAAqBlG,EAAGiC,EAAO8D,IAI3CrD,EAAWyD,GAAanG,EAAG0C,EAAUT,EAAO+D,GAGvCA,GAGChG,EAAE0F,aACNO,EAAWhE,EAAM4C,kBAAkB,iBAC9BoB,IACJr8B,EAAOm5B,aAAckB,GAAagC,GAEnCA,EAAWhE,EAAM4C,kBAAkB,QAC9BoB,IACJr8B,EAAOo5B,KAAMiB,GAAagC,IAKZ,MAAXpD,GAA6B,SAAX7C,EAAExvB,KACxB40B,EAAa,YAGS,MAAXvC,EACXuC,EAAa,eAIbA,EAAa1C,EAASzb,MACtBqe,EAAU5C,EAASrxB,KACnBH,EAAQwxB,EAASxxB,MACjB80B,GAAa90B,KAKdA,EAAQk0B,GACHvC,IAAWuC,KACfA,EAAa,QACC,EAATvC,IACJA,EAAS,KAMZZ,EAAMY,OAASA,EACfZ,EAAMmD,YAAeU,GAAoBV,GAAe,GAGnDY,EACJ7e,EAAS/W,YAAak0B,GAAmBgB,EAASF,EAAYnD,IAE9D9a,EAASif,WAAY9B,GAAmBrC,EAAOmD,EAAYl0B,IAI5D+wB,EAAMwC,WAAYA,GAClBA,EAAat7B,UAERk7B,GACJE,EAAmBl0B,QAAS21B,EAAY,cAAgB,aACrD/D,EAAOjC,EAAGgG,EAAYV,EAAUp0B,IAIpCszB,EAAiB1d,SAAUwd,GAAmBrC,EAAOmD,IAEhDf,IACJE,EAAmBl0B,QAAS,gBAAkB4xB,EAAOjC,MAE3Cp2B,EAAOk5B,QAChBl5B,EAAO2lB,MAAMlf,QAAQ,cAKxB,MAAO4xB,IAGRoE,QAAS,SAAUpM,EAAK5oB,EAAMrD,GAC7B,MAAOpE,GAAO6D,IAAKwsB,EAAK5oB,EAAMrD,EAAU,SAGzCs4B,UAAW,SAAUrM,EAAKjsB,GACzB,MAAOpE,GAAO6D,IAAKwsB,EAAK9wB,UAAW6E,EAAU,aAI/CpE,EAAOmE,MAAQ,MAAO,QAAU,SAAUU,EAAG82B,GAC5C37B,EAAQ27B,GAAW,SAAUtL,EAAK5oB,EAAMrD,EAAUwC,GAQjD,MANK5G,GAAOsD,WAAYmE,KACvBb,EAAOA,GAAQxC,EACfA,EAAWqD,EACXA,EAAOlI,WAGDS,EAAOswB,MACbD,IAAKA,EACLzpB,KAAM+0B,EACNpL,SAAU3pB,EACVa,KAAMA,EACNi0B,QAASt3B,MASZ,SAASk4B,IAAqBlG,EAAGiC,EAAO8D,GAEvC,GAAIQ,GAAI/1B,EAAMg2B,EAAeC,EAC5BtR,EAAW6K,EAAE7K,SACb2M,EAAY9B,EAAE8B,SAGf,OAA0B,MAAnBA,EAAW,GACjBA,EAAUtnB,QACL+rB,IAAOp9B,YACXo9B,EAAKvG,EAAEkF,UAAYjD,EAAM4C,kBAAkB,gBAK7C,IAAK0B,EACJ,IAAM/1B,IAAQ2kB,GACb,GAAKA,EAAU3kB,IAAU2kB,EAAU3kB,GAAOxD,KAAMu5B,GAAO,CACtDzE,EAAUrkB,QAASjN,EACnB,OAMH,GAAKsxB,EAAW,IAAOiE,GACtBS,EAAgB1E,EAAW,OACrB,CAEN,IAAMtxB,IAAQu1B,GAAY,CACzB,IAAMjE,EAAW,IAAO9B,EAAEuD,WAAY/yB,EAAO,IAAMsxB,EAAU,IAAO,CACnE0E,EAAgBh2B,CAChB,OAEKi2B,IACLA,EAAgBj2B,GAIlBg2B,EAAgBA,GAAiBC,EAMlC,MAAKD,IACCA,IAAkB1E,EAAW,IACjCA,EAAUrkB,QAAS+oB,GAEbT,EAAWS,IAJnB,UAWD,QAASL,IAAanG,EAAG0C,EAAUT,EAAO+D,GACzC,GAAIU,GAAOC,EAASC,EAAM10B,EAAKkjB,EAC9BmO,KAEAzB,EAAY9B,EAAE8B,UAAUv3B,OAGzB,IAAKu3B,EAAW,GACf,IAAM8E,IAAQ5G,GAAEuD,WACfA,EAAYqD,EAAKzzB,eAAkB6sB,EAAEuD,WAAYqD,EAInDD,GAAU7E,EAAUtnB,OAGpB,OAAQmsB,EAcP,GAZK3G,EAAEsD,eAAgBqD,KACtB1E,EAAOjC,EAAEsD,eAAgBqD,IAAcjE,IAIlCtN,GAAQ4Q,GAAahG,EAAE6G,aAC5BnE,EAAW1C,EAAE6G,WAAYnE,EAAU1C,EAAE7F,WAGtC/E,EAAOuR,EACPA,EAAU7E,EAAUtnB,QAKnB,GAAiB,MAAZmsB,EAEJA,EAAUvR,MAGJ,IAAc,MAATA,GAAgBA,IAASuR,EAAU,CAM9C,GAHAC,EAAOrD,EAAYnO,EAAO,IAAMuR,IAAapD,EAAY,KAAOoD,IAG1DC,EACL,IAAMF,IAASnD,GAId,GADArxB,EAAMw0B,EAAMzxB,MAAO,KACd/C,EAAK,KAAQy0B,IAGjBC,EAAOrD,EAAYnO,EAAO,IAAMljB,EAAK,KACpCqxB,EAAY,KAAOrxB,EAAK,KACb,CAEN00B,KAAS,EACbA,EAAOrD,EAAYmD,GAGRnD,EAAYmD,MAAY,IACnCC,EAAUz0B,EAAK,GACf4vB,EAAUrkB,QAASvL,EAAK,IAEzB,OAOJ,GAAK00B,KAAS,EAGb,GAAKA,GAAQ5G,EAAG,UACf0C,EAAWkE,EAAMlE,OAEjB,KACCA,EAAWkE,EAAMlE,GAChB,MAAQ1xB,GACT,OAASiW,MAAO,cAAe/V,MAAO01B,EAAO51B,EAAI,sBAAwBokB,EAAO,OAASuR,IAQ/F,OAAS1f,MAAO,UAAW5V,KAAMqxB,GAGlC94B,EAAOg6B,WACN/Y,SACCpY,OAAQ,6FAET0iB,UACC1iB,OAAQ,uBAET8wB,YACCuD,cAAe,SAAUl0B,GAExB,MADAhJ,GAAO2I,WAAYK,GACZA,MAMVhJ,EAAOk6B,cAAe,SAAU,SAAU9D,GACpCA,EAAE1lB,QAAUnR,YAChB62B,EAAE1lB,OAAQ,GAEN0lB,EAAEwF,cACNxF,EAAExvB,KAAO,SAKX5G,EAAOm6B,cAAe,SAAU,SAAU/D,GAEzC,GAAKA,EAAEwF,YAAc,CACpB,GAAI/yB,GAAQzE,CACZ,QACC63B,KAAM,SAAUjtB,EAAGgqB,GAClBnwB,EAAS7I,EAAO,YAAYuhB,MAC3BiP,OAAO,EACP2M,QAAS/G,EAAEgH,cACX73B,IAAK6wB,EAAE/F,MACLtF,GACF,aACA3mB,EAAW,SAAUi5B,GACpBx0B,EAAOd,SACP3D,EAAW,KACNi5B,GACJrE,EAAuB,UAAbqE,EAAIz2B,KAAmB,IAAM,IAAKy2B,EAAIz2B,QAInDhH,EAASqJ,KAAKC,YAAaL,EAAQ,KAEpC0yB,MAAO,WACDn3B,GACJA,QAML,IAAIk5B,OACHC,GAAS,mBAGVv9B,GAAOg6B,WACNwD,MAAO,WACPC,cAAe,WACd,GAAIr5B,GAAWk5B,GAAarwB,OAAWjN,EAAO8F,QAAU,IAAQoxB,IAEhE,OADAv0B,MAAMyB,IAAa,EACZA,KAKTpE,EAAOk6B,cAAe,aAAc,SAAU9D,EAAGsH,EAAkBrF,GAElE,GAAIsF,GAAcC,EAAaC,EAC9BC,EAAW1H,EAAEoH,SAAU,IAAWD,GAAOn6B,KAAMgzB,EAAE/F,KAChD,MACkB,gBAAX+F,GAAE3uB,QAAwB2uB,EAAEmD,aAAe,IAAK14B,QAAQ,sCAAwC08B,GAAOn6B,KAAMgzB,EAAE3uB,OAAU,OAIlI,OAAKq2B,IAAiC,UAArB1H,EAAE8B,UAAW,IAG7ByF,EAAevH,EAAEqH,cAAgBz9B,EAAOsD,WAAY8yB,EAAEqH,eACrDrH,EAAEqH,gBACFrH,EAAEqH,cAGEK,EACJ1H,EAAG0H,GAAa1H,EAAG0H,GAAW73B,QAASs3B,GAAQ,KAAOI,GAC3CvH,EAAEoH,SAAU,IACvBpH,EAAE/F,MAAS8G,GAAY/zB,KAAMgzB,EAAE/F,KAAQ,IAAM,KAAQ+F,EAAEoH,MAAQ,IAAMG,GAItEvH,EAAEuD,WAAW,eAAiB,WAI7B,MAHMkE,IACL79B,EAAOsH,MAAOq2B,EAAe,mBAEvBE,EAAmB,IAI3BzH,EAAE8B,UAAW,GAAM,OAGnB0F,EAAct+B,EAAQq+B,GACtBr+B,EAAQq+B,GAAiB,WACxBE,EAAoBp5B,WAIrB4zB,EAAM/a,OAAO,WAEZhe,EAAQq+B,GAAiBC,EAGpBxH,EAAGuH,KAEPvH,EAAEqH,cAAgBC,EAAiBD,cAGnCH,GAAa78B,KAAMk9B,IAIfE,GAAqB79B,EAAOsD,WAAYs6B,IAC5CA,EAAaC,EAAmB,IAGjCA,EAAoBD,EAAcr+B,YAI5B,UAtDR,YAyDDS,EAAOs2B,aAAayH,IAAM,WACzB,IACC,MAAO,IAAIC,gBACV,MAAO52B,KAGV,IAAI62B,IAAej+B,EAAOs2B,aAAayH,MACtCG,IAEC,EAAG,IAGHC,KAAM,KAKPC,GAAQ,EACRC,KAEI/+B,GAAOg/B,eACXt+B,EAAQV,GAASyrB,GAAI,SAAU,WAC9B,IAAK,GAAIxgB,KAAO8zB,IACfA,GAAc9zB,IAEf8zB,IAAe9+B,YAIjBS,EAAOsL,QAAQizB,OAASN,IAAkB,mBAAqBA,IAC/Dj+B,EAAOsL,QAAQglB,KAAO2N,KAAiBA,GAEvCj+B,EAAOm6B,cAAc,SAAU90B,GAC9B,GAAIjB,EAEJ,OAAKpE,GAAOsL,QAAQizB,MAAQN,KAAiB54B,EAAQu2B,aAEnDK,KAAM,SAAUF,EAAS/C,GACxB,GAAIn0B,GAAGgL,EACNkuB,EAAM14B,EAAQ04B,KAGf,IAFAA,EAAIS,KAAMn5B,EAAQuB,KAAMvB,EAAQgrB,IAAKhrB,EAAQmrB,MAAOnrB,EAAQo5B,SAAUp5B,EAAQ6S,UAEzE7S,EAAQq5B,UACZ,IAAM75B,IAAKQ,GAAQq5B,UAClBX,EAAKl5B,GAAMQ,EAAQq5B,UAAW75B,EAI3BQ,GAAQi2B,UAAYyC,EAAI1C,kBAC5B0C,EAAI1C,iBAAkBh2B,EAAQi2B,UAOzBj2B,EAAQu2B,aAAgBG,EAAQ,sBACrCA,EAAQ,oBAAsB,iBAG/B,KAAMl3B,IAAKk3B,GACVgC,EAAI5C,iBAAkBt2B,EAAGk3B,EAASl3B,GAGnCT,GAAW,SAAUwC,GACpB,MAAO,YACDxC,UACGi6B,IAAcxuB,GACrBzL,EAAW25B,EAAIY,OAASZ,EAAIa,QAAU,KACxB,UAATh4B,EACJm3B,EAAIxC,QACgB,UAAT30B,EACXoyB,EAEC+E,EAAI9E,QAAU,IACd8E,EAAIvC,YAGLxC,EACCkF,GAAkBH,EAAI9E,SAAY8E,EAAI9E,OACtC8E,EAAIvC,WAIwB,gBAArBuC,GAAIhF,cACV/vB,KAAM+0B,EAAIhF,cACPx5B,UACJw+B,EAAI7C,4BAOT6C,EAAIY,OAASv6B,IACb25B,EAAIa,QAAUx6B,EAAS,SAEvBA,EAAWi6B,GAAexuB,EAAKuuB,MAAah6B,EAAS,SAIrD25B,EAAI9B,KAAM52B,EAAQw2B,YAAcx2B,EAAQoC,MAAQ,OAEjD8zB,MAAO,WACDn3B,GACJA,MAtEJ,WA4ED,IAAIy6B,IAAOC,GACVC,GAAW,yBACXC,GAAatxB,OAAQ,iBAAmBlM,EAAY,cAAe,KACnEy9B,GAAO,cACPC,IAAwBC,IACxBC,IACC5F,KAAM,SAAUjY,EAAM/X,GACrB,GAAI61B,GAAQ18B,KAAK28B,YAAa/d,EAAM/X,GACnC7D,EAAS05B,EAAMhuB,MACfqkB,EAAQsJ,GAAOl8B,KAAM0G,GACrB+1B,EAAO7J,GAASA,EAAO,KAAS11B,EAAOwzB,UAAWjS,GAAS,GAAK,MAGhEzL,GAAU9V,EAAOwzB,UAAWjS,IAAmB,OAATge,IAAkB55B,IACvDq5B,GAAOl8B,KAAM9C,EAAO4yB,IAAKyM,EAAM38B,KAAM6e,IACtCie,EAAQ,EACRC,EAAgB,EAEjB,IAAK3pB,GAASA,EAAO,KAAQypB,EAAO,CAEnCA,EAAOA,GAAQzpB,EAAO,GAGtB4f,EAAQA,MAGR5f,GAASnQ,GAAU,CAEnB,GAGC65B,GAAQA,GAAS,KAGjB1pB,GAAgB0pB,EAChBx/B,EAAOgL,MAAOq0B,EAAM38B,KAAM6e,EAAMzL,EAAQypB,SAI/BC,KAAWA,EAAQH,EAAMhuB,MAAQ1L,IAAqB,IAAV65B,KAAiBC,GAaxE,MATK/J,KACJ5f,EAAQupB,EAAMvpB,OAASA,IAAUnQ,GAAU,EAC3C05B,EAAME,KAAOA,EAEbF,EAAMp6B,IAAMywB,EAAO,GAClB5f,GAAU4f,EAAO,GAAM,GAAMA,EAAO,IACnCA,EAAO,IAGH2J,IAKV,SAASK,MAIR,MAHAv0B,YAAW,WACV0zB,GAAQt/B,YAEAs/B,GAAQ7+B,EAAO4K,MAGzB,QAAS00B,IAAa91B,EAAO+X,EAAMoe,GAClC,GAAIN,GACHO,GAAeR,GAAU7d,QAAehhB,OAAQ6+B,GAAU,MAC1DriB,EAAQ,EACRla,EAAS+8B,EAAW/8B,MACrB,MAAgBA,EAARka,EAAgBA,IACvB,GAAMsiB,EAAQO,EAAY7iB,GAAQnZ,KAAM+7B,EAAWpe,EAAM/X,GAGxD,MAAO61B,GAKV,QAASQ,IAAWn9B,EAAMo9B,EAAYz6B,GACrC,GAAIkQ,GACHwqB,EACAhjB,EAAQ,EACRla,EAASq8B,GAAoBr8B,OAC7B0a,EAAWvd,EAAOiL,WAAWqS,OAAQ,iBAE7B0iB,GAAKt9B,OAEbs9B,EAAO,WACN,GAAKD,EACJ,OAAO,CAER,IAAIE,GAAcpB,IAASa,KAC1BlhB,EAAYzY,KAAKwe,IAAK,EAAGob,EAAUO,UAAYP,EAAUQ,SAAWF,GAEpEtmB,EAAO6E,EAAYmhB,EAAUQ,UAAY,EACzCC,EAAU,EAAIzmB,EACdoD,EAAQ,EACRla,EAAS88B,EAAUU,OAAOx9B,MAE3B,MAAgBA,EAARka,EAAiBA,IACxB4iB,EAAUU,OAAQtjB,GAAQujB,IAAKF,EAKhC,OAFA7iB,GAASqB,WAAYlc,GAAQi9B,EAAWS,EAAS5hB,IAElC,EAAV4hB,GAAev9B,EACZ2b,GAEPjB,EAAS/W,YAAa9D,GAAQi9B,KACvB,IAGTA,EAAYpiB,EAASjZ,SACpB5B,KAAMA,EACNgmB,MAAO1oB,EAAOoF,UAAY06B,GAC1BS,KAAMvgC,EAAOoF,QAAQ,GAAQo7B,kBAAqBn7B,GAClDo7B,mBAAoBX,EACpB1H,gBAAiB/yB,EACjB66B,UAAWrB,IAASa,KACpBS,SAAU96B,EAAQ86B,SAClBE,UACAf,YAAa,SAAU/d,EAAMtc,GAC5B,GAAIo6B,GAAQr/B,EAAO0gC,MAAOh+B,EAAMi9B,EAAUY,KAAMhf,EAAMtc,EACpD06B,EAAUY,KAAKC,cAAejf,IAAUoe,EAAUY,KAAKI,OAEzD,OADAhB,GAAUU,OAAO5/B,KAAM4+B,GAChBA,GAER7c,KAAM,SAAUoe,GACf,GAAI7jB,GAAQ,EAGXla,EAAS+9B,EAAUjB,EAAUU,OAAOx9B,OAAS,CAC9C,IAAKk9B,EACJ,MAAOp9B,KAGR,KADAo9B,GAAU,EACMl9B,EAARka,EAAiBA,IACxB4iB,EAAUU,OAAQtjB,GAAQujB,IAAK,EAUhC,OALKM,GACJrjB,EAAS/W,YAAa9D,GAAQi9B,EAAWiB,IAEzCrjB,EAASif,WAAY95B,GAAQi9B,EAAWiB,IAElCj+B,QAGT+lB,EAAQiX,EAAUjX,KAInB,KAFAmY,GAAYnY,EAAOiX,EAAUY,KAAKC,eAElB39B,EAARka,EAAiBA,IAExB,GADAxH,EAAS2pB,GAAqBniB,GAAQnZ,KAAM+7B,EAAWj9B,EAAMgmB,EAAOiX,EAAUY,MAE7E,MAAOhrB,EAmBT,OAfAvV,GAAOgF,IAAK0jB,EAAO4W,GAAaK,GAE3B3/B,EAAOsD,WAAYq8B,EAAUY,KAAKzqB,QACtC6pB,EAAUY,KAAKzqB,MAAMlS,KAAMlB,EAAMi9B,GAGlC3/B,EAAO4iB,GAAGke,MACT9gC,EAAOoF,OAAQ46B,GACdt9B,KAAMA,EACNq+B,KAAMpB,EACNzd,MAAOyd,EAAUY,KAAKre,SAKjByd,EAAU1hB,SAAU0hB,EAAUY,KAAKtiB,UACxC1Z,KAAMo7B,EAAUY,KAAKh8B,KAAMo7B,EAAUY,KAAKvH,UAC1Cxb,KAAMmiB,EAAUY,KAAK/iB,MACrBF,OAAQqiB,EAAUY,KAAKjjB,QAG1B,QAASujB,IAAYnY,EAAO8X,GAC3B,GAAIzjB,GAAOzX,EAAMq7B,EAAQn3B,EAAO6Y,CAGhC,KAAMtF,IAAS2L,GAed,GAdApjB,EAAOtF,EAAOoJ,UAAW2T,GACzB4jB,EAASH,EAAel7B,GACxBkE,EAAQkf,EAAO3L,GACV/c,EAAO6F,QAAS2D,KACpBm3B,EAASn3B,EAAO,GAChBA,EAAQkf,EAAO3L,GAAUvT,EAAO,IAG5BuT,IAAUzX,IACdojB,EAAOpjB,GAASkE,QACTkf,GAAO3L,IAGfsF,EAAQriB,EAAOqzB,SAAU/tB,GACpB+c,GAAS,UAAYA,GAAQ,CACjC7Y,EAAQ6Y,EAAMmT,OAAQhsB,SACfkf,GAAOpjB,EAId,KAAMyX,IAASvT,GACNuT,IAAS2L,KAChBA,EAAO3L,GAAUvT,EAAOuT,GACxByjB,EAAezjB,GAAU4jB,OAI3BH,GAAel7B,GAASq7B,EAK3B3gC,EAAO6/B,UAAY7/B,EAAOoF,OAAQy6B,IAEjCmB,QAAS,SAAUtY,EAAOtkB,GACpBpE,EAAOsD,WAAYolB,IACvBtkB,EAAWskB,EACXA,GAAU,MAEVA,EAAQA,EAAMrd,MAAM,IAGrB,IAAIkW,GACHxE,EAAQ,EACRla,EAAS6lB,EAAM7lB,MAEhB,MAAgBA,EAARka,EAAiBA,IACxBwE,EAAOmH,EAAO3L,GACdqiB,GAAU7d,GAAS6d,GAAU7d,OAC7B6d,GAAU7d,GAAO1N,QAASzP,IAI5B68B,UAAW,SAAU78B,EAAUiqB,GACzBA,EACJ6Q,GAAoBrrB,QAASzP,GAE7B86B,GAAoBz+B,KAAM2D,KAK7B,SAAS+6B,IAAkBz8B,EAAMgmB,EAAO6X,GAEvC,GAAIhf,GAAM/X,EAAO4pB,EAAQiM,EAAOhd,EAAO6e,EACtCH,EAAOp+B,KACPgoB,KACA3f,EAAQtI,EAAKsI,MACbgoB,EAAStwB,EAAKQ,UAAYwvB,GAAUhwB,GACpCy+B,EAAWxgB,EAAU9c,IAAKnB,EAAM,SAG3B69B,GAAKre,QACVG,EAAQriB,EAAOsiB,YAAa5f,EAAM,MACX,MAAlB2f,EAAM+e,WACV/e,EAAM+e,SAAW,EACjBF,EAAU7e,EAAM7K,MAAMkF,KACtB2F,EAAM7K,MAAMkF,KAAO,WACZ2F,EAAM+e,UACXF,MAIH7e,EAAM+e,WAENL,EAAKzjB,OAAO,WAGXyjB,EAAKzjB,OAAO,WACX+E,EAAM+e,WACAphC,EAAOkiB,MAAOxf,EAAM,MAAOG,QAChCwf,EAAM7K,MAAMkF,YAOO,IAAlBha,EAAKQ,WAAoB,UAAYwlB,IAAS,SAAWA,MAK7D6X,EAAKc,UAAar2B,EAAMq2B,SAAUr2B,EAAMs2B,UAAWt2B,EAAMu2B,WAIlB,WAAlCvhC,EAAO4yB,IAAKlwB,EAAM,YACW,SAAhC1C,EAAO4yB,IAAKlwB,EAAM,WAEnBsI,EAAMinB,QAAU,iBAIbsO,EAAKc,WACTr2B,EAAMq2B,SAAW,SACjBN,EAAKzjB,OAAO,WACXtS,EAAMq2B,SAAWd,EAAKc,SAAU,GAChCr2B,EAAMs2B,UAAYf,EAAKc,SAAU,GACjCr2B,EAAMu2B,UAAYhB,EAAKc,SAAU,KAMnC,KAAM9f,IAAQmH,GAEb,GADAlf,EAAQkf,EAAOnH,GACVwd,GAASj8B,KAAM0G,GAAU,CAG7B,SAFOkf,GAAOnH,GACd6R,EAASA,GAAoB,WAAV5pB,EACdA,KAAYwpB,EAAS,OAAS,QAAW,CAG7C,GAAe,SAAVxpB,IAAoB23B,GAAYA,EAAU5f,KAAWhiB,UAGzD,QAFAyzB,IAAS,EAKXrI,EAAMpJ,GAAS4f,GAAYA,EAAU5f,IAAUvhB,EAAOgL,MAAOtI,EAAM6e,GAIrE,IAAMvhB,EAAOqH,cAAesjB,GAAS,CAC/BwW,EACC,UAAYA,KAChBnO,EAASmO,EAASnO,QAGnBmO,EAAWxgB,EAAUrW,OAAQ5H,EAAM,aAI/B0wB,IACJ+N,EAASnO,QAAUA,GAEfA,EACJhzB,EAAQ0C,GAAOqwB,OAEfgO,EAAKx8B,KAAK,WACTvE,EAAQ0C,GAAOywB,SAGjB4N,EAAKx8B,KAAK,WACT,GAAIgd,EAEJZ,GAAU5Y,OAAQrF,EAAM,SACxB,KAAM6e,IAAQoJ,GACb3qB,EAAOgL,MAAOtI,EAAM6e,EAAMoJ,EAAMpJ,KAGlC,KAAMA,IAAQoJ,GACb0U,EAAQC,GAAatM,EAASmO,EAAU5f,GAAS,EAAGA,EAAMwf,GAElDxf,IAAQ4f,KACfA,EAAU5f,GAAS8d,EAAMvpB,MACpBkd,IACJqM,EAAMp6B,IAAMo6B,EAAMvpB,MAClBupB,EAAMvpB,MAAiB,UAATyL,GAA6B,WAATA,EAAoB,EAAI,KAO/D,QAASmf,IAAOh+B,EAAM2C,EAASkc,EAAMtc,EAAK07B,GACzC,MAAO,IAAID,IAAMp+B,UAAUf,KAAMmB,EAAM2C,EAASkc,EAAMtc,EAAK07B,GAE5D3gC,EAAO0gC,MAAQA,GAEfA,GAAMp+B,WACLE,YAAak+B,GACbn/B,KAAM,SAAUmB,EAAM2C,EAASkc,EAAMtc,EAAK07B,EAAQpB,GACjD58B,KAAKD,KAAOA,EACZC,KAAK4e,KAAOA,EACZ5e,KAAKg+B,OAASA,GAAU,QACxBh+B,KAAK0C,QAAUA,EACf1C,KAAKmT,MAAQnT,KAAKiI,IAAMjI,KAAK0O,MAC7B1O,KAAKsC,IAAMA,EACXtC,KAAK48B,KAAOA,IAAUv/B,EAAOwzB,UAAWjS,GAAS,GAAK,OAEvDlQ,IAAK,WACJ,GAAIgR,GAAQqe,GAAM1b,UAAWriB,KAAK4e,KAElC,OAAOc,IAASA,EAAMxe,IACrBwe,EAAMxe,IAAKlB,MACX+9B,GAAM1b,UAAUgD,SAASnkB,IAAKlB,OAEhC29B,IAAK,SAAUF,GACd,GAAIoB,GACHnf,EAAQqe,GAAM1b,UAAWriB,KAAK4e,KAoB/B,OAjBC5e,MAAKkpB,IAAM2V,EADP7+B,KAAK0C,QAAQ86B,SACEngC,EAAO2gC,OAAQh+B,KAAKg+B,QACtCP,EAASz9B,KAAK0C,QAAQ86B,SAAWC,EAAS,EAAG,EAAGz9B,KAAK0C,QAAQ86B,UAG3CC,EAEpBz9B,KAAKiI,KAAQjI,KAAKsC,IAAMtC,KAAKmT,OAAU0rB,EAAQ7+B,KAAKmT,MAE/CnT,KAAK0C,QAAQo8B,MACjB9+B,KAAK0C,QAAQo8B,KAAK79B,KAAMjB,KAAKD,KAAMC,KAAKiI,IAAKjI,MAGzC0f,GAASA,EAAMf,IACnBe,EAAMf,IAAK3e,MAEX+9B,GAAM1b,UAAUgD,SAAS1G,IAAK3e,MAExBA,OAIT+9B,GAAMp+B,UAAUf,KAAKe,UAAYo+B,GAAMp+B,UAEvCo+B,GAAM1b,WACLgD,UACCnkB,IAAK,SAAUw7B,GACd,GAAI9pB,EAEJ,OAAiC,OAA5B8pB,EAAM38B,KAAM28B,EAAM9d,OACpB8d,EAAM38B,KAAKsI,OAA2C,MAAlCq0B,EAAM38B,KAAKsI,MAAOq0B,EAAM9d,OAQ/ChM,EAASvV,EAAO4yB,IAAKyM,EAAM38B,KAAM28B,EAAM9d,KAAM,IAErChM,GAAqB,SAAXA,EAAwBA,EAAJ,GAT9B8pB,EAAM38B,KAAM28B,EAAM9d,OAW3BD,IAAK,SAAU+d,GAGTr/B,EAAO4iB,GAAG6e,KAAMpC,EAAM9d,MAC1BvhB,EAAO4iB,GAAG6e,KAAMpC,EAAM9d,MAAQ8d,GACnBA,EAAM38B,KAAKsI,QAAgE,MAArDq0B,EAAM38B,KAAKsI,MAAOhL,EAAOg0B,SAAUqL,EAAM9d,QAAoBvhB,EAAOqzB,SAAUgM,EAAM9d,OACrHvhB,EAAOgL,MAAOq0B,EAAM38B,KAAM28B,EAAM9d,KAAM8d,EAAMz0B,IAAMy0B,EAAME,MAExDF,EAAM38B,KAAM28B,EAAM9d,MAAS8d,EAAMz0B,OASrC81B,GAAM1b,UAAUyE,UAAYiX,GAAM1b,UAAUqE,YAC3C/H,IAAK,SAAU+d,GACTA,EAAM38B,KAAKQ,UAAYm8B,EAAM38B,KAAKe,aACtC47B,EAAM38B,KAAM28B,EAAM9d,MAAS8d,EAAMz0B,OAKpC5K,EAAOmE,MAAO,SAAU,OAAQ,QAAU,SAAUU,EAAGS,GACtD,GAAIo8B,GAAQ1hC,EAAOsB,GAAIgE,EACvBtF,GAAOsB,GAAIgE,GAAS,SAAUq8B,EAAOhB,EAAQv8B,GAC5C,MAAgB,OAATu9B,GAAkC,iBAAVA,GAC9BD,EAAMl9B,MAAO7B,KAAM8B,WACnB9B,KAAKi/B,QAASC,GAAOv8B,GAAM,GAAQq8B,EAAOhB,EAAQv8B,MAIrDpE,EAAOsB,GAAG8D,QACT08B,OAAQ,SAAUH,EAAOI,EAAIpB,EAAQv8B,GAGpC,MAAOzB,MAAK+P,OAAQggB,IAAWE,IAAK,UAAW,GAAIG,OAGjD9tB,MAAM28B,SAAUtO,QAASyO,GAAMJ,EAAOhB,EAAQv8B,IAEjDw9B,QAAS,SAAUrgB,EAAMogB,EAAOhB,EAAQv8B,GACvC,GAAIoT,GAAQxX,EAAOqH,cAAeka,GACjCygB,EAAShiC,EAAO2hC,MAAOA,EAAOhB,EAAQv8B,GACtC69B,EAAc,WAEb,GAAIlB,GAAOlB,GAAWl9B,KAAM3C,EAAOoF,UAAYmc,GAAQygB,IAGlDxqB,GAASmJ,EAAU9c,IAAKlB,KAAM,YAClCo+B,EAAKve,MAAM,GAKd,OAFCyf,GAAYC,OAASD,EAEfzqB,GAASwqB,EAAO9f,SAAU,EAChCvf,KAAKwB,KAAM89B,GACXt/B,KAAKuf,MAAO8f,EAAO9f,MAAO+f,IAE5Bzf,KAAM,SAAU5b,EAAMoc,EAAY4d,GACjC,GAAIuB,GAAY,SAAU9f,GACzB,GAAIG,GAAOH,EAAMG,WACVH,GAAMG,KACbA,EAAMoe,GAYP,OATqB,gBAATh6B,KACXg6B,EAAU5d,EACVA,EAAapc,EACbA,EAAOrH,WAEHyjB,GAAcpc,KAAS,GAC3BjE,KAAKuf,MAAOtb,GAAQ,SAGdjE,KAAKwB,KAAK,WAChB,GAAIge,IAAU,EACbpF,EAAgB,MAARnW,GAAgBA,EAAO,aAC/Bw7B,EAASpiC,EAAOoiC,OAChB36B,EAAOkZ,EAAU9c,IAAKlB,KAEvB,IAAKoa,EACCtV,EAAMsV,IAAWtV,EAAMsV,GAAQyF,MACnC2f,EAAW16B,EAAMsV,QAGlB,KAAMA,IAAStV,GACTA,EAAMsV,IAAWtV,EAAMsV,GAAQyF,MAAQyc,GAAK77B,KAAM2Z,IACtDolB,EAAW16B,EAAMsV,GAKpB,KAAMA,EAAQqlB,EAAOv/B,OAAQka,KACvBqlB,EAAQrlB,GAAQra,OAASC,MAAiB,MAARiE,GAAgBw7B,EAAQrlB,GAAQmF,QAAUtb,IAChFw7B,EAAQrlB,GAAQgkB,KAAKve,KAAMoe,GAC3Bze,GAAU,EACVigB,EAAOj9B,OAAQ4X,EAAO,KAOnBoF,IAAYye,IAChB5gC,EAAOmiB,QAASxf,KAAMiE,MAIzBs7B,OAAQ,SAAUt7B,GAIjB,MAHKA,MAAS,IACbA,EAAOA,GAAQ,MAETjE,KAAKwB,KAAK,WAChB,GAAI4Y,GACHtV,EAAOkZ,EAAU9c,IAAKlB,MACtBuf,EAAQza,EAAMb,EAAO,SACrByb,EAAQ5a,EAAMb,EAAO,cACrBw7B,EAASpiC,EAAOoiC,OAChBv/B,EAASqf,EAAQA,EAAMrf,OAAS,CAajC,KAVA4E,EAAKy6B,QAAS,EAGdliC,EAAOkiB,MAAOvf,KAAMiE,MAEfyb,GAASA,EAAMG,MACnBH,EAAMG,KAAK5e,KAAMjB,MAAM,GAIlBoa,EAAQqlB,EAAOv/B,OAAQka,KACvBqlB,EAAQrlB,GAAQra,OAASC,MAAQy/B,EAAQrlB,GAAQmF,QAAUtb,IAC/Dw7B,EAAQrlB,GAAQgkB,KAAKve,MAAM,GAC3B4f,EAAOj9B,OAAQ4X,EAAO,GAKxB,KAAMA,EAAQ,EAAWla,EAARka,EAAgBA,IAC3BmF,EAAOnF,IAAWmF,EAAOnF,GAAQmlB,QACrChgB,EAAOnF,GAAQmlB,OAAOt+B,KAAMjB,YAKvB8E,GAAKy6B,WAMf,SAASL,IAAOj7B,EAAMy7B,GACrB,GAAIvZ,GACH7X,GAAUqxB,OAAQ17B,GAClB/B,EAAI,CAKL,KADAw9B,EAAeA,EAAc,EAAI,EACtB,EAAJx9B,EAAQA,GAAK,EAAIw9B,EACvBvZ,EAAQuJ,GAAWxtB,GACnBoM,EAAO,SAAW6X,GAAU7X,EAAO,UAAY6X,GAAUliB,CAO1D,OAJKy7B,KACJpxB,EAAMqiB,QAAUriB,EAAMuP,MAAQ5Z,GAGxBqK,EAIRjR,EAAOmE,MACNo+B,UAAWV,GAAM,QACjBW,QAASX,GAAM,QACfY,YAAaZ,GAAM,UACnBa,QAAUpP,QAAS,QACnBqP,SAAWrP,QAAS,QACpBsP,YAActP,QAAS,WACrB,SAAUhuB,EAAMojB,GAClB1oB,EAAOsB,GAAIgE,GAAS,SAAUq8B,EAAOhB,EAAQv8B,GAC5C,MAAOzB,MAAKi/B,QAASlZ,EAAOiZ,EAAOhB,EAAQv8B,MAI7CpE,EAAO2hC,MAAQ,SAAUA,EAAOhB,EAAQr/B,GACvC,GAAI2d,GAAM0iB,GAA0B,gBAAVA,GAAqB3hC,EAAOoF,UAAYu8B,IACjE3I,SAAU13B,IAAOA,GAAMq/B,GACtB3gC,EAAOsD,WAAYq+B,IAAWA,EAC/BxB,SAAUwB,EACVhB,OAAQr/B,GAAMq/B,GAAUA,IAAW3gC,EAAOsD,WAAYq9B,IAAYA,EAwBnE,OArBA1hB,GAAIkhB,SAAWngC,EAAO4iB,GAAGlc,IAAM,EAA4B,gBAAjBuY,GAAIkhB,SAAwBlhB,EAAIkhB,SACzElhB,EAAIkhB,WAAYngC,GAAO4iB,GAAGC,OAAS7iB,EAAO4iB,GAAGC,OAAQ5D,EAAIkhB,UAAangC,EAAO4iB,GAAGC,OAAOmF,UAGtE,MAAb/I,EAAIiD,OAAiBjD,EAAIiD,SAAU,KACvCjD,EAAIiD,MAAQ,MAIbjD,EAAIlU,IAAMkU,EAAI+Z,SAEd/Z,EAAI+Z,SAAW,WACTh5B,EAAOsD,WAAY2b,EAAIlU,MAC3BkU,EAAIlU,IAAInH,KAAMjB,MAGVsc,EAAIiD,OACRliB,EAAOmiB,QAASxf,KAAMsc,EAAIiD,QAIrBjD,GAGRjf,EAAO2gC,QACNkC,OAAQ,SAAUC,GACjB,MAAOA,IAERC,MAAO,SAAUD,GAChB,MAAO,GAAM/8B,KAAKi9B,IAAKF,EAAE/8B,KAAKk9B,IAAO,IAIvCjjC,EAAOoiC,UACPpiC,EAAO4iB,GAAK8d,GAAMp+B,UAAUf,KAC5BvB,EAAO4iB,GAAGod,KAAO,WAChB,GAAIc,GACHsB,EAASpiC,EAAOoiC,OAChBv9B,EAAI,CAIL,KAFAg6B,GAAQ7+B,EAAO4K,MAEHw3B,EAAOv/B,OAAXgC,EAAmBA,IAC1Bi8B,EAAQsB,EAAQv9B,GAEVi8B,KAAWsB,EAAQv9B,KAAQi8B,GAChCsB,EAAOj9B,OAAQN,IAAK,EAIhBu9B,GAAOv/B,QACZ7C,EAAO4iB,GAAGJ,OAEXqc,GAAQt/B,WAGTS,EAAO4iB,GAAGke,MAAQ,SAAUA,GACtBA,KAAW9gC,EAAOoiC,OAAO3hC,KAAMqgC,IACnC9gC,EAAO4iB,GAAG9M,SAIZ9V,EAAO4iB,GAAGsgB,SAAW,GAErBljC,EAAO4iB,GAAG9M,MAAQ,WACXgpB,KACLA,GAAUqE,YAAanjC,EAAO4iB,GAAGod,KAAMhgC,EAAO4iB,GAAGsgB,YAInDljC,EAAO4iB,GAAGJ,KAAO,WAChB4gB,cAAetE,IACfA,GAAU,MAGX9+B,EAAO4iB,GAAGC,QACTwgB,KAAM,IACNC,KAAM,IAENtb,SAAU,KAIXhoB,EAAO4iB,GAAG6e,QAELzhC,EAAO8T,MAAQ9T,EAAO8T,KAAKwE,UAC/BtY,EAAO8T,KAAKwE,QAAQirB,SAAW,SAAU7gC,GACxC,MAAO1C,GAAOgK,KAAKhK,EAAOoiC,OAAQ,SAAU9gC,GAC3C,MAAOoB,KAASpB,EAAGoB,OACjBG,SAGL7C,EAAOsB,GAAGkiC,OAAS,SAAUn+B,GAC5B,GAAKZ,UAAU5B,OACd,MAAOwC,KAAY9F,UAClBoD,KACAA,KAAKwB,KAAK,SAAUU,GACnB7E,EAAOwjC,OAAOC,UAAW9gC,KAAM0C,EAASR,IAI3C,IAAIhF,GAAS6jC,EACZhhC,EAAOC,KAAM,GACbghC,GAAQxxB,IAAK,EAAGyxB,KAAM,GACtB7xB,EAAMrP,GAAQA,EAAKS,aAEpB,IAAM4O,EAON,MAHAlS,GAAUkS,EAAIjS,gBAGRE,EAAOmM,SAAUtM,EAAS6C,UAMpBA,GAAKmhC,wBAA0BnkC,IAC1CikC,EAAMjhC,EAAKmhC,yBAEZH,EAAMI,GAAW/xB,IAEhBI,IAAKwxB,EAAIxxB,IAAMuxB,EAAIK,YAAclkC,EAAQ6pB,UACzCka,KAAMD,EAAIC,KAAOF,EAAIM,YAAcnkC,EAAQypB,aAXpCqa,GAeT3jC,EAAOwjC,QAENC,UAAW,SAAU/gC,EAAM2C,EAASR,GACnC,GAAIo/B,GAAaC,EAASC,EAAWC,EAAQC,EAAWC,EAAYC,EACnExS,EAAW/xB,EAAO4yB,IAAKlwB,EAAM,YAC7B8hC,EAAUxkC,EAAQ0C,GAClBgmB,IAGiB,YAAbqJ,IACJrvB,EAAKsI,MAAM+mB,SAAW,YAGvBsS,EAAYG,EAAQhB,SACpBW,EAAYnkC,EAAO4yB,IAAKlwB,EAAM,OAC9B4hC,EAAatkC,EAAO4yB,IAAKlwB,EAAM,QAC/B6hC,GAAmC,aAAbxS,GAAwC,UAAbA,KAA4BoS,EAAYG,GAAazjC,QAAQ,QAAU,GAGnH0jC,GACJN,EAAcO,EAAQzS,WACtBqS,EAASH,EAAY9xB,IACrB+xB,EAAUD,EAAYL,OAGtBQ,EAASn9B,WAAYk9B,IAAe,EACpCD,EAAUj9B,WAAYq9B,IAAgB,GAGlCtkC,EAAOsD,WAAY+B,KACvBA,EAAUA,EAAQzB,KAAMlB,EAAMmC,EAAGw/B,IAGd,MAAfh/B,EAAQ8M,MACZuW,EAAMvW,IAAQ9M,EAAQ8M,IAAMkyB,EAAUlyB,IAAQiyB,GAE1B,MAAhB/+B,EAAQu+B,OACZlb,EAAMkb,KAASv+B,EAAQu+B,KAAOS,EAAUT,KAASM,GAG7C,SAAW7+B,GACfA,EAAQo/B,MAAM7gC,KAAMlB,EAAMgmB,GAG1B8b,EAAQ5R,IAAKlK,KAMhB1oB,EAAOsB,GAAG8D,QAET2sB,SAAU,WACT,GAAMpvB,KAAM,GAAZ,CAIA,GAAI+hC,GAAclB,EACjB9gC,EAAOC,KAAM,GACbgiC,GAAiBxyB,IAAK,EAAGyxB,KAAM,EAuBhC,OApBwC,UAAnC5jC,EAAO4yB,IAAKlwB,EAAM,YAEtB8gC,EAAS9gC,EAAKmhC,yBAIda,EAAe/hC,KAAK+hC,eAGpBlB,EAAS7gC,KAAK6gC,SACRxjC,EAAOsJ,SAAUo7B,EAAc,GAAK,UACzCC,EAAeD,EAAalB,UAI7BmB,EAAaxyB,KAAOnS,EAAO4yB,IAAK8R,EAAc,GAAK,kBAAkB,GACrEC,EAAaf,MAAQ5jC,EAAO4yB,IAAK8R,EAAc,GAAK,mBAAmB,KAKvEvyB,IAAKqxB,EAAOrxB,IAAMwyB,EAAaxyB,IAAMnS,EAAO4yB,IAAKlwB,EAAM,aAAa,GACpEkhC,KAAMJ,EAAOI,KAAOe,EAAaf,KAAO5jC,EAAO4yB,IAAKlwB,EAAM,cAAc,MAI1EgiC,aAAc,WACb,MAAO/hC,MAAKqC,IAAI,WACf,GAAI0/B,GAAe/hC,KAAK+hC,cAAgB7kC,CAExC,OAAQ6kC,IAAmB1kC,EAAOsJ,SAAUo7B,EAAc,SAAsD,WAA1C1kC,EAAO4yB,IAAK8R,EAAc,YAC/FA,EAAeA,EAAaA,YAG7B,OAAOA,IAAgB7kC,OAO1BG,EAAOmE,MAAOklB,WAAY,cAAeI,UAAW,eAAgB,SAAUkS,EAAQpa,GACrF,GAAIpP,GAAM,gBAAkBoP,CAE5BvhB,GAAOsB,GAAIq6B,GAAW,SAAU3nB,GAC/B,MAAOhU,GAAOsK,OAAQ3H,KAAM,SAAUD,EAAMi5B,EAAQ3nB,GACnD,GAAI0vB,GAAMI,GAAWphC,EAErB,OAAKsR,KAAQzU,UACLmkC,EAAMA,EAAKniB,GAAS7e,EAAMi5B,IAG7B+H,EACJA,EAAIkB,SACFzyB,EAAY7S,EAAO0kC,YAAbhwB,EACP7B,EAAM6B,EAAM1U,EAAOykC,aAIpBrhC,EAAMi5B,GAAW3nB,EAPlB,YASE2nB,EAAQ3nB,EAAKvP,UAAU5B,OAAQ,QAIpC,SAASihC,IAAWphC,GACnB,MAAO1C,GAAO8G,SAAUpE,GAASA,EAAyB,IAAlBA,EAAKQ,UAAkBR,EAAKuP,YAGrEjS,EAAOmE,MAAQ0gC,OAAQ,SAAUC,MAAO,SAAW,SAAUx/B,EAAMsB,GAClE5G,EAAOmE,MAAQixB,QAAS,QAAU9vB,EAAMorB,QAAS9pB,EAAM,GAAI,QAAUtB,GAAQ,SAAUy/B,EAAcC,GAEpGhlC,EAAOsB,GAAI0jC,GAAa,SAAU7P,EAAQ3rB,GACzC,GAAIgB,GAAY/F,UAAU5B,SAAYkiC,GAAkC,iBAAX5P,IAC5DjB,EAAQ6Q,IAAkB5P,KAAW,GAAQ3rB,KAAU,EAAO,SAAW,SAE1E,OAAOxJ,GAAOsK,OAAQ3H,KAAM,SAAUD,EAAMkE,EAAM4C,GACjD,GAAIuI,EAEJ,OAAK/R,GAAO8G,SAAUpE,GAIdA,EAAK9C,SAASE,gBAAiB,SAAWwF,GAI3B,IAAlB5C,EAAKQ,UACT6O,EAAMrP,EAAK5C,gBAIJiG,KAAKwe,IACX7hB,EAAKwd,KAAM,SAAW5a,GAAQyM,EAAK,SAAWzM,GAC9C5C,EAAKwd,KAAM,SAAW5a,GAAQyM,EAAK,SAAWzM,GAC9CyM,EAAK,SAAWzM,KAIXkE,IAAUjK,UAEhBS,EAAO4yB,IAAKlwB,EAAMkE,EAAMstB,GAGxBl0B,EAAOgL,MAAOtI,EAAMkE,EAAM4C,EAAO0qB,IAChCttB,EAAM4D,EAAY2qB,EAAS51B,UAAWiL,EAAW,WAQvDxK,EAAOsB,GAAG2jC,KAAO,WAChB,MAAOtiC,MAAKE,QAGb7C,EAAOsB,GAAG4jC,QAAUllC,EAAOsB,GAAGyqB,QAGP,gBAAXoZ,SAAuBA,QAAoC,gBAAnBA,QAAOC,QAK1DD,OAAOC,QAAUplC,EASM,kBAAXqlC,SAAyBA,OAAOC,KAC3CD,OAAQ,YAAc,WAAc,MAAOrlC,KAMtB,gBAAXV,IAAkD,gBAApBA,GAAOM,WAChDN,EAAOU,OAASV,EAAOY,EAAIF,KAGxBV"} \ No newline at end of file diff --git a/examples/_site/js/phaser-examples.js b/examples/_site/js/phaser-examples.js index 51c7587a..d82363e0 100644 --- a/examples/_site/js/phaser-examples.js +++ b/examples/_site/js/phaser-examples.js @@ -95,7 +95,7 @@ $(document).ready(function(){ .done(function(data) { - if (data.version !== '1.1.3') + if (data.version !== '1.1.4') { $("#upgrade").append(data.version); $("#upgrade").css('display', 'inline-block'); diff --git a/examples/_site/js/phaser-viewer.js b/examples/_site/js/phaser-viewer.js index 6b154048..bc57fe0a 100644 --- a/examples/_site/js/phaser-viewer.js +++ b/examples/_site/js/phaser-viewer.js @@ -58,7 +58,7 @@ $(document).ready(function(){ .done(function(data) { - if (data.version !== '1.1.3') + if (data.version !== '1.1.4') { $("#upgrade").append(data.version); $("#upgrade").css('display', 'inline-block'); diff --git a/examples/_site/view_full.html b/examples/_site/view_full.html index 0c87ff57..6e1a2d57 100644 --- a/examples/_site/view_full.html +++ b/examples/_site/view_full.html @@ -81,6 +81,9 @@ + + + @@ -103,6 +106,7 @@ + @@ -115,6 +119,7 @@ + @@ -132,6 +137,7 @@ + @@ -157,7 +163,7 @@
    - Phaser Version: 1.1.3 + Phaser Version: 1.1.4 New version:
    @@ -209,7 +215,7 @@
    - © 2013 Photon Storm Ltd.
    + © 2014 Photon Storm Ltd.
    All rights reserved.
    diff --git a/examples/_site/view_lite.html b/examples/_site/view_lite.html index 2f7dca3c..0134e8ef 100644 --- a/examples/_site/view_lite.html +++ b/examples/_site/view_lite.html @@ -81,6 +81,9 @@ + + + @@ -103,6 +106,7 @@ + @@ -115,6 +119,7 @@ + @@ -132,6 +137,7 @@ + diff --git a/examples/animation/group creation.js b/examples/animation/group creation.js new file mode 100644 index 00000000..ee575536 --- /dev/null +++ b/examples/animation/group creation.js @@ -0,0 +1,40 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create }); + +function preload() { + + game.load.atlas('seacreatures', 'assets/sprites/seacreatures_json.png', 'assets/sprites/seacreatures_json.json'); + game.load.image('undersea', 'assets/pics/undersea.jpg'); + game.load.image('coral', 'assets/pics/seabed.png'); + +} + +function create() { + + game.add.sprite(0, 0, 'undersea'); + + // Here we create our group and populate it with 6 sprites + var group = game.add.group(); + + for (var i = 0; i < 6; i++) + { + // They are evenly spaced out on the X coordinate, with a random Y coordinate + sprite = group.create(120 * i, game.rnd.integerInRange(100, 400), 'seacreatures', 'octopus0000'); + } + + // These are the frame names for the octopus animation. We use the generateFrames function to help create the array. + var frameNames = Phaser.Animation.generateFrameNames('octopus', 0, 24, '', 4); + + // Here is the important part. Group.callAll will call a method that exists on every child in the Group. + // In this case we're saying: child.animations.add('swim', frameNames, 30, true, false) + // The second parameter ('animations') is really important and is the context in which the method is called. + // For animations the context is the Phaser.AnimationManager, which is linked to the child.animations property. + // Everything after the 2nd parameter is just the usual values you'd pass to the animations.add method. + group.callAll('animations.add', 'animations', 'swim', frameNames, 30, true, false); + + // Here we just say 'play the swim animation', this time the 'play' method exists on the child itself, so we can set the context to null. + group.callAll('play', null, 'swim'); + + game.add.sprite(0, 466, 'coral'); + +} diff --git a/examples/assets/audio/CatAstroPhi_shmup_normal.wav b/examples/assets/audio/CatAstroPhi_shmup_normal.wav new file mode 100644 index 00000000..8d31f394 Binary files /dev/null and b/examples/assets/audio/CatAstroPhi_shmup_normal.wav differ diff --git a/examples/assets/audio/protracker/act_of_impulse.mod b/examples/assets/audio/protracker/act_of_impulse.mod new file mode 100644 index 00000000..9b4c9e5b Binary files /dev/null and b/examples/assets/audio/protracker/act_of_impulse.mod differ diff --git a/examples/assets/audio/protracker/chinese_dream.mod b/examples/assets/audio/protracker/chinese_dream.mod new file mode 100644 index 00000000..8b8615e3 Binary files /dev/null and b/examples/assets/audio/protracker/chinese_dream.mod differ diff --git a/examples/assets/audio/protracker/elysium.mod b/examples/assets/audio/protracker/elysium.mod new file mode 100644 index 00000000..fbeae7ea Binary files /dev/null and b/examples/assets/audio/protracker/elysium.mod differ diff --git a/examples/assets/audio/protracker/enigma.mod b/examples/assets/audio/protracker/enigma.mod new file mode 100644 index 00000000..cd93aeb7 Binary files /dev/null and b/examples/assets/audio/protracker/enigma.mod differ diff --git a/examples/assets/audio/protracker/global_trash_3_v2.mod b/examples/assets/audio/protracker/global_trash_3_v2.mod new file mode 100644 index 00000000..876ec467 Binary files /dev/null and b/examples/assets/audio/protracker/global_trash_3_v2.mod differ diff --git a/examples/assets/audio/protracker/just_spank_it.mod b/examples/assets/audio/protracker/just_spank_it.mod new file mode 100644 index 00000000..8a4b5ee9 Binary files /dev/null and b/examples/assets/audio/protracker/just_spank_it.mod differ diff --git a/examples/assets/audio/protracker/macrocosm.mod b/examples/assets/audio/protracker/macrocosm.mod new file mode 100644 index 00000000..db795f50 Binary files /dev/null and b/examples/assets/audio/protracker/macrocosm.mod differ diff --git a/examples/assets/audio/protracker/overload.mod b/examples/assets/audio/protracker/overload.mod new file mode 100644 index 00000000..6a9c32de Binary files /dev/null and b/examples/assets/audio/protracker/overload.mod differ diff --git a/examples/assets/audio/protracker/sd-ingame1.mod b/examples/assets/audio/protracker/sd-ingame1.mod new file mode 100644 index 00000000..ec3434f6 Binary files /dev/null and b/examples/assets/audio/protracker/sd-ingame1.mod differ diff --git a/examples/assets/audio/protracker/the_sweat_shop.mod b/examples/assets/audio/protracker/the_sweat_shop.mod new file mode 100644 index 00000000..fe9fd45c Binary files /dev/null and b/examples/assets/audio/protracker/the_sweat_shop.mod differ diff --git a/examples/assets/buttons/gamepad-input-start.png b/examples/assets/buttons/gamepad-input-start.png new file mode 100644 index 00000000..1e27ac85 Binary files /dev/null and b/examples/assets/buttons/gamepad-input-start.png differ diff --git a/examples/assets/buttons/gamepad-reset-buttons.png b/examples/assets/buttons/gamepad-reset-buttons.png new file mode 100644 index 00000000..c4dd1aca Binary files /dev/null and b/examples/assets/buttons/gamepad-reset-buttons.png differ diff --git a/examples/assets/fonts/desyrel.xml b/examples/assets/fonts/desyrel.xml index 54fcdbba..9919ad35 100644 --- a/examples/assets/fonts/desyrel.xml +++ b/examples/assets/fonts/desyrel.xml @@ -99,7 +99,7 @@ - + diff --git a/examples/assets/fonts/interference_48x48.png b/examples/assets/fonts/interference_48x48.png new file mode 100644 index 00000000..a4c6fa86 Binary files /dev/null and b/examples/assets/fonts/interference_48x48.png differ diff --git a/examples/assets/fonts/interference_48x48_negiert.png b/examples/assets/fonts/interference_48x48_negiert.png new file mode 100644 index 00000000..42eb17a1 Binary files /dev/null and b/examples/assets/fonts/interference_48x48_negiert.png differ diff --git a/examples/assets/games/snake/sprites.png b/examples/assets/games/snake/sprites.png new file mode 100644 index 00000000..fc7102bf Binary files /dev/null and b/examples/assets/games/snake/sprites.png differ diff --git a/examples/assets/maps/ActraiserMapBloodpoolAct1.png b/examples/assets/maps/ActraiserMapBloodpoolAct1.png deleted file mode 100644 index 33fbaa8c..00000000 Binary files a/examples/assets/maps/ActraiserMapBloodpoolAct1.png and /dev/null differ diff --git a/examples/assets/maps/CommandoMap1-1BG.png b/examples/assets/maps/CommandoMap1-1BG.png deleted file mode 100644 index 963eaa46..00000000 Binary files a/examples/assets/maps/CommandoMap1-1BG.png and /dev/null differ diff --git a/examples/assets/maps/ContraMapStage1BG.png b/examples/assets/maps/ContraMapStage1BG.png deleted file mode 100644 index 430400e9..00000000 Binary files a/examples/assets/maps/ContraMapStage1BG.png and /dev/null differ diff --git a/examples/assets/maps/ContraMapStage3BG.png b/examples/assets/maps/ContraMapStage3BG.png deleted file mode 100644 index 913ced4d..00000000 Binary files a/examples/assets/maps/ContraMapStage3BG.png and /dev/null differ diff --git a/examples/assets/maps/ContraMapStage5BG.png b/examples/assets/maps/ContraMapStage5BG.png deleted file mode 100644 index f2a52cba..00000000 Binary files a/examples/assets/maps/ContraMapStage5BG.png and /dev/null differ diff --git a/examples/assets/maps/ContraMapStage6BG.png b/examples/assets/maps/ContraMapStage6BG.png deleted file mode 100644 index e7a05f1f..00000000 Binary files a/examples/assets/maps/ContraMapStage6BG.png and /dev/null differ diff --git a/examples/assets/maps/ContraMapStage7BG.png b/examples/assets/maps/ContraMapStage7BG.png deleted file mode 100644 index c12f54e3..00000000 Binary files a/examples/assets/maps/ContraMapStage7BG.png and /dev/null differ diff --git a/examples/assets/maps/CybernoidMap3BG_bank.png b/examples/assets/maps/CybernoidMap3BG_bank.png deleted file mode 100644 index 8f49737c..00000000 Binary files a/examples/assets/maps/CybernoidMap3BG_bank.png and /dev/null differ diff --git a/examples/assets/maps/burd.tmx b/examples/assets/maps/burd.tmx deleted file mode 100644 index cd06b7c4..00000000 --- a/examples/assets/maps/burd.tmx +++ /dev/null @@ -1,19 +0,0 @@ - - - - - - - - - - - AQAAAAEAAAABAAAAAQAAAAIAAAABAAAAAQAAAAEAAAABAAAAAQAAAAsAAAABAAAAAQAAAAkAAAANAAAAAQAAAAEAAAABAAAAAQAAAAsAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAFAAAADAAAAAEAAAABAAAAAQAAAAIAAAABAAAAAwAAAAEAAAABAAAACAAAAAEAAAABAAAAAQAAAAEAAAABAAAACAAAAAEAAAABAAAAAQAAAAEAAAAJAAAAAQAAAA0AAAABAAAAAQAAAAgAAAABAAAAAQAAAAEAAAAFAAAAAQAAAAEAAAAGAAAAAQAAAAEAAAABAAAACQAAAAEAAAAEAAAAAQAAAAEAAAABAAAAAwAAAAEAAAANAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAgAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAACgAAAAEAAAABAAAAAQAAAAEAAAABAAAABgAAAAEAAAABAAAAAQAAAAgAAAABAAAAAQAAAAEAAAAHAAAAAQAAAAQAAAABAAAAAQAAAAkAAAABAAAADAAAAAwAAAABAAAABgAAAAEAAAAJAAAAAQAAAAEAAAALAAAACAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAgAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAACQAAAAEAAAABAAAAAQAAAAMAAAABAAAAAQAAAAEAAAABAAAAAQAAAAUAAAABAAAAAQAAAAEAAAACAAAAAQAAAAEAAAABAAAAAQAAAAsAAAAHAAAAAQAAAAEAAAAEAAAAAQAAAAEAAAABAAAAAQAAAAEAAAANAAAAAQAAAAEAAAABAAAAAwAAAAEAAAABAAAAAQAAAAEAAAAJAAAAAQAAAAkAAAABAAAAAgAAAAEAAAABAAAAAgAAAAEAAAAMAAAAAQAAAAkAAAABAAAAAQAAAAkAAAABAAAAAQAAAAEAAAAIAAAAAQAAAAEAAAABAAAAAQAAAAgAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAQAAAABAAAAAQAAAAEAAAADAAAAAQAAAAEAAAADAAAAAQAAAAEAAAABAAAAAwAAAAEAAAAHAAAAAQAAAAEAAAACAAAAAQAAAAMAAAABAAAADQAAAAIAAAAKAAAAAQAAAAMAAAABAAAAAQAAAAEAAAAJAAAAAQAAAAQAAAABAAAAAQAAAAEAAAALAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAHAAAAAQAAAAEAAAADAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAABgAAAAEAAAAIAAAAAQAAAAEAAAACAAAAAQAAAAwAAAABAAAAAQAAAAEAAAALAAAADAAAAAgAAAABAAAAAQAAAAEAAAABAAAACwAAAAEAAAABAAAAAQAAAAMAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAABQAAAAEAAAABAAAAAQAAAAEAAAAGAAAAAQAAAAEAAAADAAAAAQAAAAEAAAABAAAABwAAAAEAAAABAAAAAQAAAAYAAAABAAAAAQAAAAgAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAkAAAABAAAAAQAAAAEAAAABAAAABgAAAAEAAAABAAAAAQAAAAEAAAABAAAACQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAoAAAABAAAAAQAAAAkAAAABAAAAAgAAAAEAAAABAAAAAQAAAAEAAAAHAAAAAQAAAAEAAAABAAAABQAAAAEAAAADAAAAAQAAAAEAAAALAAAAAQAAAAEAAAABAAAABwAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAACgAAAAEAAAABAAAAAQAAAAIAAAABAAAAAQAAAAMAAAABAAAAAQAAAAgAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAwAAAAEAAAABAAAAAQAAAAEAAAANAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAABgAAAAEAAAAIAAAAAQAAAAEAAAADAAAAAQAAAAEAAAADAAAAAQAAAAgAAAAGAAAAAQAAAAEAAAABAAAACwAAAAEAAAABAAAAAQAAAAEAAAABAAAACwAAAAEAAAABAAAAAQAAAAEAAAADAAAAAQAAAAEAAAABAAAAAQAAAAwAAAABAAAAAQAAAAkAAAABAAAAAQAAAAIAAAAFAAAAAwAAAAEAAAABAAAAAgAAAAMAAAABAAAACAAAAAQAAAAGAAAAAQAAAAMAAAABAAAACQAAAAYAAAABAAAABAAAAAEAAAAFAAAACQAAAAEAAAAIAAAAAQAAAA== - - - - - AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAAAAAAAAAAAAAAAAAAAAAAAdAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAhAAAAAAAAAAAAAAAAAAAAAAAAABoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAIQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABsAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB0AAAAAAAAAAAAAACEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB0AAAAAAAAAAAAAACEAAAAAAAAAAAAAAB8AAAAAAAAAAAAAAAAAAAAhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAAB4AAAAAAAAAAAAAAAAAAAAAAAAAHwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAHwAAAAAAAAAAAAAAAAAAAB8AAAAAAAAAAAAAAAAAAAAhAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGwAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAcAAAAAAAAAAAAAAAAAAAAAAAAACEAAAAAAAAAAAAAAB8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA== - - - diff --git a/examples/assets/maps/compass grid.tmx b/examples/assets/maps/compass grid.tmx deleted file mode 100644 index 3cf4e09b..00000000 --- a/examples/assets/maps/compass grid.tmx +++ /dev/null @@ -1,11 +0,0 @@ - - - - - - - - eJzt3NuNwkAMhWGaSBm0Qv/l7OOKaC6ei+Pfw3k40oqIYPtLMlkpcL1er0tB5TOQlfdH9rCrf+8+ZupR1u0ze2SocadhbZt1Ht6upf3TjqXWzCznwIxHrf8nLEoe0QYjHrN9luZ/VT7zKY/ZHiM8SsfuTo/WOtQy8vLonauRFvfZlWbWusZYjnfLfYF3r9a6Iz1a9e06P3o+T1hY1rfo9Na2VQ9KWrWR6rYcvyvXKyXGVB6cyIMVebAiD1bkwYo8WJEHL/JgJYPH+5boen7Z425xugvZ4z77d2XbSTZUj9Ksa3M/yYTucercM3nU5i4PXuTBijxYkQcr8mBFHqzIgxV5sCIPVuTBijxYkQcr8mBFHqzIgxV5sCIPVuTByekW8uBFHqzIgxV5sCKP/30TvOXx7RHt4umxuzfvORFMPDy8enpiRtHP05c8Zn0Ix5eny65Z936npOTR+02HEy1a58aOvkZ+w8T63trr1l5292zZ30hK+97lHeUxs50Uj1qt63TP46r8nX3mT/cw+hs/Vg9rP9FzXbHw2Lf1Hqm3zltMTzDxrnmXx+j+PPvz/v/c03vVg5hs51xpzrPrBzGZPUbdouuQiTyIkQcr8mBFHqzIgxV5sCIPVuTBijxYkQcr8mCF7FGavfW1rKF7lJ4xuG+XR5yJPOJT8jjRIpNH6/mt6Pp+zaPmcJpFJo+7SXQt8vg2ia5DHr8RebAiD1bkwYo8WJn1iDCsPeM9+9w3MaXvd1i+Y/B0z9nm3DpGWsdOb/Ykj+gZ76q3ty2LRyaTXR7U61XUZ67UarletTxKvd/3Ez2bkTWd5GedXTaPUbfoOuTBsNhxf5Xdg3idWjmWaus56dqcZb3Y4aHERx6sjN4/Kv75A/snIls= - - - diff --git a/examples/assets/maps/mapCSV_Group1_Map1.csv b/examples/assets/maps/mapCSV_Group1_Map1.csv deleted file mode 100644 index aa9841f5..00000000 --- a/examples/assets/maps/mapCSV_Group1_Map1.csv +++ /dev/null @@ -1,80 +0,0 @@ -31,31,31,31,31,31,31,31,31,31,31,31,31,32,31,31,31,31,31,31,31,32,32,33,32,33,34,32,34,33,31,32,31,31,31,31,31,31,31,32,32,33,32,33,34,32,34,33,31,32,31,31,31,31,31,31,31,32,32,33,32,33,31,31,31,31,31,31,31,32,32,33,32,33,34,32,34,33,31,32 -32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34 -33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,31 -32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,32,32,0,0,0,32 -31,32,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,32,32,0,0,0,0,0,32,0,0,0,0,31 -32,0,0,0,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,32,0,0,0,0,34 -34,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,32,32,32,0,0,0,31 -31,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,32,32,32,32,0,0,0,0,32,32,32,32,0,0,33 -32,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,32,32,0,0,0,32,32,32,32,32,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,32,0,0,31 -31,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,32,32,32,32,0,0,0,0,32,32,32,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,34 -34,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,32,0,0,0,0,32,32,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32 -31,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,32,0,0,32,32,32,0,0,0,0,0,32,32,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,32,0,0,0,0,32,32,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33 -33,0,0,0,0,0,32,32,0,0,0,0,32,32,0,0,0,0,0,32,0,0,0,32,32,32,0,0,0,0,0,32,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,32,32,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,32 -31,0,0,0,0,0,32,0,0,0,0,0,32,32,0,0,0,0,0,32,32,0,0,32,32,32,0,0,0,0,32,32,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,32,32,0,0,0,0,0,0,32,32,0,32,32,32,32,0,0,0,0,31 -34,32,0,0,32,32,32,0,0,0,0,0,32,32,0,0,0,0,0,0,32,32,32,32,32,0,0,0,0,0,32,32,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,32,32,0,0,0,0,0,0,32,32,0,0,0,0,0,32,32,0,0,0,32 -32,32,32,32,32,32,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,32,32,0,0,0,0,0,32,32,0,0,0,0,0,0,32,32,0,0,0,34 -33,32,32,32,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,32,0,0,0,0,0,0,32,0,0,32,32,0,0,0,0,32,0,0,0,31 -32,32,32,32,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,32,0,0,0,0,0,32,32,0,0,0,32,32,0,0,0,32,32,0,0,32 -31,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,32,32,32,32,0,0,0,0,0,0,32,0,0,0,0,0,32,0,0,0,0,32,32,0,0,0,32,32,0,0,31 -32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,32,32,32,32,0,0,0,0,0,0,32,0,0,0,0,0,32,32,32,32,32,32,0,0,0,32,32,32,0,0,34 -34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,32,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,32,32,32,0,0,0,0,32,32,0,0,0,31 -31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,32,32,32,32,0,0,0,0,32,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,32 -32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,33 -31,0,0,0,32,32,32,32,32,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,32 -34,0,0,0,0,0,32,32,32,0,0,0,0,0,0,32,32,32,32,32,32,32,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,31 -31,0,0,0,0,0,0,32,32,32,0,0,0,0,32,0,0,0,0,0,32,32,32,0,0,0,0,0,0,32,32,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,0,0,0,0,0,0,32 -33,0,0,0,0,0,0,0,32,32,0,0,0,0,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,34 -31,0,0,0,0,0,0,0,32,0,0,0,0,32,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,0,0,0,0,32,32,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,31 -34,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,0,0,0,32,32,32,32,32,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,32 -32,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,32,32,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,31 -33,0,0,0,0,0,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,32,32,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,34 -32,0,0,0,0,0,32,32,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,32,32,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,32,32,32,32,32,32,0,0,0,0,32,32,0,0,0,0,0,31 -31,0,0,0,0,32,32,32,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,32,32,32,32,0,0,0,0,0,0,32,32,32,0,0,0,0,32,32,32,0,0,0,0,0,32,32,32,32,32,32,0,0,0,0,0,32,32,32,0,0,0,0,32 -32,0,0,0,32,32,32,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,32,32,32,0,0,0,0,0,32,0,0,0,0,0,0,0,32,0,0,32,0,0,0,0,0,0,32,32,32,32,32,0,0,31 -34,32,32,32,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,34 -31,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,31 -32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,32 -31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,32,0,32,32,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,33 -34,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,32 -31,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,32,0,0,0,31 -33,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,32,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,32,32,0,0,0,32 -31,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,34 -34,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31 -32,0,32,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32 -33,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31 -32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,34 -31,32,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,32,0,0,31 -32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,0,0,0,0,0,32,32,0,32,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,32,32,0,32 -34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,32,32,32,32,0,0,32,32,32,0,0,0,0,0,0,0,0,0,32,32,0,34 -31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,0,32,32,32,32,31 -32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,32,32,32,32,32,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,32,32,32,32,32,0,0,0,0,0,0,0,0,32,32,32,32,0,0,32 -31,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,0,0,0,0,0,32,32,32,32,32,32,32,32,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,31 -34,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,32,32,32,32,32,0,32,32,32,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,34 -31,0,0,0,0,32,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,31 -33,32,32,32,32,32,32,0,0,0,32,32,32,32,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,33 -31,0,0,0,0,32,32,32,32,32,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31 -34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,34 -32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,32,0,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32 -33,0,32,32,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,0,32,32,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,0,33 -32,0,32,32,32,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,32,32,32,32,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,32,32,32,32,32,0,0,0,0,0,0,0,32,32,32,32,32,32,32,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,0,0,0,0,32 -31,32,32,32,32,32,32,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,32,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,32,32,0,0,0,32,32,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,31 -32,0,32,32,32,32,32,0,0,0,0,0,0,0,0,32,32,0,0,0,32,32,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,32 -34,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,32,0,0,0,32,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,34 -31,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,32,0,0,32,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31 -32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32 -31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31 -34,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,34 -31,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,31 -32,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,32 -33,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33 -32,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,0,32,32,32,32,32,32,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32 -31,0,0,0,0,32,32,32,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,32,32,0,0,32,0,0,0,0,0,0,32,32,32,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,31 -32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,32,0,0,32,32,0,0,0,32,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,32,0,0,0,0,0,32,32,32,32 -34,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,32,32,32,0,32,0,0,32,32,32,32,32,32,32,32,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,32,34 -31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,32,0,32,32,32,32,32,0,0,0,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,0,0,0,0,0,0,32,32,0,0,0,0,0,0,0,0,31 -32,0,0,0,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,0,0,32,32,32,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,32 -31,0,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,31 -34,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,0,0,0,32,32,32,32,0,0,0,0,32,32,0,0,0,0,0,0,0,0,0,32,32,32,32,0,0,0,0,0,0,0,34 -31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,0,0,0,32,32,32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32,32,32,32,32,32,32,0,0,0,0,0,0,31 -33,31,31,31,31,31,31,32,32,33,32,33,34,32,34,33,31,31,31,31,31,31,31,31,32,32,33,32,33,34,32,34,33,31,32,31,31,31,31,31,31,31,32,32,33,32,33,34,32,34,33,31,31,31,31,31,31,31,31,32,32,33,32,33,34,32,31,31,31,31,31,31,31,32,32,33,32,33,34,32 diff --git a/examples/assets/maps/mapCSV_SciFi_Map1.csv b/examples/assets/maps/mapCSV_SciFi_Map1.csv deleted file mode 100644 index 308bc124..00000000 --- a/examples/assets/maps/mapCSV_SciFi_Map1.csv +++ /dev/null @@ -1,16 +0,0 @@ -55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55 -55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55 -55,40,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,44,41,55 -55,50,38,35,1,1,1,1,1,1,29,34,29,1,1,28,1,1,47,55 -55,50,30,28,34,29,1,2,3,4,5,6,34,34,1,34,28,34,47,55 -55,50,1,30,34,29,28,7,8,9,10,11,1,33,30,1,39,29,47,55 -55,50,28,1,29,1,36,12,13,14,15,16,29,35,34,29,34,1,47,55 -55,50,30,34,29,30,32,17,18,19,20,21,30,35,31,32,1,30,47,55 -55,50,29,31,36,35,36,22,23,24,25,26,35,28,1,34,34,29,47,55 -55,42,45,45,45,45,49,35,35,35,35,34,27,34,35,34,35,1,47,55 -55,55,55,55,55,55,50,36,1,34,28,36,28,29,34,34,34,29,47,55 -55,40,53,53,53,53,54,28,32,1,1,28,34,35,29,38,34,1,47,55 -55,50,1,29,30,1,29,33,32,29,1,34,28,1,29,1,32,1,47,55 -55,42,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,45,43,55 -55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55 -55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55,55 diff --git a/examples/assets/maps/mapdraw.json b/examples/assets/maps/mapdraw.json deleted file mode 100644 index a363e3aa..00000000 --- a/examples/assets/maps/mapdraw.json +++ /dev/null @@ -1,39 +0,0 @@ -{ "height":40, - "layers":[ - { - "data":[21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 21, 21, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 21, 21, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 21, 21, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 21, 21, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 60, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 59, 60, 79, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 79, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78], - "height":40, - "name":"Tile Layer 1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":50, - "x":0, - "y":0 - }], - "orientation":"orthogonal", - "properties": - { - - }, - "tileheight":16, - "tilesets":[ - { - "firstgid":1, - "image":"..\/..\/..\/..\/kiwi-lite\/Test Suite\/assets\/tiles\/platformer_tiles.png", - "imageheight":96, - "imagewidth":304, - "margin":0, - "name":"platformer_tiles", - "properties": - { - - }, - "spacing":0, - "tileheight":16, - "tilewidth":16 - }], - "tilewidth":16, - "version":1, - "width":50 -} \ No newline at end of file diff --git a/examples/assets/maps/mario1.json b/examples/assets/maps/mario1.json deleted file mode 100644 index ffff33bb..00000000 --- a/examples/assets/maps/mario1.json +++ /dev/null @@ -1,39 +0,0 @@ -{ "height":13, - "layers":[ - { - "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 3, 4, 1, 1, 1, 1, 6, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 3, 4, 1, 1, 1, 1, 6, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 3, 4, 1, 1, 1, 1, 6, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 3, 4, 1, 1, 1, 1, 6, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 7, 7, 8, 1, 11, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 1, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 17, 18, 16, 16, 16, 16, 16, 1, 1, 1, 16, 16, 16, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 1, 1, 1, 1, 16, 15, 15, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 22, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 23, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 19, 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 1, 1, 27, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 1, 1, 1, 1, 1, 1, 30, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 19, 19, 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 1, 31, 31, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 1, 1, 1, 16, 15, 16, 15, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 15, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, 16, 28, 1, 1, 1, 1, 15, 1, 1, 15, 1, 1, 15, 1, 1, 1, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 1, 1, 1, 1, 1, 1, 19, 1, 1, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 19, 1, 1, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 15, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 19, 19, 19, 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, 20, 1, 1, 1, 1, 34, 35, 36, 1, 1, 1, 1, 1, 1, 1, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 33, 1, 1, 1, 1, 1, 1, 38, 39, 1, 1, 37, 1, 1, 1, 1, 1, 1, 40, 41, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 19, 1, 1, 19, 19, 1, 1, 1, 1, 37, 1, 1, 1, 19, 19, 19, 1, 1, 19, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 19, 19, 19, 19, 19, 19, 1, 1, 1, 1, 37, 1, 1, 1, 20, 1, 1, 1, 31, 42, 42, 42, 31, 1, 1, 1, 1, 1, 43, 44, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 33, 1, 1, 1, 1, 1, 1, 1, 1, 38, 39, 1, 1, 1, 1, 1, 1, 38, 39, 1, 43, 44, 45, 1, 1, 1, 1, 1, 46, 47, 1, 1, 1, 1, 1, 1, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 43, 44, 45, 1, 1, 1, 1, 1, 48, 49, 1, 1, 1, 1, 1, 1, 37, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 19, 19, 1, 1, 19, 19, 19, 1, 1, 43, 44, 45, 1, 19, 19, 19, 19, 1, 1, 19, 19, 19, 1, 1, 1, 37, 1, 32, 33, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 32, 33, 1, 19, 19, 19, 19, 19, 19, 19, 19, 1, 1, 1, 43, 44, 45, 1, 1, 20, 1, 1, 1, 35, 35, 50, 35, 35, 1, 1, 37, 1, 43, 44, 51, 52, 45, 1, 1, 1, 1, 1, 1, 53, 54, 54, 54, 55, 43, 44, 45, 1, 56, 57, 1, 53, 54, 55, 1, 1, 38, 39, 1, 1, 1, 1, 1, 1, 1, 1, 38, 39, 58, 59, 54, 54, 55, 1, 38, 39, 43, 44, 60, 61, 62, 57, 63, 64, 1, 38, 39, 53, 54, 54, 54, 55, 43, 44, 45, 1, 1, 1, 1, 53, 54, 55, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 53, 54, 54, 55, 1, 65, 66, 67, 68, 60, 61, 45, 1, 1, 1, 1, 69, 70, 53, 54, 54, 54, 55, 43, 44, 45, 1, 1, 1, 1, 53, 54, 55, 1, 71, 72, 66, 65, 66, 58, 73, 1, 1, 1, 1, 19, 19, 19, 19, 54, 54, 19, 19, 19, 19, 43, 44, 60, 61, 19, 19, 19, 19, 19, 1, 1, 19, 19, 19, 19, 55, 43, 44, 45, 74, 75, 1, 1, 53, 54, 55, 1, 1, 1, 76, 77, 78, 1, 1, 1, 38, 39, 19, 19, 19, 19, 19, 19, 19, 19, 19, 1, 1, 43, 44, 60, 61, 45, 1, 19, 1, 1, 1, 35, 35, 79, 35, 35, 55, 43, 44, 45, 80, 80, 81, 82, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 83, 84, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 85, 86, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 83, 84, 87, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 1, 1, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 1, 1, 1, 80, 80, 80, 80, 80, 80, 88, 89, 90, 80, 80, 80, 80, 80, 80, 80, 91, 92, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 93, 94, 88, 80, 88, 85, 86, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 1, 1, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 95, 96, 97, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80, 80], - "height":13, - "name":"ShoeBox Tile Grab", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":211, - "x":0, - "y":0 - }], - "orientation":"orthogonal", - "properties": - { - - }, - "tileheight":16, - "tilesets":[ - { - "firstgid":1, - "image":"..\/..\/..\/..\/..\/..\/Art\/Artwork for game inspirations\/Super Mario Level Maps\/NES\/mario-1-1_bank.png", - "imageheight":144, - "imagewidth":176, - "margin":0, - "name":"mario-1-1_bank.png", - "properties": - { - - }, - "spacing":0, - "tileheight":16, - "tilewidth":16 - }], - "tilewidth":16, - "version":1, - "width":211 -} \ No newline at end of file diff --git a/examples/assets/maps/mario1.png b/examples/assets/maps/mario1.png deleted file mode 100644 index 9cc96c17..00000000 Binary files a/examples/assets/maps/mario1.png and /dev/null differ diff --git a/examples/assets/maps/multi-layer-test.json b/examples/assets/maps/multi-layer-test.json deleted file mode 100644 index 6ce1897e..00000000 --- a/examples/assets/maps/multi-layer-test.json +++ /dev/null @@ -1,50 +0,0 @@ -{ "height":100, - "layers":[ - { - "data":[21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 78, 78, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 21, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 21, 78, 78, 21, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 78, 21, 78, 21, 78, 21, 21, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 78, 21, 21, 21, 78, 78, 21, 21, 21, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 21, 21, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 21, 78, 21, 78, 78, 21, 21, 21, 21, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 78, 78, 21, 21, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 21, 21, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 78, 78, 78, 21, 78, 78, 21, 21, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 21, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 21, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 45, 78, 78, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 45, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 21, 21, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 45, 45, 45, 45, 78, 45, 45, 45, 45, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 21, 21, 78, 21, 21, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 21, 21, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 45, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 45, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 45, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 45, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 21, 21, 21, 21, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 21, 21, 21, 21, 78, 78, 78, 21, 21, 78, 21, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 21, 78, 21, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 21, 78, 21, 21, 21, 21, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 21, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 21, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 21, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 21, 21, 21, 21, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 21, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 21, 21, 21, 21, 78, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21], - "height":100, - "name":"Tile Layer 1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":100, - "x":0, - "y":0 - }, - { - "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 0, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 16, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 15, 15, 15, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 15, 15, 15, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 15, 15, 15, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 16, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 16, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 16, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 15, 15, 15, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], - "height":100, - "name":"Tile Layer 2", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":100, - "x":0, - "y":0 - }], - "orientation":"orthogonal", - "properties": - { - - }, - "tileheight":16, - "tilesets":[ - { - "firstgid":1, - "image":"..\/..\/..\/..\/kiwi-lite\/Test Suite\/assets\/tiles\/platformer_tiles.png", - "imageheight":96, - "imagewidth":304, - "margin":0, - "name":"platformer_tiles", - "properties": - { - - }, - "spacing":0, - "tileheight":16, - "tilewidth":16 - }], - "tilewidth":16, - "version":1, - "width":100 -} \ No newline at end of file diff --git a/examples/assets/maps/platform-test-1.json b/examples/assets/maps/platform-test-1.json deleted file mode 100644 index eeb0528a..00000000 --- a/examples/assets/maps/platform-test-1.json +++ /dev/null @@ -1,39 +0,0 @@ -{ "height":40, - "layers":[ - { - "data":[21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 105, 106, 106, 107, 108, 18, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 17, 105, 106, 106, 107, 108, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 105, 106, 106, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 1, 1, 0, 0, 0, 0, 0, 0, 17, 105, 106, 106, 107, 108, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 17, 105, 106, 106, 107, 108, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 108, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 105, 106, 106, 107, 108, 18, 0, 0, 0, 0, 0, 17, 105, 106, 106, 107, 108, 18, 0, 0, 0, 0, 0, 0, 17, 105, 106, 106, 107, 108, 18, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 17, 105, 106, 106, 107, 108, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 105, 106, 106, 107, 108, 18, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 105, 106, 106, 107, 108, 18, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 17, 105, 106, 106, 107, 108, 18, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 45, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 21, 16, 1, 1, 1, 1, 16, 1, 1, 1, 45, 48, 45, 45, 1, 1, 1, 1, 1, 1, 1, 14, 16, 1, 1, 1, 16, 1, 1, 1, 1, 16, 1, 1, 1, 45, 48, 45, 45, 1, 1, 1, 1, 1, 1, 1, 14, 16, 1, 21, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 3, 1, 1, 1, 2, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 3, 1, 1, 1, 2, 41, 41, 41, 41, 41, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 59, 59, 59, 59, 59, 60, 60, 60, 60, 60, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 78, 78, 78, 78, 78, 79, 79, 79, 79, 79, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78], - "height":40, - "name":"Tile Layer 1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":50, - "x":0, - "y":0 - }], - "orientation":"orthogonal", - "properties": - { - - }, - "tileheight":16, - "tilesets":[ - { - "firstgid":1, - "image":"..\/..\/..\/..\/kiwi-lite\/Test Suite\/assets\/tiles\/platformer_tiles.png", - "imageheight":96, - "imagewidth":304, - "margin":0, - "name":"platformer_tiles", - "properties": - { - - }, - "spacing":0, - "tileheight":16, - "tilewidth":16 - }], - "tilewidth":16, - "version":1, - "width":50 -} \ No newline at end of file diff --git a/examples/assets/maps/platformer_map.csv b/examples/assets/maps/platformer_map.csv deleted file mode 100644 index 912f6e4e..00000000 --- a/examples/assets/maps/platformer_map.csv +++ /dev/null @@ -1,18 +0,0 @@ -31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31,31 -32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32 -33,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33 -32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,32 -31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31,34 -32,105,106,107,17,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33 -34,0,0,0,0,0,0,31,0,0,0,0,0,0,0,0,0,0,0,32 -31,0,0,0,0,0,0,0,0,0,0,16,104,105,107,17,0,0,31,31 -32,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,31 -31,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,33 -34,0,0,16,104,105,106,107,17,0,0,0,0,0,0,0,0,0,31,31 -31,0,0,0,0,0,0,0,0,0,0,0,63,65,0,0,0,0,0,31 -33,13,0,0,0,0,0,0,0,0,0,0,49,50,0,0,0,0,15,33 -31,33,13,0,0,0,0,0,0,0,0,47,51,52,46,0,0,13,34,31 -34,31,33,15,0,14,0,15,0,14,0,0,69,71,0,0,14,34,31,32 -42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42,42 -59,59,59,59,60,59,59,59,59,59,59,59,59,59,59,59,59,60,59,59 -78,78,78,78,79,78,78,78,78,78,78,78,78,78,78,78,78,79,78,78 diff --git a/examples/assets/maps/shmup_level_1_map.csv b/examples/assets/maps/shmup_level_1_map.csv deleted file mode 100644 index 8266146d..00000000 --- a/examples/assets/maps/shmup_level_1_map.csv +++ /dev/null @@ -1,90 +0,0 @@ -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,12,15,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,12,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,6,7,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,6,8,8,7,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,6,21,8,8,8,7,0,0,0,0,0,6,7,0 -0,0,0,0,0,6,9,8,11,11,20,9,7,0,0,0,0,12,15,0 -0,0,0,0,0,20,8,9,11,11,9,10,8,0,0,0,0,0,0,0 -0,0,0,0,0,13,8,21,11,11,21,20,14,0,0,0,0,0,0,0 -0,0,0,0,0,0,12,13,13,14,14,15,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,4,5,0,0,0 -0,0,0,0,0,6,7,0,0,0,0,0,0,0,6,11,8,7,0,0 -0,0,0,0,0,12,15,0,0,0,0,0,0,0,8,9,10,8,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,12,13,14,15,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,1,1,0,0,0,0,0,0,0,0,0,6,7,0,0,0,0 -0,0,1,2,2,1,0,0,0,0,0,0,0,0,12,15,0,0,0,0 -0,0,2,8,20,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,2,12,15,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,3,0,0,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,4,5,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,6,11,8,7,0,0,0,0,0,0 -0,0,0,0,0,0,6,7,0,0,8,9,10,8,0,0,0,0,0,0 -0,0,0,0,0,0,12,15,0,0,12,13,14,15,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,4,5,0,0,0,0,0,0,0,0,0,0,1,0,0,0,0,0 -0,6,11,8,7,0,0,0,0,0,0,0,1,1,2,1,0,0,0,0 -0,8,9,10,8,0,0,0,0,0,0,0,2,8,20,2,0,0,0,0 -0,12,13,14,15,0,0,0,0,0,0,0,2,12,15,2,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,3,0,0,3,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,4,5,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,1,6,11,8,7,1,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,2,8,9,10,8,2,0,0,1,0,1,0 -0,0,0,0,0,0,0,0,3,12,13,14,15,3,0,0,2,8,2,0 -0,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,2,13,2,0 -0,12,15,0,0,0,0,0,0,0,0,0,0,0,0,0,3,0,3,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,6,7,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,2,8,8,2,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,6,21,8,8,8,7,0,0,0,0,0,0,0,0,0 -0,0,0,1,2,9,8,11,11,20,9,2,1,0,0,0,0,0,0,0 -0,0,0,2,20,8,9,11,11,9,10,20,2,0,0,0,0,0,0,0 -0,0,0,3,13,8,21,11,11,21,20,14,3,0,0,0,0,0,0,0 -0,0,0,0,0,12,13,13,14,14,15,0,0,4,5,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,6,11,8,7,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,8,9,10,8,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,12,13,14,15,0,0,0,0 -0,0,0,0,6,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,12,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,7,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,8,8,7,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,21,8,8,8,7 -0,0,0,1,0,0,1,0,0,0,0,0,0,6,9,8,11,11,20,9 -0,0,0,2,9,20,2,0,0,0,0,0,0,20,8,9,11,11,9,10 -0,0,0,2,12,15,2,0,0,0,0,0,0,13,8,21,11,11,21,20 -0,0,0,3,0,0,3,0,0,0,0,0,0,0,12,13,13,14,14,15 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,6,7,0,0 -0,0,0,0,0,0,4,5,0,0,0,0,0,0,0,0,12,15,0,0 -0,0,0,0,0,6,11,8,7,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,4,8,9,10,8,5,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,12,13,13,14,14,15,0,0,0,4,5,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,1,6,11,8,7,1,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,2,8,9,10,8,2,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,3,12,13,14,15,3,0,0,0 -0,0,0,4,5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,6,11,8,7,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,8,9,10,8,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,12,13,14,15,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,6,7,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,12,15,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 -0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 diff --git a/examples/assets/maps/smb_bg.json b/examples/assets/maps/smb_bg.json deleted file mode 100644 index 6a7ef43c..00000000 --- a/examples/assets/maps/smb_bg.json +++ /dev/null @@ -1,39 +0,0 @@ -{ "height":27, - "layers":[ - { - "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 10, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 10, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 10, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 10, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 10, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 10, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 10, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 10, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 10, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 10, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 13, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 13, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 13, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 13, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 13, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 13, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 13, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 13, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 13, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 13, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 15, 10, 14, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 15, 10, 14, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 15, 10, 14, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 15, 10, 14, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 15, 10, 14, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 15, 10, 14, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 15, 10, 14, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 15, 10, 14, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 15, 10, 14, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 15, 10, 14, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 18, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 1, 1, 1, 1, 12, 10, 10, 14, 19, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 17, 21, 1, 1, 1, 1, 1, 5, 6, 22, 23, 13, 14, 3, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 1, 1, 5, 6, 22, 23, 13, 14, 3, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 1, 1, 5, 6, 22, 23, 13, 14, 3, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 1, 1, 5, 6, 22, 23, 13, 14, 3, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 1, 1, 5, 6, 22, 23, 13, 14, 3, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 1, 1, 5, 6, 22, 23, 13, 14, 3, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 1, 1, 5, 6, 22, 23, 13, 14, 3, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 1, 1, 5, 6, 22, 23, 13, 14, 3, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 1, 1, 5, 6, 22, 23, 13, 14, 3, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 1, 1, 5, 6, 22, 23, 13, 14, 3, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 19, 20, 25, 2, 3, 4, 1, 1, 9, 10, 10, 26, 27, 28, 29, 30, 25, 3, 4, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 16, 17, 18, 31, 32, 25, 2, 3, 4, 1, 1, 9, 10, 10, 26, 27, 28, 29, 30, 25, 3, 4, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 16, 17, 18, 31, 32, 25, 2, 3, 4, 1, 1, 9, 10, 10, 26, 27, 28, 29, 30, 25, 3, 4, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 16, 17, 18, 31, 32, 25, 2, 3, 4, 1, 1, 9, 10, 10, 26, 27, 28, 29, 30, 25, 3, 4, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 16, 17, 18, 31, 32, 25, 2, 3, 4, 1, 1, 9, 10, 10, 26, 27, 28, 29, 30, 25, 3, 4, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 16, 17, 18, 31, 32, 25, 2, 3, 4, 1, 1, 9, 10, 10, 26, 27, 28, 29, 30, 25, 3, 4, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 16, 17, 18, 31, 32, 25, 2, 3, 4, 1, 1, 9, 10, 10, 26, 27, 28, 29, 30, 25, 3, 4, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 16, 17, 18, 31, 32, 25, 2, 3, 4, 1, 1, 9, 10, 10, 26, 27, 28, 29, 30, 25, 3, 4, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 16, 17, 18, 31, 32, 25, 2, 3, 4, 1, 1, 9, 10, 10, 26, 27, 28, 29, 30, 25, 3, 4, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 16, 17, 18, 31, 32, 25, 2, 3, 4, 1, 1, 9, 10, 10, 26, 27, 28, 29, 30, 25, 3, 4, 1, 1, 1, 1, 16, 17, 18, 1, 1, 1, 16, 17, 18, 31, 32, 25, 3, 4, 1, 1, 1, 12, 13, 10, 14, 33, 10, 10, 34, 25, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 19, 20, 21, 35, 32, 25, 3, 4, 1, 1, 1, 12, 13, 10, 14, 33, 10, 10, 34, 25, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 19, 20, 21, 35, 32, 25, 3, 4, 1, 1, 1, 12, 13, 10, 14, 33, 10, 10, 34, 25, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 19, 20, 21, 35, 32, 25, 3, 4, 1, 1, 1, 12, 13, 10, 14, 33, 10, 10, 34, 25, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 19, 20, 21, 35, 32, 25, 3, 4, 1, 1, 1, 12, 13, 10, 14, 33, 10, 10, 34, 25, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 19, 20, 21, 35, 32, 25, 3, 4, 1, 1, 1, 12, 13, 10, 14, 33, 10, 10, 34, 25, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 19, 20, 21, 35, 32, 25, 3, 4, 1, 1, 1, 12, 13, 10, 14, 33, 10, 10, 34, 25, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 19, 20, 21, 35, 32, 25, 3, 4, 1, 1, 1, 12, 13, 10, 14, 33, 10, 10, 34, 25, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 19, 20, 21, 35, 32, 25, 3, 4, 1, 1, 1, 12, 13, 10, 14, 33, 10, 10, 34, 25, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 19, 20, 21, 35, 32, 25, 3, 4, 1, 1, 1, 12, 13, 10, 14, 33, 10, 10, 34, 25, 1, 1, 1, 1, 1, 1, 19, 20, 21, 1, 1, 1, 19, 20, 21, 35, 32, 36, 7, 8, 1, 1, 1, 12, 10, 15, 14, 12, 10, 15, 14, 25, 1, 1, 1, 1, 2, 3, 3, 24, 25, 1, 1, 1, 35, 32, 25, 31, 37, 36, 7, 8, 1, 1, 1, 12, 10, 15, 14, 12, 10, 15, 14, 25, 1, 1, 1, 1, 2, 3, 3, 24, 25, 1, 1, 1, 35, 32, 25, 31, 37, 36, 7, 8, 1, 1, 1, 12, 10, 15, 14, 12, 10, 15, 14, 25, 1, 1, 1, 1, 2, 3, 3, 24, 25, 1, 1, 1, 35, 32, 25, 31, 37, 36, 7, 8, 1, 1, 1, 12, 10, 15, 14, 12, 10, 15, 14, 25, 1, 1, 1, 1, 2, 3, 3, 24, 25, 1, 1, 1, 35, 32, 25, 31, 37, 36, 7, 8, 1, 1, 1, 12, 10, 15, 14, 12, 10, 15, 14, 25, 1, 1, 1, 1, 2, 3, 3, 24, 25, 1, 1, 1, 35, 32, 25, 31, 37, 36, 7, 8, 1, 1, 1, 12, 10, 15, 14, 12, 10, 15, 14, 25, 1, 1, 1, 1, 2, 3, 3, 24, 25, 1, 1, 1, 35, 32, 25, 31, 37, 36, 7, 8, 1, 1, 1, 12, 10, 15, 14, 12, 10, 15, 14, 25, 1, 1, 1, 1, 2, 3, 3, 24, 25, 1, 1, 1, 35, 32, 25, 31, 37, 36, 7, 8, 1, 1, 1, 12, 10, 15, 14, 12, 10, 15, 14, 25, 1, 1, 1, 1, 2, 3, 3, 24, 25, 1, 1, 1, 35, 32, 25, 31, 37, 36, 7, 8, 1, 1, 1, 12, 10, 15, 14, 12, 10, 15, 14, 25, 1, 1, 1, 1, 2, 3, 3, 24, 25, 1, 1, 1, 35, 32, 25, 31, 37, 36, 7, 8, 1, 1, 1, 12, 10, 15, 14, 12, 10, 15, 14, 25, 1, 1, 1, 1, 2, 3, 3, 24, 25, 1, 1, 1, 35, 32, 25, 31, 37, 13, 10, 11, 1, 5, 6, 12, 10, 10, 14, 12, 10, 10, 14, 25, 1, 16, 17, 18, 1, 1, 31, 20, 25, 2, 3, 3, 24, 32, 25, 31, 38, 13, 10, 11, 1, 5, 6, 12, 10, 10, 14, 12, 10, 10, 14, 25, 1, 16, 17, 18, 1, 1, 31, 20, 25, 2, 3, 3, 24, 32, 25, 31, 38, 13, 10, 11, 1, 5, 6, 12, 10, 10, 14, 12, 10, 10, 14, 25, 1, 16, 17, 18, 1, 1, 31, 20, 25, 2, 3, 3, 24, 32, 25, 31, 38, 13, 10, 11, 1, 5, 6, 12, 10, 10, 14, 12, 10, 10, 14, 25, 1, 16, 17, 18, 1, 1, 31, 20, 25, 2, 3, 3, 24, 32, 25, 31, 38, 13, 10, 11, 1, 5, 6, 12, 10, 10, 14, 12, 10, 10, 14, 25, 1, 16, 17, 18, 1, 1, 31, 20, 25, 2, 3, 3, 24, 32, 25, 31, 38, 13, 10, 11, 1, 5, 6, 12, 10, 10, 14, 12, 10, 10, 14, 25, 1, 16, 17, 18, 1, 1, 31, 20, 25, 2, 3, 3, 24, 32, 25, 31, 38, 13, 10, 11, 1, 5, 6, 12, 10, 10, 14, 12, 10, 10, 14, 25, 1, 16, 17, 18, 1, 1, 31, 20, 25, 2, 3, 3, 24, 32, 25, 31, 38, 13, 10, 11, 1, 5, 6, 12, 10, 10, 14, 12, 10, 10, 14, 25, 1, 16, 17, 18, 1, 1, 31, 20, 25, 2, 3, 3, 24, 32, 25, 31, 38, 13, 10, 11, 1, 5, 6, 12, 10, 10, 14, 12, 10, 10, 14, 25, 1, 16, 17, 18, 1, 1, 31, 20, 25, 2, 3, 3, 24, 32, 25, 31, 38, 13, 10, 11, 1, 5, 6, 12, 10, 10, 14, 12, 10, 10, 14, 25, 1, 16, 17, 18, 1, 1, 31, 20, 25, 2, 3, 3, 24, 32, 25, 31, 38, 10, 10, 14, 1, 9, 10, 12, 13, 10, 14, 12, 13, 10, 14, 25, 1, 19, 20, 21, 1, 1, 35, 32, 25, 1, 1, 1, 35, 32, 39, 3, 12, 10, 10, 14, 1, 9, 10, 12, 13, 10, 14, 12, 13, 10, 14, 25, 1, 19, 20, 21, 1, 1, 35, 32, 25, 1, 1, 1, 35, 32, 39, 3, 12, 10, 10, 14, 1, 9, 10, 12, 13, 10, 14, 12, 13, 10, 14, 25, 1, 19, 20, 21, 1, 1, 35, 32, 25, 1, 1, 1, 35, 32, 39, 3, 12, 10, 10, 14, 1, 9, 10, 12, 13, 10, 14, 12, 13, 10, 14, 25, 1, 19, 20, 21, 1, 1, 35, 32, 25, 1, 1, 1, 35, 32, 39, 3, 12, 10, 10, 14, 1, 9, 10, 12, 13, 10, 14, 12, 13, 10, 14, 25, 1, 19, 20, 21, 1, 1, 35, 32, 25, 1, 1, 1, 35, 32, 39, 3, 12, 10, 10, 14, 1, 9, 10, 12, 13, 10, 14, 12, 13, 10, 14, 25, 1, 19, 20, 21, 1, 1, 35, 32, 25, 1, 1, 1, 35, 32, 39, 3, 12, 10, 10, 14, 1, 9, 10, 12, 13, 10, 14, 12, 13, 10, 14, 25, 1, 19, 20, 21, 1, 1, 35, 32, 25, 1, 1, 1, 35, 32, 39, 3, 12, 10, 10, 14, 1, 9, 10, 12, 13, 10, 14, 12, 13, 10, 14, 25, 1, 19, 20, 21, 1, 1, 35, 32, 25, 1, 1, 1, 35, 32, 39, 3, 12, 10, 10, 14, 1, 9, 10, 12, 13, 10, 14, 12, 13, 10, 14, 25, 1, 19, 20, 21, 1, 1, 35, 32, 25, 1, 1, 1, 35, 32, 39, 3, 12, 10, 10, 14, 1, 9, 10, 12, 13, 10, 14, 12, 13, 10, 14, 25, 1, 19, 20, 21, 1, 1, 35, 32, 25, 1, 1, 1, 35, 32, 39, 3, 12, 10, 10, 14, 3, 12, 10, 12, 10, 10, 14, 12, 10, 10, 14, 3, 3, 3, 24, 25, 5, 6, 29, 30, 25, 1, 2, 3, 37, 36, 29, 30, 12, 10, 10, 14, 3, 12, 10, 12, 10, 10, 14, 12, 10, 10, 14, 3, 3, 3, 24, 25, 5, 6, 29, 30, 25, 1, 2, 3, 37, 36, 29, 30, 12, 10, 10, 14, 3, 12, 10, 12, 10, 10, 14, 12, 10, 10, 14, 3, 3, 3, 24, 25, 5, 6, 29, 30, 25, 1, 2, 3, 37, 36, 29, 30, 12, 10, 10, 14, 3, 12, 10, 12, 10, 10, 14, 12, 10, 10, 14, 3, 3, 3, 24, 25, 5, 6, 29, 30, 25, 1, 2, 3, 37, 36, 29, 30, 12, 10, 10, 14, 3, 12, 10, 12, 10, 10, 14, 12, 10, 10, 14, 3, 3, 3, 24, 25, 5, 6, 29, 30, 25, 1, 2, 3, 37, 36, 29, 30, 12, 10, 10, 14, 3, 12, 10, 12, 10, 10, 14, 12, 10, 10, 14, 3, 3, 3, 24, 25, 5, 6, 29, 30, 25, 1, 2, 3, 37, 36, 29, 30, 12, 10, 10, 14, 3, 12, 10, 12, 10, 10, 14, 12, 10, 10, 14, 3, 3, 3, 24, 25, 5, 6, 29, 30, 25, 1, 2, 3, 37, 36, 29, 30, 12, 10, 10, 14, 3, 12, 10, 12, 10, 10, 14, 12, 10, 10, 14, 3, 3, 3, 24, 25, 5, 6, 29, 30, 25, 1, 2, 3, 37, 36, 29, 30, 12, 10, 10, 14, 3, 12, 10, 12, 10, 10, 14, 12, 10, 10, 14, 3, 3, 3, 24, 25, 5, 6, 29, 30, 25, 1, 2, 3, 37, 36, 29, 30, 12, 10, 10, 14, 3, 12, 10, 12, 10, 10, 14, 12, 10, 10, 14, 3, 3, 3, 24, 25, 5, 6, 29, 30, 25, 1, 2, 3, 37, 36, 29, 30, 12, 10, 15, 14, 1, 12, 15, 12, 10, 10, 14, 12, 10, 15, 14, 3, 4, 35, 32, 25, 9, 10, 10, 34, 25, 3, 3, 4, 38, 10, 10, 34, 12, 10, 15, 14, 1, 12, 15, 12, 10, 10, 14, 12, 10, 15, 14, 3, 4, 35, 32, 25, 9, 10, 10, 34, 25, 3, 3, 4, 38, 10, 10, 34, 12, 10, 15, 14, 1, 12, 15, 12, 10, 10, 14, 12, 10, 15, 14, 3, 4, 35, 32, 25, 9, 10, 10, 34, 25, 3, 3, 4, 38, 10, 10, 34, 12, 10, 15, 14, 1, 12, 15, 12, 10, 10, 14, 12, 10, 15, 14, 3, 4, 35, 32, 25, 9, 10, 10, 34, 25, 3, 3, 4, 38, 10, 10, 34, 12, 10, 15, 14, 1, 12, 15, 12, 10, 10, 14, 12, 10, 15, 14, 3, 4, 35, 32, 25, 9, 10, 10, 34, 25, 3, 3, 4, 38, 10, 10, 34, 12, 10, 15, 14, 1, 12, 15, 12, 10, 10, 14, 12, 10, 15, 14, 3, 4, 35, 32, 25, 9, 10, 10, 34, 25, 3, 3, 4, 38, 10, 10, 34, 12, 10, 15, 14, 1, 12, 15, 12, 10, 10, 14, 12, 10, 15, 14, 3, 4, 35, 32, 25, 9, 10, 10, 34, 25, 3, 3, 4, 38, 10, 10, 34, 12, 10, 15, 14, 1, 12, 15, 12, 10, 10, 14, 12, 10, 15, 14, 3, 4, 35, 32, 25, 9, 10, 10, 34, 25, 3, 3, 4, 38, 10, 10, 34, 12, 10, 15, 14, 1, 12, 15, 12, 10, 10, 14, 12, 10, 15, 14, 3, 4, 35, 32, 25, 9, 10, 10, 34, 25, 3, 3, 4, 38, 10, 10, 34, 12, 10, 15, 14, 1, 12, 15, 12, 10, 10, 14, 12, 10, 15, 14, 3, 4, 35, 32, 25, 9, 10, 10, 34, 25, 3, 3, 4, 38, 10, 10, 34, 12, 10, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 10, 14, 25, 1, 31, 20, 25, 12, 13, 10, 14, 25, 1, 43, 41, 12, 10, 13, 14, 12, 10, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 10, 14, 25, 1, 31, 20, 25, 12, 13, 10, 14, 25, 1, 43, 41, 12, 10, 13, 14, 12, 10, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 10, 14, 25, 1, 31, 20, 25, 12, 13, 10, 14, 25, 1, 43, 41, 12, 10, 13, 14, 12, 10, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 10, 14, 25, 1, 31, 20, 25, 12, 13, 10, 14, 25, 1, 43, 41, 12, 10, 13, 14, 12, 10, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 10, 14, 25, 1, 31, 20, 25, 12, 13, 10, 14, 25, 1, 43, 41, 12, 10, 13, 14, 12, 10, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 10, 14, 25, 1, 31, 20, 25, 12, 13, 10, 14, 25, 1, 43, 41, 12, 10, 13, 14, 12, 10, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 10, 14, 25, 1, 31, 20, 25, 12, 13, 10, 14, 25, 1, 43, 41, 12, 10, 13, 14, 12, 10, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 10, 14, 25, 1, 31, 20, 25, 12, 13, 10, 14, 25, 1, 43, 41, 12, 10, 13, 14, 12, 10, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 10, 14, 25, 1, 31, 20, 25, 12, 13, 10, 14, 25, 1, 43, 41, 12, 10, 13, 14, 12, 10, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 10, 14, 25, 1, 31, 20, 25, 12, 13, 10, 14, 25, 1, 43, 41, 12, 10, 13, 14, 12, 23, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 25, 3, 35, 39, 3, 12, 10, 10, 14, 3, 4, 47, 45, 12, 10, 27, 28, 22, 23, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 25, 3, 35, 39, 3, 12, 10, 10, 14, 3, 4, 47, 45, 12, 10, 27, 28, 22, 23, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 25, 3, 35, 39, 3, 12, 10, 10, 14, 3, 4, 47, 45, 12, 10, 27, 28, 22, 23, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 25, 3, 35, 39, 3, 12, 10, 10, 14, 3, 4, 47, 45, 12, 10, 27, 28, 22, 23, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 25, 3, 35, 39, 3, 12, 10, 10, 14, 3, 4, 47, 45, 12, 10, 27, 28, 22, 23, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 25, 3, 35, 39, 3, 12, 10, 10, 14, 3, 4, 47, 45, 12, 10, 27, 28, 22, 23, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 25, 3, 35, 39, 3, 12, 10, 10, 14, 3, 4, 47, 45, 12, 10, 27, 28, 22, 23, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 25, 3, 35, 39, 3, 12, 10, 10, 14, 3, 4, 47, 45, 12, 10, 27, 28, 22, 23, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 25, 3, 35, 39, 3, 12, 10, 10, 14, 3, 4, 47, 45, 12, 10, 27, 28, 22, 23, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 25, 3, 35, 39, 3, 12, 10, 10, 14, 3, 4, 47, 45, 12, 10, 27, 28, 22, 41, 42, 14, 3, 12, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 15, 14, 41, 41, 41, 41, 12, 40, 41, 41, 41, 41, 42, 14, 3, 12, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 15, 14, 41, 41, 41, 41, 12, 40, 41, 41, 41, 41, 42, 14, 3, 12, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 15, 14, 41, 41, 41, 41, 12, 40, 41, 41, 41, 41, 42, 14, 3, 12, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 15, 14, 41, 41, 41, 41, 12, 40, 41, 41, 41, 41, 42, 14, 3, 12, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 15, 14, 41, 41, 41, 41, 12, 40, 41, 41, 41, 41, 42, 14, 3, 12, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 15, 14, 41, 41, 41, 41, 12, 40, 41, 41, 41, 41, 42, 14, 3, 12, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 15, 14, 41, 41, 41, 41, 12, 40, 41, 41, 41, 41, 42, 14, 3, 12, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 15, 14, 41, 41, 41, 41, 12, 40, 41, 41, 41, 41, 42, 14, 3, 12, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 15, 14, 41, 41, 41, 41, 12, 40, 41, 41, 41, 41, 42, 14, 3, 12, 40, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 42, 15, 14, 41, 41, 41, 41, 12, 40, 41, 41, 41, 45, 46, 14, 41, 12, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 45, 45, 45, 45, 12, 44, 45, 45, 45, 45, 46, 14, 41, 12, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 45, 45, 45, 45, 12, 44, 45, 45, 45, 45, 46, 14, 41, 12, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 45, 45, 45, 45, 12, 44, 45, 45, 45, 45, 46, 14, 41, 12, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 45, 45, 45, 45, 12, 44, 45, 45, 45, 45, 46, 14, 41, 12, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 45, 45, 45, 45, 12, 44, 45, 45, 45, 45, 46, 14, 41, 12, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 45, 45, 45, 45, 12, 44, 45, 45, 45, 45, 46, 14, 41, 12, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 45, 45, 45, 45, 12, 44, 45, 45, 45, 45, 46, 14, 41, 12, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 45, 45, 45, 45, 12, 44, 45, 45, 45, 45, 46, 14, 41, 12, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 45, 45, 45, 45, 12, 44, 45, 45, 45, 45, 46, 14, 41, 12, 44, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 46, 10, 14, 45, 45, 45, 45, 12, 44, 45, 45, 45], - "height":27, - "name":"ShoeBox Tile Grab", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":320, - "x":0, - "y":0 - }], - "orientation":"orthogonal", - "properties": - { - - }, - "tileheight":16, - "tilesets":[ - { - "firstgid":1, - "image":"super_mario_world-1_yoshis_island-yoshis_island_1(105-background)_bank.png", - "imageheight":80, - "imagewidth":176, - "margin":0, - "name":"super_mario_world-1_yoshis_island-yoshis_island_1(105-background)_bank.png", - "properties": - { - - }, - "spacing":0, - "tileheight":16, - "tilewidth":16 - }], - "tilewidth":16, - "version":1, - "width":320 -} \ No newline at end of file diff --git a/examples/assets/maps/smb_bg.png b/examples/assets/maps/smb_bg.png deleted file mode 100644 index 080b7219..00000000 Binary files a/examples/assets/maps/smb_bg.png and /dev/null differ diff --git a/examples/assets/maps/smb_level1.json b/examples/assets/maps/smb_level1.json deleted file mode 100644 index 95353ba9..00000000 --- a/examples/assets/maps/smb_level1.json +++ /dev/null @@ -1,39 +0,0 @@ -{ "height":27, - "layers":[ - { - "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 7, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 10, 10, 10, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 15, 15, 15, 15, 16, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 18, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 18, 19, 1, 1, 18, 19, 1, 1, 18, 19, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 20, 21, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 10, 10, 22, 15, 15, 15, 15, 16, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 18, 23, 15, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 26, 27, 28, 1, 1, 1, 1, 1, 1, 1, 29, 30, 30, 31, 1, 1, 1, 1, 1, 1, 18, 23, 15, 24, 18, 23, 15, 24, 18, 23, 15, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 26, 27, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 15, 15, 15, 32, 15, 15, 15, 15, 15, 16, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 18, 23, 15, 15, 15, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 33, 34, 35, 36, 37, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 38, 1, 1, 18, 23, 15, 15, 39, 23, 15, 15, 39, 23, 15, 15, 15, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 40, 6, 6, 40, 1, 1, 1, 1, 25, 33, 34, 35, 36, 41, 1, 1, 1, 1, 1, 1, 42, 43, 1, 1, 1, 1, 1, 1, 1, 1, 1, 44, 1, 45, 1, 1, 1, 46, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 15, 15, 15, 32, 15, 15, 15, 15, 15, 15, 16, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 10, 10, 10, 10, 10, 10, 47, 1, 1, 1, 1, 1, 1, 48, 49, 1, 1, 1, 1, 1, 40, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 50, 15, 15, 15, 15, 15, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 33, 34, 51, 52, 1, 53, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 54, 1, 1, 50, 15, 15, 15, 55, 15, 15, 15, 55, 15, 15, 15, 15, 15, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 56, 57, 1, 1, 1, 1, 40, 1, 1, 40, 1, 1, 1, 25, 33, 34, 51, 52, 41, 58, 1, 1, 1, 1, 1, 1, 59, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 61, 62, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 15, 15, 64, 10, 10, 22, 15, 15, 15, 15, 15, 16, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 15, 15, 15, 15, 15, 15, 15, 32, 1, 1, 1, 1, 1, 1, 65, 66, 37, 10, 10, 10, 10, 38, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 67, 15, 15, 15, 15, 15, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 25, 33, 34, 51, 52, 1, 1, 53, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 54, 1, 1, 1, 67, 15, 15, 15, 68, 15, 15, 15, 68, 15, 15, 15, 15, 15, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 69, 70, 1, 1, 1, 1, 40, 56, 57, 40, 1, 1, 25, 33, 34, 51, 52, 1, 58, 58, 1, 1, 1, 1, 1, 1, 59, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 71, 1, 63, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 15, 15, 14, 15, 15, 32, 15, 15, 15, 15, 15, 15, 16, 10, 47, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 15, 15, 15, 15, 15, 15, 15, 32, 1, 1, 1, 1, 1, 1, 65, 66, 53, 15, 15, 15, 15, 54, 1, 1, 72, 73, 1, 1, 1, 1, 1, 12, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 30, 31, 1, 1, 1, 1, 1, 1, 67, 15, 15, 15, 15, 15, 24, 29, 30, 30, 31, 1, 1, 1, 1, 1, 1, 29, 30, 30, 31, 1, 1, 1, 1, 1, 1, 29, 30, 31, 1, 1, 1, 29, 30, 30, 31, 1, 25, 33, 34, 51, 52, 1, 1, 1, 53, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 54, 1, 1, 1, 1, 67, 15, 15, 15, 68, 15, 15, 15, 68, 15, 15, 15, 15, 15, 24, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 30, 31, 1, 1, 1, 1, 29, 30, 31, 1, 1, 69, 70, 1, 1, 1, 1, 40, 69, 70, 40, 1, 25, 33, 34, 51, 52, 1, 1, 74, 74, 1, 1, 1, 1, 1, 1, 59, 60, 1, 1, 1, 1, 1, 1, 1, 1, 1, 71, 1, 63, 1, 29, 30, 30, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 15, 15, 14, 15, 15, 32, 15, 15, 15, 15, 15, 15, 15, 15, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 30, 30, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 30, 30, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 30, 30, 31, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 29, 30, 30, 31, 1, 14, 15, 15, 15, 15, 15, 15, 15, 32, 1, 1, 1, 1, 1, 1, 65, 66, 53, 15, 15, 15, 15, 54, 1, 1, 75, 76, 1, 1, 1, 1, 1, 12, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 23, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 38, 1, 1, 1, 1, 1, 37, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 38, 46, 46, 37, 10, 10, 38, 1, 1, 1, 1, 37, 10, 10, 10, 38, 46, 46, 37, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 23, 15, 15, 15, 15, 16, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 16, 10, 10, 10, 10, 10, 23, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 54, 1, 1, 53, 15, 15, 16, 10, 10, 10, 10, 23, 15, 15, 15, 54, 1, 1, 53, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 54, 1, 1, 53, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 54, 1, 1, 53, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 15], - "height":27, - "name":"ShoeBox Tile Grab", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":320, - "x":0, - "y":0 - }], - "orientation":"orthogonal", - "properties": - { - - }, - "tileheight":16, - "tilesets":[ - { - "firstgid":1, - "image":"super_mario_world-1_yoshis_island-yoshis_island_1(105-map)_bank.png", - "imageheight":112, - "imagewidth":176, - "margin":0, - "name":"super_mario_world-1_yoshis_island-yoshis_island_1(105-map)_bank.png", - "properties": - { - - }, - "spacing":0, - "tileheight":16, - "tilewidth":16 - }], - "tilewidth":16, - "version":1, - "width":320 -} \ No newline at end of file diff --git a/examples/assets/maps/smb_tiles.png b/examples/assets/maps/smb_tiles.png deleted file mode 100644 index 1170296c..00000000 Binary files a/examples/assets/maps/smb_tiles.png and /dev/null differ diff --git a/examples/assets/maps/super_mario_world-1_yoshis_island-yoshis_island_1(105-background)_map.tmx b/examples/assets/maps/super_mario_world-1_yoshis_island-yoshis_island_1(105-background)_map.tmx deleted file mode 100644 index ffcf339d..00000000 --- a/examples/assets/maps/super_mario_world-1_yoshis_island-yoshis_island_1(105-background)_map.tmx +++ /dev/null @@ -1,8650 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/assets/maps/super_mario_world-1_yoshis_island-yoshis_island_1(105-map)_map.tmx b/examples/assets/maps/super_mario_world-1_yoshis_island-yoshis_island_1(105-map)_map.tmx deleted file mode 100644 index e5527527..00000000 --- a/examples/assets/maps/super_mario_world-1_yoshis_island-yoshis_island_1(105-map)_map.tmx +++ /dev/null @@ -1,8650 +0,0 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/examples/assets/maps/test.json b/examples/assets/maps/test.json deleted file mode 100644 index eefadf86..00000000 --- a/examples/assets/maps/test.json +++ /dev/null @@ -1,39 +0,0 @@ -{ "height":100, - "layers":[ - { - "data":[21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 78, 78, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 21, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 21, 78, 78, 21, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 78, 21, 78, 21, 78, 21, 21, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 78, 21, 21, 21, 78, 78, 21, 21, 21, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 21, 21, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 21, 78, 21, 78, 78, 21, 21, 21, 21, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 78, 78, 21, 21, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 21, 21, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 78, 78, 78, 21, 78, 78, 21, 21, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 21, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 21, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 45, 78, 78, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 45, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 21, 21, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 45, 45, 45, 45, 78, 45, 45, 45, 45, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 45, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 21, 21, 78, 21, 21, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 21, 21, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 78, 78, 45, 78, 78, 78, 78, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 45, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 45, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 78, 78, 45, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 45, 45, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 21, 21, 21, 21, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 21, 21, 21, 21, 78, 78, 78, 21, 21, 78, 21, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 21, 78, 21, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 21, 78, 21, 21, 21, 21, 78, 21, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 21, 21, 21, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 21, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 21, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 21, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 78, 78, 21, 21, 21, 21, 78, 78, 78, 21, 21, 78, 78, 78, 78, 21, 78, 21, 78, 78, 21, 78, 78, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 21, 21, 21, 21, 78, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21, 21], - "height":100, - "name":"Tile Layer 1", - "opacity":1, - "type":"tilelayer", - "visible":true, - "width":100, - "x":0, - "y":0 - }], - "orientation":"orthogonal", - "properties": - { - - }, - "tileheight":16, - "tilesets":[ - { - "firstgid":1, - "image":"..\/tiles\/platformer_tiles.png", - "imageheight":96, - "imagewidth":304, - "margin":0, - "name":"platformer_tiles", - "properties": - { - - }, - "spacing":0, - "tileheight":16, - "tilewidth":16 - }], - "tilewidth":16, - "version":1, - "width":100 -} \ No newline at end of file diff --git a/examples/assets/misc/controller-indicator.png b/examples/assets/misc/controller-indicator.png new file mode 100644 index 00000000..8f39d98a Binary files /dev/null and b/examples/assets/misc/controller-indicator.png differ diff --git a/examples/assets/pics/cougar_sanity_train.png b/examples/assets/pics/cougar_sanity_train.png new file mode 100644 index 00000000..6d08bb7b Binary files /dev/null and b/examples/assets/pics/cougar_sanity_train.png differ diff --git a/examples/assets/sprites/block.png b/examples/assets/sprites/block.png new file mode 100644 index 00000000..3d3ffd20 Binary files /dev/null and b/examples/assets/sprites/block.png differ diff --git a/examples/assets/sprites/bluemetal_32x32x4.png b/examples/assets/sprites/bluemetal_32x32x4.png new file mode 100644 index 00000000..b3ce2c2a Binary files /dev/null and b/examples/assets/sprites/bluemetal_32x32x4.png differ diff --git a/examples/assets/sprites/budbrain_chick.png b/examples/assets/sprites/budbrain_chick.png new file mode 100644 index 00000000..ed7eecff Binary files /dev/null and b/examples/assets/sprites/budbrain_chick.png differ diff --git a/examples/assets/sprites/exocet_spaceman.png b/examples/assets/sprites/exocet_spaceman.png new file mode 100644 index 00000000..a71662af Binary files /dev/null and b/examples/assets/sprites/exocet_spaceman.png differ diff --git a/examples/assets/sprites/gameboy_seize_color_40x60.png b/examples/assets/sprites/gameboy_seize_color_40x60.png new file mode 100644 index 00000000..40f40800 Binary files /dev/null and b/examples/assets/sprites/gameboy_seize_color_40x60.png differ diff --git a/examples/assets/sprites/interference_ball_48x48.png b/examples/assets/sprites/interference_ball_48x48.png new file mode 100644 index 00000000..a5466bac Binary files /dev/null and b/examples/assets/sprites/interference_ball_48x48.png differ diff --git a/examples/assets/sprites/interference_tunnel.png b/examples/assets/sprites/interference_tunnel.png new file mode 100644 index 00000000..6cfc0412 Binary files /dev/null and b/examples/assets/sprites/interference_tunnel.png differ diff --git a/examples/assets/sprites/longarrow2.png b/examples/assets/sprites/longarrow2.png new file mode 100644 index 00000000..82cf0a5a Binary files /dev/null and b/examples/assets/sprites/longarrow2.png differ diff --git a/examples/assets/sprites/physics blocks.pes b/examples/assets/sprites/physics blocks.pes new file mode 100644 index 00000000..f92ada05 Binary files /dev/null and b/examples/assets/sprites/physics blocks.pes differ diff --git a/examples/assets/sprites/physics export.txt b/examples/assets/sprites/physics export.txt new file mode 100644 index 00000000..f8fffe8a --- /dev/null +++ b/examples/assets/sprites/physics export.txt @@ -0,0 +1,125 @@ +Simple plain text exporter for demo purposes + +See http://www.grantlee.org/apidox/for_themers.html for more information + +Custom values (from the section) + Grav: 9.81 + +List of all bodies: + + + Name: exocet_spaceman + Custom values (from the section): + Identifier: 0 + FixedRotation: NO + + AnchorPointRel: { 0.000,1.000 } + AnchorPointAbs: { 0.000,175.000 } + Size: { 153.000,175.000 } + + List of all fixtures: + + ---------------------------------------------------------- + fixtureType: POLYGON + + Box2D special values (only available if box2d is active): + filter_groupIndex: + filter_categoryBits: + filter_maskBits: + + Custom values (from the section): + density: 2 + friction: 0 + restitution: 0 + isSensor: NO + + + Hull polygon: + (34, -172) , (75, -172) , (87, -145) , (121, -52) , (105, -16) , (55, -3) , (9, -19) , (1, -57) , (24, -145) + + Convex sub polygons: + + (75, -172) , (87, -145) , (121, -52) , (105, -16) , (55, -3) , (1, -57) , (24, -145) , (34, -172) + (1, -57) , (55, -3) , (9, -19) + + + + + Name: parsec + Custom values (from the section): + Identifier: 0 + FixedRotation: NO + + AnchorPointRel: { 0.000,1.000 } + AnchorPointAbs: { 0.000,80.000 } + Size: { 302.000,80.000 } + + List of all fixtures: + + ---------------------------------------------------------- + fixtureType: POLYGON + + Box2D special values (only available if box2d is active): + filter_groupIndex: + filter_categoryBits: + filter_maskBits: + + Custom values (from the section): + density: 2 + friction: 0 + restitution: 0 + isSensor: NO + + + Hull polygon: + (56, -1) , (10, -5) , (1, -13) , (0, -34) , (55, -60) , (122, -78) , (165, -80) , (214, -74) , (285, -71) , (296, -44) , (298, -12) , (292, -5) , (168, -3) + + Convex sub polygons: + + (296, -44) , (298, -12) , (292, -5) , (168, -3) , (214, -74) , (285, -71) + (0, -34) , (55, -60) , (122, -78) , (165, -80) , (168, -3) , (56, -1) , (10, -5) , (1, -13) + (214, -74) , (168, -3) , (165, -80) + + + + + Name: wasp + Custom values (from the section): + Identifier: 0 + FixedRotation: NO + + AnchorPointRel: { 0.000,1.000 } + AnchorPointAbs: { 0.000,91.000 } + Size: { 175.000,91.000 } + + List of all fixtures: + + ---------------------------------------------------------- + fixtureType: POLYGON + + Box2D special values (only available if box2d is active): + filter_groupIndex: + filter_categoryBits: + filter_maskBits: + + Custom values (from the section): + density: 2 + friction: 0 + restitution: 0 + isSensor: NO + + + Hull polygon: + (62, -89) , (89, -85) , (173, -42) , (171, -32) , (116, -31) , (106, -2) , (93, -1) , (91, -22) , (52, -17) , (39, 0) , (28, -5) , (31, -25) , (21, -37) , (5, -41) , (0, -62) , (17, -68) , (18, -85) , (38, -90) + + Convex sub polygons: + + (17, -68) , (21, -37) , (5, -41) , (0, -62) + (38, -90) , (62, -89) , (89, -85) , (173, -42) , (116, -31) , (21, -37) , (17, -68) , (18, -85) + (91, -22) , (116, -31) , (106, -2) , (93, -1) + (31, -25) , (52, -17) , (39, 0) , (28, -5) + (21, -37) , (116, -31) , (91, -22) , (52, -17) , (31, -25) + (116, -31) , (173, -42) , (171, -32) + + + diff --git a/examples/assets/sprites/rain.png b/examples/assets/sprites/rain.png new file mode 100644 index 00000000..d9a944df Binary files /dev/null and b/examples/assets/sprites/rain.png differ diff --git a/examples/assets/sprites/snowflakes.png b/examples/assets/sprites/snowflakes.png new file mode 100644 index 00000000..caf98ae8 Binary files /dev/null and b/examples/assets/sprites/snowflakes.png differ diff --git a/examples/assets/sprites/snowflakes_large.png b/examples/assets/sprites/snowflakes_large.png new file mode 100644 index 00000000..b8811128 Binary files /dev/null and b/examples/assets/sprites/snowflakes_large.png differ diff --git a/examples/assets/sprites/spinObj_01.png b/examples/assets/sprites/spinObj_01.png new file mode 100644 index 00000000..86873665 Binary files /dev/null and b/examples/assets/sprites/spinObj_01.png differ diff --git a/examples/assets/sprites/spinObj_02.png b/examples/assets/sprites/spinObj_02.png new file mode 100644 index 00000000..a140876d Binary files /dev/null and b/examples/assets/sprites/spinObj_02.png differ diff --git a/examples/assets/sprites/spinObj_03.png b/examples/assets/sprites/spinObj_03.png new file mode 100644 index 00000000..82532c79 Binary files /dev/null and b/examples/assets/sprites/spinObj_03.png differ diff --git a/examples/assets/sprites/spinObj_04.png b/examples/assets/sprites/spinObj_04.png new file mode 100644 index 00000000..9c790c37 Binary files /dev/null and b/examples/assets/sprites/spinObj_04.png differ diff --git a/examples/assets/sprites/spinObj_05.png b/examples/assets/sprites/spinObj_05.png new file mode 100644 index 00000000..ebb28c84 Binary files /dev/null and b/examples/assets/sprites/spinObj_05.png differ diff --git a/examples/assets/sprites/spinObj_06.png b/examples/assets/sprites/spinObj_06.png new file mode 100644 index 00000000..1dec5c81 Binary files /dev/null and b/examples/assets/sprites/spinObj_06.png differ diff --git a/examples/assets/sprites/spinObj_07.png b/examples/assets/sprites/spinObj_07.png new file mode 100644 index 00000000..e14a0215 Binary files /dev/null and b/examples/assets/sprites/spinObj_07.png differ diff --git a/examples/assets/sprites/spinObj_08.png b/examples/assets/sprites/spinObj_08.png new file mode 100644 index 00000000..0197fefa Binary files /dev/null and b/examples/assets/sprites/spinObj_08.png differ diff --git a/examples/assets/sprites/stormlord-dragon96x64.png b/examples/assets/sprites/stormlord-dragon96x64.png new file mode 100644 index 00000000..2fbc4a95 Binary files /dev/null and b/examples/assets/sprites/stormlord-dragon96x64.png differ diff --git a/examples/assets/sprites/tetrisblock1.png b/examples/assets/sprites/tetrisblock1.png new file mode 100644 index 00000000..fb2c4aac Binary files /dev/null and b/examples/assets/sprites/tetrisblock1.png differ diff --git a/examples/assets/sprites/tetrisblock2.png b/examples/assets/sprites/tetrisblock2.png new file mode 100644 index 00000000..7459d2ca Binary files /dev/null and b/examples/assets/sprites/tetrisblock2.png differ diff --git a/examples/assets/sprites/tetrisblock3.png b/examples/assets/sprites/tetrisblock3.png new file mode 100644 index 00000000..166ce597 Binary files /dev/null and b/examples/assets/sprites/tetrisblock3.png differ diff --git a/examples/assets/sprites/vu.png b/examples/assets/sprites/vu.png new file mode 100644 index 00000000..5f06d804 Binary files /dev/null and b/examples/assets/sprites/vu.png differ diff --git a/examples/assets/sprites/wasp.png b/examples/assets/sprites/wasp.png new file mode 100644 index 00000000..9fb560b0 Binary files /dev/null and b/examples/assets/sprites/wasp.png differ diff --git a/examples/assets/sprites/wizball.png b/examples/assets/sprites/wizball.png index f471f549..d0523312 100644 Binary files a/examples/assets/sprites/wizball.png and b/examples/assets/sprites/wizball.png differ diff --git a/examples/assets/tests/fusia.png b/examples/assets/tests/fusia.png new file mode 100644 index 00000000..5c584a0f Binary files /dev/null and b/examples/assets/tests/fusia.png differ diff --git a/examples/assets/maps/catastrophi_level1.csv b/examples/assets/tilemaps/csv/catastrophi_level1.csv similarity index 100% rename from examples/assets/maps/catastrophi_level1.csv rename to examples/assets/tilemaps/csv/catastrophi_level1.csv diff --git a/examples/assets/maps/catastrophi_level2.csv b/examples/assets/tilemaps/csv/catastrophi_level2.csv similarity index 100% rename from examples/assets/maps/catastrophi_level2.csv rename to examples/assets/tilemaps/csv/catastrophi_level2.csv diff --git a/examples/assets/maps/catastrophi_level3.csv b/examples/assets/tilemaps/csv/catastrophi_level3.csv similarity index 100% rename from examples/assets/maps/catastrophi_level3.csv rename to examples/assets/tilemaps/csv/catastrophi_level3.csv diff --git a/examples/assets/tilemaps/maps/commando.json b/examples/assets/tilemaps/maps/commando.json new file mode 100644 index 00000000..07500aef --- /dev/null +++ b/examples/assets/tilemaps/maps/commando.json @@ -0,0 +1,39 @@ +{ "height":180, + "layers":[ + { + "data":[1, 1, 1, 1, 1, 2, 3, 4, 4, 5, 6, 1, 1, 1, 1, 1, 7, 7, 7, 7, 7, 8, 9, 4, 4, 10, 11, 7, 7, 7, 7, 7, 12, 12, 12, 12, 12, 13, 14, 4, 4, 15, 16, 12, 12, 12, 12, 12, 17, 17, 18, 17, 18, 4, 19, 4, 4, 20, 21, 18, 17, 17, 18, 17, 18, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 17, 17, 18, 17, 18, 22, 23, 23, 24, 17, 17, 18, 17, 22, 23, 23, 24, 18, 17, 18, 17, 17, 17, 17, 17, 17, 18, 17, 18, 17, 17, 17, 25, 26, 26, 26, 26, 27, 18, 18, 17, 18, 18, 18, 17, 17, 17, 18, 28, 29, 29, 29, 29, 30, 18, 17, 18, 17, 17, 18, 17, 17, 17, 18, 28, 31, 31, 31, 31, 30, 17, 17, 17, 17, 18, 17, 18, 17, 18, 18, 28, 29, 29, 29, 29, 30, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 28, 31, 31, 31, 31, 30, 17, 18, 17, 18, 18, 17, 17, 17, 17, 18, 28, 29, 29, 29, 29, 30, 18, 18, 17, 17, 18, 17, 17, 18, 17, 17, 28, 31, 31, 31, 31, 30, 17, 17, 18, 17, 17, 17, 18, 17, 17, 17, 28, 29, 29, 32, 32, 33, 18, 17, 17, 18, 17, 17, 17, 18, 18, 17, 34, 32, 32, 35, 35, 35, 35, 35, 36, 17, 17, 18, 37, 18, 17, 17, 17, 17, 17, 38, 38, 38, 38, 38, 39, 17, 17, 17, 18, 17, 18, 17, 17, 17, 17, 38, 38, 38, 38, 38, 39, 18, 17, 18, 17, 18, 37, 17, 17, 17, 17, 38, 38, 38, 38, 38, 39, 17, 17, 22, 23, 23, 24, 17, 37, 18, 37, 40, 40, 40, 40, 40, 41, 17, 17, 17, 17, 17, 17, 42, 43, 17, 18, 37, 18, 18, 37, 17, 18, 17, 17, 18, 17, 18, 18, 44, 45, 18, 17, 18, 17, 37, 17, 17, 17, 37, 18, 42, 43, 17, 17, 17, 18, 37, 18, 17, 17, 17, 18, 18, 17, 18, 46, 44, 45, 17, 17, 18, 17, 18, 17, 17, 17, 17, 18, 42, 43, 18, 37, 18, 17, 17, 18, 18, 37, 18, 17, 17, 18, 17, 17, 44, 45, 17, 18, 17, 18, 18, 37, 46, 25, 26, 26, 18, 17, 18, 18, 37, 18, 17, 17, 18, 17, 18, 18, 37, 28, 29, 29, 42, 43, 17, 37, 46, 37, 18, 18, 17, 17, 17, 37, 18, 28, 31, 31, 44, 45, 17, 18, 47, 47, 47, 18, 17, 17, 18, 17, 17, 28, 29, 29, 37, 17, 18, 17, 48, 48, 48, 17, 17, 18, 17, 17, 17, 28, 31, 31, 17, 18, 37, 18, 49, 49, 49, 17, 17, 17, 18, 18, 17, 34, 32, 32, 17, 18, 18, 46, 18, 18, 17, 17, 18, 37, 18, 17, 18, 17, 18, 47, 18, 17, 37, 18, 37, 17, 17, 17, 17, 18, 17, 18, 18, 37, 47, 48, 23, 23, 23, 23, 24, 37, 18, 17, 18, 17, 18, 37, 18, 47, 48, 48, 17, 37, 18, 17, 18, 17, 17, 17, 17, 18, 17, 18, 47, 48, 48, 48, 18, 46, 37, 17, 17, 17, 17, 17, 17, 17, 17, 17, 49, 48, 48, 48, 37, 18, 18, 37, 17, 18, 17, 17, 18, 17, 18, 18, 17, 48, 48, 48, 18, 17, 37, 17, 17, 17, 22, 23, 23, 24, 17, 17, 17, 49, 48, 48, 17, 17, 17, 18, 18, 17, 18, 46, 18, 17, 17, 17, 18, 17, 48, 48, 17, 17, 17, 18, 17, 37, 18, 37, 18, 17, 17, 18, 18, 37, 48, 48, 17, 18, 17, 17, 18, 18, 17, 18, 18, 18, 37, 17, 46, 18, 49, 48, 22, 23, 23, 24, 37, 18, 17, 17, 18, 17, 18, 18, 37, 37, 18, 48, 17, 18, 17, 37, 46, 37, 18, 18, 17, 17, 17, 37, 18, 17, 18, 49, 17, 17, 17, 18, 18, 37, 17, 18, 17, 22, 23, 23, 23, 24, 17, 18, 37, 17, 18, 17, 37, 18, 17, 17, 17, 18, 17, 17, 17, 17, 18, 17, 17, 18, 37, 18, 17, 17, 18, 17, 17, 17, 18, 18, 17, 18, 17, 17, 17, 50, 51, 46, 18, 18, 17, 17, 18, 37, 18, 17, 18, 25, 29, 29, 50, 52, 53, 51, 37, 17, 17, 17, 17, 18, 17, 18, 18, 28, 29, 29, 54, 55, 56, 55, 22, 23, 23, 24, 18, 17, 18, 37, 18, 28, 29, 29, 17, 57, 18, 57, 18, 17, 17, 17, 17, 18, 17, 18, 17, 28, 29, 29, 18, 46, 37, 17, 17, 17, 17, 17, 17, 17, 17, 17, 18, 28, 31, 31, 37, 18, 18, 37, 17, 18, 17, 17, 18, 17, 18, 18, 17, 34, 32, 32, 18, 17, 37, 17, 17, 17, 37, 18, 37, 18, 17, 17, 17, 18, 37, 18, 17, 17, 17, 18, 18, 17, 18, 46, 37, 18, 17, 17, 17, 18, 37, 18, 17, 42, 43, 18, 17, 37, 18, 42, 43, 17, 17, 18, 18, 42, 43, 17, 17, 44, 45, 17, 18, 18, 17, 44, 45, 18, 18, 37, 46, 44, 45, 18, 18, 17, 18, 18, 37, 18, 17, 17, 18, 17, 18, 18, 37, 37, 18, 17, 17, 18, 17, 37, 46, 37, 18, 18, 17, 17, 17, 37, 18, 17, 18, 37, 17, 17, 17, 17, 18, 37, 17, 18, 17, 17, 18, 17, 17, 18, 17, 18, 17, 17, 17, 17, 37, 18, 17, 17, 17, 18, 42, 43, 17, 17, 18, 17, 17, 17, 17, 17, 17, 17, 18, 17, 17, 17, 44, 45, 17, 18, 17, 17, 17, 18, 18, 46, 18, 18, 17, 17, 18, 37, 18, 17, 18, 17, 18, 17, 18, 17, 37, 18, 37, 17, 17, 17, 17, 18, 17, 18, 18, 37, 18, 18, 17, 18, 17, 17, 17, 37, 18, 17, 18, 17, 18, 42, 43, 18, 46, 37, 22, 23, 23, 24, 18, 17, 17, 17, 17, 18, 17, 44, 45, 37, 18, 37, 18, 46, 37, 17, 17, 17, 17, 42, 43, 17, 17, 17, 18, 17, 17, 18, 37, 18, 18, 37, 17, 18, 17, 44, 45, 17, 18, 18, 17, 17, 18, 17, 18, 17, 42, 43, 17, 17, 37, 18, 37, 18, 17, 17, 17, 18, 37, 18, 17, 17, 44, 45, 18, 17, 18, 46, 18, 17, 17, 17, 18, 17, 18, 17, 17, 17, 17, 18, 17, 37, 18, 37, 18, 17, 17, 18, 22, 23, 23, 24, 17, 18, 17, 17, 18, 18, 17, 18, 17, 18, 18, 37, 46, 18, 17, 47, 18, 17, 18, 18, 37, 18, 17, 17, 18, 17, 18, 18, 37, 37, 47, 48, 17, 18, 17, 42, 43, 37, 18, 18, 17, 17, 42, 43, 18, 17, 48, 48, 17, 17, 17, 44, 45, 37, 17, 18, 17, 17, 44, 45, 17, 18, 48, 48, 37, 17, 18, 17, 37, 18, 17, 17, 17, 18, 17, 17, 17, 17, 48, 48, 17, 18, 37, 18, 17, 17, 18, 17, 17, 17, 18, 18, 17, 18, 49, 49, 42, 43, 18, 46, 18, 18, 17, 17, 18, 37, 58, 35, 35, 35, 35, 35, 44, 45, 37, 18, 37, 17, 17, 17, 17, 18, 59, 38, 38, 38, 38, 38, 17, 18, 17, 17, 17, 37, 18, 17, 18, 17, 59, 38, 38, 38, 38, 38, 17, 37, 58, 35, 35, 36, 17, 17, 17, 18, 59, 38, 38, 38, 38, 38, 18, 46, 59, 38, 38, 39, 17, 17, 17, 17, 59, 38, 38, 38, 38, 38, 37, 18, 60, 40, 40, 41, 17, 17, 18, 17, 60, 40, 40, 40, 40, 40, 18, 17, 37, 17, 17, 17, 37, 18, 37, 18, 17, 17, 17, 18, 37, 18, 17, 17, 17, 18, 18, 17, 18, 46, 18, 17, 17, 17, 18, 17, 18, 17, 17, 17, 17, 18, 17, 37, 18, 37, 18, 17, 17, 18, 18, 37, 18, 17, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 61, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 62, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 63, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 64, 65, 65, 65, 65, 65, 65, 66, 67, 67, 68, 65, 65, 65, 65, 65, 65, 69, 69, 69, 69, 69, 69, 70, 71, 71, 72, 69, 69, 69, 69, 69, 69, 47, 47, 47, 46, 18, 18, 17, 17, 18, 37, 18, 17, 18, 17, 18, 17, 48, 48, 48, 47, 37, 17, 17, 17, 17, 18, 17, 18, 18, 73, 18, 18, 48, 48, 48, 48, 17, 50, 51, 17, 18, 17, 18, 37, 22, 23, 23, 24, 48, 48, 48, 49, 18, 54, 55, 17, 17, 18, 17, 18, 17, 37, 18, 37, 48, 48, 49, 17, 17, 17, 57, 17, 17, 17, 17, 17, 18, 17, 17, 18, 48, 49, 18, 37, 17, 18, 17, 17, 18, 17, 18, 18, 17, 17, 18, 17, 48, 50, 51, 17, 17, 17, 37, 18, 37, 50, 51, 17, 17, 18, 37, 18, 48, 54, 55, 18, 18, 17, 18, 46, 37, 54, 55, 17, 17, 18, 37, 18, 48, 47, 57, 18, 37, 37, 18, 37, 18, 17, 57, 18, 18, 37, 18, 47, 48, 48, 17, 17, 47, 47, 47, 18, 17, 18, 18, 37, 46, 18, 17, 48, 48, 48, 18, 18, 49, 48, 48, 17, 18, 17, 18, 18, 37, 37, 47, 48, 48, 48, 17, 37, 46, 49, 49, 18, 17, 17, 17, 37, 18, 17, 48, 48, 48, 48, 17, 18, 18, 37, 17, 18, 17, 18, 37, 17, 17, 18, 48, 48, 48, 48, 18, 17, 37, 18, 17, 17, 17, 18, 17, 17, 17, 47, 48, 48, 49, 49, 37, 18, 17, 17, 18, 17, 37, 18, 18, 18, 47, 48, 48, 48, 18, 17, 37, 18, 37, 50, 51, 17, 17, 18, 17, 18, 48, 48, 48, 48, 74, 74, 75, 17, 50, 52, 53, 51, 18, 17, 18, 37, 48, 48, 48, 48, 76, 76, 76, 77, 54, 55, 56, 55, 17, 18, 17, 18, 49, 48, 48, 48, 78, 78, 78, 79, 17, 57, 17, 57, 17, 17, 17, 17, 18, 49, 49, 49, 80, 80, 80, 81, 17, 18, 17, 18, 18, 18, 18, 18, 17, 82, 74, 74, 83, 83, 83, 84, 17, 17, 37, 46, 37, 18, 17, 17, 85, 76, 76, 76, 17, 17, 17, 18, 18, 17, 18, 17, 17, 18, 17, 17, 86, 78, 78, 78, 17, 18, 18, 46, 18, 18, 17, 17, 18, 37, 18, 17, 87, 88, 88, 88, 17, 17, 17, 18, 17, 37, 18, 37, 18, 17, 17, 18, 89, 90, 90, 90, 17, 18, 17, 17, 18, 18, 17, 18, 17, 18, 18, 37, 46, 47, 47, 47, 18, 17, 18, 18, 37, 18, 17, 18, 17, 17, 18, 18, 37, 48, 48, 48, 17, 18, 17, 37, 18, 82, 74, 74, 75, 17, 17, 37, 18, 48, 48, 48, 47, 17, 17, 18, 85, 76, 76, 76, 76, 77, 17, 37, 17, 48, 48, 48, 48, 47, 18, 17, 86, 78, 78, 78, 78, 79, 18, 17, 17, 48, 48, 48, 48, 48, 37, 18, 87, 88, 88, 80, 80, 81, 17, 17, 17, 49, 49, 49, 48, 48, 37, 18, 89, 90, 90, 83, 83, 84, 18, 18, 18, 82, 74, 74, 48, 48, 17, 17, 18, 17, 37, 17, 18, 17, 18, 37, 85, 76, 76, 76, 48, 48, 18, 17, 17, 18, 17, 37, 17, 18, 17, 18, 86, 78, 78, 78, 49, 49, 37, 17, 17, 17, 37, 17, 17, 17, 17, 17, 87, 88, 88, 88, 74, 74, 74, 74, 74, 74, 75, 17, 18, 17, 18, 18, 89, 90, 90, 90, 76, 76, 76, 76, 76, 76, 76, 77, 37, 18, 17, 17, 17, 47, 47, 47, 78, 78, 78, 78, 78, 78, 78, 79, 18, 17, 17, 17, 18, 48, 48, 48, 80, 80, 80, 80, 80, 80, 80, 81, 18, 17, 17, 18, 18, 48, 48, 48, 83, 83, 83, 83, 83, 83, 83, 84, 17, 18, 18, 37, 46, 48, 48, 48, 47, 47, 47, 47, 37, 18, 17, 17, 18, 17, 18, 18, 37, 48, 48, 48, 48, 48, 48, 48, 18, 18, 17, 17, 18, 37, 18, 17, 18, 48, 48, 48, 48, 48, 48, 48, 46, 37, 18, 18, 17, 17, 17, 37, 18, 48, 48, 48, 48, 48, 48, 48, 18, 37, 17, 18, 17, 17, 18, 17, 47, 48, 48, 48, 48, 48, 48, 48, 37, 18, 17, 17, 17, 18, 17, 17, 48, 48, 48, 48, 48, 48, 49, 49, 17, 17, 18, 17, 17, 17, 18, 18, 48, 48, 48, 48, 48, 48, 17, 18, 17, 17, 17, 17, 17, 18, 17, 17, 49, 48, 48, 48, 48, 48, 18, 17, 18, 17, 47, 47, 47, 47, 17, 17, 17, 48, 48, 48, 48, 48, 17, 17, 17, 18, 48, 48, 48, 48, 17, 18, 17, 49, 48, 48, 48, 48, 18, 17, 17, 17, 49, 49, 49, 49, 17, 17, 17, 18, 49, 48, 48, 49, 18, 17, 17, 17, 17, 17, 17, 17, 17, 17, 17, 50, 51, 48, 49, 18, 17, 18, 17, 18, 18, 18, 17, 17, 17, 17, 17, 54, 55, 48, 74, 74, 75, 17, 17, 17, 18, 17, 18, 17, 17, 17, 17, 17, 57, 48, 76, 76, 76, 77, 17, 17, 17, 18, 18, 17, 17, 17, 17, 17, 47, 48, 78, 78, 78, 79, 17, 18, 17, 18, 17, 50, 51, 17, 17, 18, 48, 48, 80, 80, 80, 81, 17, 17, 17, 17, 17, 54, 55, 18, 18, 17, 48, 48, 83, 83, 83, 84, 18, 17, 17, 17, 17, 17, 57, 17, 18, 18, 48, 48, 17, 17, 17, 18, 18, 50, 51, 17, 17, 17, 17, 18, 17, 17, 48, 48, 17, 17, 17, 17, 17, 54, 55, 17, 17, 17, 17, 17, 17, 17, 49, 48, 18, 17, 17, 17, 18, 17, 57, 17, 17, 17, 17, 17, 17, 17, 17, 48, 17, 17, 18, 17, 17, 17, 17, 17, 22, 23, 23, 24, 17, 17, 17, 49, 17, 50, 51, 46, 18, 18, 17, 17, 18, 37, 18, 17, 18, 17, 18, 17, 50, 52, 53, 51, 37, 17, 47, 47, 17, 18, 17, 18, 18, 37, 18, 18, 54, 55, 56, 55, 17, 49, 48, 49, 18, 17, 18, 37, 18, 18, 46, 37, 17, 57, 18, 57, 18, 17, 49, 17, 17, 18, 17, 18, 17, 37, 18, 37, 35, 35, 35, 36, 17, 17, 17, 17, 17, 17, 17, 17, 18, 17, 17, 18, 38, 38, 38, 39, 17, 18, 17, 17, 18, 17, 18, 18, 17, 82, 74, 74, 38, 38, 38, 39, 17, 17, 37, 18, 37, 18, 17, 17, 85, 76, 76, 76, 40, 40, 40, 41, 18, 17, 18, 46, 37, 18, 17, 17, 86, 78, 78, 78, 17, 17, 17, 18, 17, 50, 51, 37, 18, 17, 17, 18, 87, 88, 88, 88, 17, 18, 17, 17, 18, 54, 55, 18, 17, 18, 18, 37, 89, 90, 90, 90, 18, 17, 18, 18, 37, 18, 57, 17, 18, 17, 18, 18, 37, 37, 18, 17, 47, 18, 17, 37, 46, 37, 18, 18, 17, 50, 51, 37, 18, 17, 18, 37, 48, 47, 17, 18, 18, 37, 17, 18, 50, 52, 53, 51, 17, 18, 17, 18, 48, 48, 18, 17, 37, 18, 17, 17, 54, 55, 56, 55, 17, 17, 18, 17, 49, 49, 37, 18, 17, 17, 18, 17, 17, 57, 18, 57, 17, 18, 17, 17, 25, 91, 27, 17, 17, 50, 51, 17, 18, 17, 18, 37, 18, 18, 47, 47, 28, 31, 30, 17, 18, 54, 55, 17, 17, 18, 17, 18, 17, 47, 48, 48, 34, 32, 33, 17, 17, 17, 57, 17, 17, 17, 17, 17, 49, 49, 48, 49, 37, 18, 18, 37, 17, 18, 17, 17, 18, 17, 18, 18, 17, 17, 49, 17, 18, 17, 37, 17, 17, 17, 37, 18, 37, 18, 17, 17, 25, 91, 91, 27, 17, 17, 17, 18, 18, 17, 18, 46, 37, 18, 17, 17, 28, 31, 31, 30, 17, 17, 17, 18, 17, 37, 18, 37, 18, 17, 17, 18, 34, 32, 32, 33, 17, 18, 17, 17, 18, 18, 17, 18, 17, 18, 18, 37, 46, 18, 17, 18, 17, 50, 51, 46, 18, 18, 17, 17, 18, 37, 18, 17, 18, 17, 18, 17, 18, 54, 55, 18, 37, 17, 17, 17, 17, 18, 17, 18, 18, 37, 18, 18, 18, 17, 57, 18, 37, 18, 17, 17, 18, 50, 51, 18, 37, 37, 18, 17, 17, 18, 17, 37, 46, 37, 18, 18, 50, 52, 53, 51, 18, 17, 18, 37, 17, 17, 17, 18, 18, 37, 17, 18, 54, 55, 56, 55, 17, 18, 17, 18, 37, 17, 18, 17, 37, 18, 17, 17, 17, 57, 17, 57, 17, 17, 18, 17, 17, 18, 37, 18, 17, 17, 18, 17, 17, 17, 18, 18, 17, 18, 17, 17], + "height":180, + "name":"ShoeBox Tile Grab", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":16, + "x":0, + "y":0 + }], + "orientation":"orthogonal", + "properties": + { + + }, + "tileheight":32, + "tilesets":[ + { + "firstgid":1, + "image":"CommandoMap1-1BG_bank.png", + "imageheight":608, + "imagewidth":160, + "margin":0, + "name":"CommandoMap1-1BG_bank.png", + "properties": + { + + }, + "spacing":0, + "tileheight":32, + "tilewidth":32 + }], + "tilewidth":32, + "version":1, + "width":16 +} \ No newline at end of file diff --git a/examples/assets/maps/cybernoid.json b/examples/assets/tilemaps/maps/cybernoid.json similarity index 100% rename from examples/assets/maps/cybernoid.json rename to examples/assets/tilemaps/maps/cybernoid.json diff --git a/examples/assets/maps/burd.json b/examples/assets/tilemaps/maps/depthsort.json similarity index 100% rename from examples/assets/maps/burd.json rename to examples/assets/tilemaps/maps/depthsort.json diff --git a/examples/assets/maps/desert.json b/examples/assets/tilemaps/maps/desert.json similarity index 100% rename from examples/assets/maps/desert.json rename to examples/assets/tilemaps/maps/desert.json diff --git a/examples/assets/tilemaps/maps/features_test.json b/examples/assets/tilemaps/maps/features_test.json new file mode 100644 index 00000000..91c7bba3 --- /dev/null +++ b/examples/assets/tilemaps/maps/features_test.json @@ -0,0 +1,330 @@ +{ "height":18, + "layers":[ + { + "height":18, + "image":"..\/..\/sprites\/bunny.png", + "name":"Image Layer 1", + "opacity":1, + "properties": + { + "alpha":"0.8", + "x":"300" + }, + "transparentcolor":"#55ffff", + "type":"imagelayer", + "visible":true, + "width":50, + "x":0, + "y":0 + }, + { + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 11, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 11, 11, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 11, 11, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 9, 1, 1, 1, 1, 1, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "height":18, + "name":"Tile Layer 1", + "opacity":1, + "properties": + { + "collides":"true" + }, + "type":"tilelayer", + "visible":true, + "width":50, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 5, 5, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 5, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":18, + "name":"Tile Layer 2", + "opacity":1, + "properties": + { + "collides":"false" + }, + "type":"tilelayer", + "visible":true, + "width":50, + "x":0, + "y":0 + }, + { + "height":18, + "name":"Object Layer 1", + "objects":[ + { + "height":114, + "name":"exit", + "properties": + { + "open":"false" + }, + "type":"door", + "visible":true, + "width":44, + "x":475, + "y":430 + }, + { + "ellipse":true, + "height":70, + "name":"sun", + "properties": + { + + }, + "type":"collision", + "visible":true, + "width":77, + "x":793, + "y":340 + }, + { + "gid":34, + "height":0, + "name":"", + "properties": + { + "alpha":"0.5" + }, + "type":"", + "visible":true, + "width":0, + "x":443, + "y":244 + }, + { + "gid":34, + "height":0, + "name":"", + "properties": + { + + }, + "type":"", + "visible":true, + "width":0, + "x":483, + "y":267 + }, + { + "gid":34, + "height":0, + "name":"", + "properties": + { + "alpha":"0.5" + }, + "type":"", + "visible":true, + "width":0, + "x":513, + "y":237 + }, + { + "gid":34, + "height":0, + "name":"", + "properties": + { + + }, + "type":"", + "visible":true, + "width":0, + "x":549, + "y":229 + }, + { + "gid":34, + "height":0, + "name":"", + "properties": + { + "body.gravity.y":"5" + }, + "type":"", + "visible":true, + "width":0, + "x":580, + "y":249 + }, + { + "gid":34, + "height":0, + "name":"", + "properties": + { + + }, + "type":"", + "visible":true, + "width":0, + "x":610, + "y":278 + }, + { + "gid":34, + "height":0, + "name":"", + "properties": + { + + }, + "type":"", + "visible":true, + "width":0, + "x":639, + "y":309 + }, + { + "gid":34, + "height":0, + "name":"", + "properties": + { + + }, + "type":"", + "visible":true, + "width":0, + "x":662, + "y":342 + }, + { + "height":0, + "name":"ramp", + "polyline":[ + { + "x":-28, + "y":2 + }, + { + "x":52, + "y":-55 + }, + { + "x":189, + "y":-21 + }, + { + "x":91, + "y":-21 + }, + { + "x":75, + "y":78 + }, + { + "x":-40, + "y":79 + }, + { + "x":-30, + "y":3 + }], + "properties": + { + + }, + "type":"", + "visible":true, + "width":0, + "x":158, + "y":462 + }], + "opacity":1, + "type":"objectgroup", + "visible":true, + "width":50, + "x":0, + "y":0 + }, + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 100, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 130, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], + "height":18, + "name":"Tile Layer 3", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":50, + "x":0, + "y":0 + }], + "orientation":"orthogonal", + "properties": + { + + }, + "tileheight":32, + "tilesets":[ + { + "firstgid":1, + "image":"..\/tiles\/ground_1x1.png", + "imageheight":32, + "imagewidth":800, + "margin":0, + "name":"ground_1x1", + "properties": + { + + }, + "spacing":0, + "tileheight":32, + "tileproperties": + { + "1": + { + "bounce":"1" + } + }, + "tilewidth":32 + }, + { + "firstgid":26, + "image":"..\/tiles\/walls_1x2.png", + "imageheight":64, + "imagewidth":256, + "margin":0, + "name":"walls_1x2", + "properties": + { + + }, + "spacing":0, + "tileheight":64, + "tilewidth":32 + }, + { + "firstgid":34, + "image":"..\/..\/sprites\/coin.png", + "imageheight":32, + "imagewidth":192, + "margin":0, + "name":"coin", + "properties": + { + + }, + "spacing":0, + "tileheight":32, + "tilewidth":32 + }, + { + "firstgid":40, + "image":"..\/tiles\/tiles2.png", + "imageheight":910, + "imagewidth":840, + "margin":0, + "name":"tiles2", + "properties": + { + + }, + "spacing":0, + "tileheight":70, + "tilewidth":70 + }], + "tilewidth":32, + "version":1, + "width":50 +} \ No newline at end of file diff --git a/examples/assets/tilemaps/maps/platform.json b/examples/assets/tilemaps/maps/platform.json new file mode 100644 index 00000000..8650a88a --- /dev/null +++ b/examples/assets/tilemaps/maps/platform.json @@ -0,0 +1,39 @@ +{ "height":40, + "layers":[ + { + "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 33, 32, 32, 33, 32, 35, 32, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 34, 32, 32, 34, 34, 32, 32, 34, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 47, 45, 50, 51, 47, 49, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 21, 21, 52, 53, 23, 29, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 16, 0, 0, 0, 28, 24, 23, 24, 22, 21, 31, 0, 0, 0, 0, 0, 0, 0, 2, 41, 41, 41, 41, 43, 41, 41, 41, 41, 41, 43, 41, 41, 41, 41, 43, 41, 41, 41, 43, 43, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 41, 44, 3, 78, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 60, 78, 78, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 80, 79, 79, 79, 79, 79, 79, 79, 81, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 79, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78, 78], + "height":40, + "name":"Tile Layer 1", + "opacity":1, + "type":"tilelayer", + "visible":true, + "width":50, + "x":0, + "y":0 + }], + "orientation":"orthogonal", + "properties": + { + + }, + "tileheight":16, + "tilesets":[ + { + "firstgid":1, + "image":"..\/tiles\/platformer_tiles.png", + "imageheight":96, + "imagewidth":304, + "margin":0, + "name":"platformer_tiles", + "properties": + { + + }, + "spacing":0, + "tileheight":16, + "tilewidth":16 + }], + "tilewidth":16, + "version":1, + "width":50 +} \ No newline at end of file diff --git a/examples/assets/tilemaps/maps/super_mario.json b/examples/assets/tilemaps/maps/super_mario.json new file mode 100644 index 00000000..08502c39 --- /dev/null +++ b/examples/assets/tilemaps/maps/super_mario.json @@ -0,0 +1,50 @@ +{ "height":15, + "layers":[ + { + "data":[1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 3, 4, 1, 1, 1, 1, 6, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 3, 4, 1, 1, 1, 1, 6, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 3, 4, 1, 1, 1, 1, 6, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 2, 3, 3, 3, 4, 1, 1, 1, 1, 6, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 9, 10, 1, 2, 3, 4, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 1, 1, 1, 1, 6, 7, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 7, 7, 8, 1, 11, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 7, 7, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 13, 1, 6, 7, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 15, 15, 15, 15, 15, 1, 1, 1, 15, 15, 15, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 15, 1, 1, 1, 1, 15, 14, 14, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 18, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 1, 1, 1, 1, 12, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 12, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 1, 1, 1, 1, 1, 1, 19, 1, 1, 1, 1, 11, 1, 1, 11, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 11, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 20, 20, 20, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 1, 1, 1, 15, 14, 15, 14, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 22, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 22, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 14, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 14, 1, 1, 1, 1, 1, 15, 14, 1, 1, 1, 1, 14, 1, 1, 14, 1, 1, 14, 1, 1, 1, 1, 1, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 1, 1, 1, 1, 1, 1, 16, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 1, 1, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 15, 15, 14, 15, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 17, 1, 1, 1, 1, 23, 24, 25, 1, 1, 1, 1, 1, 1, 1, 1, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 22, 1, 1, 1, 1, 1, 1, 27, 28, 1, 1, 26, 1, 1, 1, 1, 1, 1, 27, 28, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 1, 1, 16, 16, 1, 1, 1, 1, 26, 1, 1, 1, 16, 16, 16, 1, 1, 16, 16, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 16, 16, 16, 1, 1, 1, 1, 26, 1, 1, 1, 17, 1, 1, 1, 20, 29, 29, 29, 20, 1, 1, 1, 1, 1, 1, 30, 31, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 22, 1, 1, 1, 1, 1, 1, 1, 1, 27, 28, 1, 1, 1, 1, 1, 1, 27, 28, 1, 30, 31, 32, 1, 1, 1, 1, 1, 27, 28, 1, 1, 1, 1, 1, 1, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 30, 31, 32, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 1, 1, 16, 16, 16, 1, 1, 30, 31, 32, 1, 16, 16, 16, 16, 1, 1, 16, 16, 16, 1, 1, 1, 26, 1, 21, 22, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 21, 22, 1, 16, 16, 16, 16, 16, 16, 16, 16, 1, 1, 1, 30, 31, 32, 1, 1, 17, 1, 1, 1, 24, 24, 33, 24, 24, 1, 1, 26, 1, 1, 30, 31, 34, 35, 32, 1, 1, 1, 1, 1, 1, 36, 37, 37, 37, 38, 30, 31, 32, 1, 1, 1, 1, 36, 37, 38, 1, 1, 27, 28, 1, 1, 1, 1, 1, 1, 1, 1, 27, 28, 1, 36, 37, 37, 38, 1, 27, 28, 30, 31, 34, 35, 32, 1, 1, 1, 1, 27, 28, 36, 37, 37, 37, 38, 30, 31, 32, 1, 1, 1, 1, 36, 37, 38, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 36, 37, 37, 38, 1, 1, 1, 30, 31, 34, 35, 32, 1, 1, 1, 1, 1, 1, 36, 37, 37, 37, 38, 30, 31, 32, 1, 1, 1, 1, 36, 37, 38, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 16, 16, 16, 16, 37, 37, 16, 16, 16, 16, 30, 31, 34, 35, 16, 16, 16, 16, 16, 1, 1, 16, 16, 16, 16, 38, 30, 31, 32, 27, 28, 1, 1, 36, 37, 38, 1, 1, 1, 1, 1, 1, 1, 1, 1, 27, 28, 16, 16, 16, 16, 16, 16, 16, 16, 16, 1, 1, 30, 31, 34, 35, 32, 1, 16, 1, 1, 1, 24, 24, 39, 24, 24, 38, 30, 31, 32, 1, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 1, 1, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 1, 1, 1, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 1, 1, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 1, 1, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 1, 1, 1, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 1, 1, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40, 40], + "height":15, + "name":"World1", + "opacity":1, + "properties": + { + "time":"1000" + }, + "type":"tilelayer", + "visible":true, + "width":212, + "x":0, + "y":0 + }], + "orientation":"orthogonal", + "properties": + { + "mapProp":"123" + }, + "tileheight":16, + "tilesets":[ + { + "firstgid":1, + "image":"super_mario.png", + "imageheight":64, + "imagewidth":176, + "margin":0, + "name":"SuperMarioBros-World1-1", + "properties": + { + + }, + "spacing":0, + "tileheight":16, + "tileproperties": + { + "10": + { + "coin":"true" + } + }, + "tilewidth":16 + }], + "tilewidth":16, + "version":1, + "width":212 +} \ No newline at end of file diff --git a/examples/assets/tilemaps/maps/tile_collision_test.json b/examples/assets/tilemaps/maps/tile_collision_test.json new file mode 100644 index 00000000..95c9dacf --- /dev/null +++ b/examples/assets/tilemaps/maps/tile_collision_test.json @@ -0,0 +1,65 @@ +{ "height":18, + "layers":[ + { + "data":[26, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 1, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 26, 26, 26, 0, 0, 0, 0, 1, 1, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 11, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 11, 11, 0, 0, 0, 0, 26, 0, 0, 1, 0, 0, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 26, 26, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 0, 0, 0, 11, 11, 0, 0, 0, 0, 1, 0, 0, 1, 1, 1, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 26, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 9, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 26, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 26, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 9, 1, 1, 1, 1, 1, 9, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], + "height":18, + "name":"Tile Layer 1", + "opacity":1, + "properties": + { + "collides":"true" + }, + "type":"tilelayer", + "visible":true, + "width":50, + "x":0, + "y":0 + }], + "orientation":"orthogonal", + "properties": + { + + }, + "tileheight":32, + "tilesets":[ + { + "firstgid":1, + "image":"..\/tiles\/ground_1x1.png", + "imageheight":32, + "imagewidth":800, + "margin":0, + "name":"ground_1x1", + "properties": + { + + }, + "spacing":0, + "tileheight":32, + "tileproperties": + { + "1": + { + "bounce":"1" + } + }, + "tilewidth":32 + }, + { + "firstgid":26, + "image":"..\/..\/sprites\/coin.png", + "imageheight":32, + "imagewidth":192, + "margin":0, + "name":"coin", + "properties": + { + + }, + "spacing":0, + "tileheight":32, + "tilewidth":32 + }], + "tilewidth":32, + "version":1, + "width":50 +} \ No newline at end of file diff --git a/examples/assets/tiles/catastrophi_tiles.png b/examples/assets/tilemaps/tiles/catastrophi_tiles.png similarity index 100% rename from examples/assets/tiles/catastrophi_tiles.png rename to examples/assets/tilemaps/tiles/catastrophi_tiles.png diff --git a/examples/assets/tiles/catastrophi_tiles_16.png b/examples/assets/tilemaps/tiles/catastrophi_tiles_16.png similarity index 100% rename from examples/assets/tiles/catastrophi_tiles_16.png rename to examples/assets/tilemaps/tiles/catastrophi_tiles_16.png diff --git a/examples/assets/tilemaps/tiles/commando.png b/examples/assets/tilemaps/tiles/commando.png new file mode 100644 index 00000000..bd2ebe65 Binary files /dev/null and b/examples/assets/tilemaps/tiles/commando.png differ diff --git a/examples/assets/maps/cybernoid.png b/examples/assets/tilemaps/tiles/cybernoid.png similarity index 100% rename from examples/assets/maps/cybernoid.png rename to examples/assets/tilemaps/tiles/cybernoid.png diff --git a/examples/assets/tiles/ground-tile.png b/examples/assets/tilemaps/tiles/ground-tile.png similarity index 100% rename from examples/assets/tiles/ground-tile.png rename to examples/assets/tilemaps/tiles/ground-tile.png diff --git a/examples/assets/maps/ground_1x1.png b/examples/assets/tilemaps/tiles/ground_1x1.png similarity index 100% rename from examples/assets/maps/ground_1x1.png rename to examples/assets/tilemaps/tiles/ground_1x1.png diff --git a/examples/assets/tiles/muddy-ground.png b/examples/assets/tilemaps/tiles/muddy-ground.png similarity index 100% rename from examples/assets/tiles/muddy-ground.png rename to examples/assets/tilemaps/tiles/muddy-ground.png diff --git a/examples/assets/tiles/platformer_tiles.png b/examples/assets/tilemaps/tiles/platformer_tiles.png similarity index 100% rename from examples/assets/tiles/platformer_tiles.png rename to examples/assets/tilemaps/tiles/platformer_tiles.png diff --git a/examples/assets/tiles/sci-fi-tiles.png b/examples/assets/tilemaps/tiles/sci-fi-tiles.png similarity index 100% rename from examples/assets/tiles/sci-fi-tiles.png rename to examples/assets/tilemaps/tiles/sci-fi-tiles.png diff --git a/examples/assets/tilemaps/tiles/super_mario.png b/examples/assets/tilemaps/tiles/super_mario.png new file mode 100644 index 00000000..919030fe Binary files /dev/null and b/examples/assets/tilemaps/tiles/super_mario.png differ diff --git a/examples/assets/tiles/tiles.png b/examples/assets/tilemaps/tiles/tiles.png similarity index 100% rename from examples/assets/tiles/tiles.png rename to examples/assets/tilemaps/tiles/tiles.png diff --git a/examples/assets/tilemaps/tiles/tiles2.png b/examples/assets/tilemaps/tiles/tiles2.png new file mode 100644 index 00000000..8d986cc2 Binary files /dev/null and b/examples/assets/tilemaps/tiles/tiles2.png differ diff --git a/examples/assets/tiles/tmw_desert_spacing.png b/examples/assets/tilemaps/tiles/tmw_desert_spacing.png similarity index 100% rename from examples/assets/tiles/tmw_desert_spacing.png rename to examples/assets/tilemaps/tiles/tmw_desert_spacing.png diff --git a/examples/assets/maps/walls_1x2.png b/examples/assets/tilemaps/tiles/walls_1x2.png similarity index 100% rename from examples/assets/maps/walls_1x2.png rename to examples/assets/tilemaps/tiles/walls_1x2.png diff --git a/examples/assets/tilemaps/tmx/commando.tmx b/examples/assets/tilemaps/tmx/commando.tmx new file mode 100644 index 00000000..9a66b482 --- /dev/null +++ b/examples/assets/tilemaps/tmx/commando.tmx @@ -0,0 +1,2890 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/examples/assets/maps/CybernoidMap3BG_map.tmx b/examples/assets/tilemaps/tmx/cybernoid.tmx similarity index 99% rename from examples/assets/maps/CybernoidMap3BG_map.tmx rename to examples/assets/tilemaps/tmx/cybernoid.tmx index 6d1b444f..98f557f1 100644 --- a/examples/assets/maps/CybernoidMap3BG_map.tmx +++ b/examples/assets/tilemaps/tmx/cybernoid.tmx @@ -1,9 +1,9 @@ - - + + - + diff --git a/examples/assets/tilemaps/tmx/features test.tmx b/examples/assets/tilemaps/tmx/features test.tmx new file mode 100644 index 00000000..60cac68e --- /dev/null +++ b/examples/assets/tilemaps/tmx/features test.tmx @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAJAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAsAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAALAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAACwAAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAACQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAACQAAAAEAAAABAAAAAQAAAAEAAAABAAAACQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAA + + + + + + + + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAABQAAAAAAAAAFAAAABQAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABQAAAAUAAAAAAAAAAAAAAAUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAABQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAUAAAAFAAAAAAAAAAAAAAAFAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABkAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACCAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAWAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAACgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA + + + diff --git a/examples/assets/maps/map draw.tmx b/examples/assets/tilemaps/tmx/map draw.tmx similarity index 86% rename from examples/assets/maps/map draw.tmx rename to examples/assets/tilemaps/tmx/map draw.tmx index 2572504d..c00c8006 100644 --- a/examples/assets/maps/map draw.tmx +++ b/examples/assets/tilemaps/tmx/map draw.tmx @@ -1,7 +1,7 @@ - + diff --git a/examples/assets/tilemaps/tmx/platform test.tmx b/examples/assets/tilemaps/tmx/platform test.tmx new file mode 100644 index 00000000..08b8c8f5 --- /dev/null +++ b/examples/assets/tilemaps/tmx/platform test.tmx @@ -0,0 +1,11 @@ + + + + + + + + eJztlcsOgjAQRavu1Y2PGI2IK6PG+Nr5Daj//zOOsYkExz5mphSUm5wgpZ3eW1tQ6rfUKuDaz4VYonitSg5p702OTz+SOShjXHxIr0VoH5T6lDxl7CvueaGuq+lZjBw+NbB+Ejm4/jGfvv3LPAMUHyH8uuaQWoeYGWxeqKpaDmqWKuXgZOGuQQhxzwh3LqwO5z+j5MhfKd6xOV37Su1TbG5bFps4+5Uq33V0rRlDEu+afC3KfBLZy/wGUM5DiMw9i0cX+Z4z6RwJsNDX/O9lrq0OStXbb4rcJ1Fc/Y58zlyMb4KrKDmqBJalrHWwjfWpa/IUS3tgB2yBA3DU93tVrz0+AQaaE3AGRsDMs05f2JdJXWS+KTBWL+/P61C9Ms0ttdrAqsAaafvWXmxbG8aHYAN0gAy41JxMc2Vyszy/C8xhImtoaPgLHpcgdus= + + + diff --git a/examples/assets/maps/ContraMapStage8BG.png b/examples/assets/tilemaps/tmx/raw/ContraMapStage8BG.png similarity index 100% rename from examples/assets/maps/ContraMapStage8BG.png rename to examples/assets/tilemaps/tmx/raw/ContraMapStage8BG.png diff --git a/examples/assets/maps/CybernoidMap3BG.png b/examples/assets/tilemaps/tmx/raw/CybernoidMap3BG.png similarity index 100% rename from examples/assets/maps/CybernoidMap3BG.png rename to examples/assets/tilemaps/tmx/raw/CybernoidMap3BG.png diff --git a/examples/assets/tilemaps/tmx/raw/SuperMarioBros-World1-1.png b/examples/assets/tilemaps/tmx/raw/SuperMarioBros-World1-1.png new file mode 100644 index 00000000..3c024c1b Binary files /dev/null and b/examples/assets/tilemaps/tmx/raw/SuperMarioBros-World1-1.png differ diff --git a/examples/assets/tilemaps/tmx/super mario bros.tmx b/examples/assets/tilemaps/tmx/super mario bros.tmx new file mode 100644 index 00000000..7d8d6f0c --- /dev/null +++ b/examples/assets/tilemaps/tmx/super mario bros.tmx @@ -0,0 +1,3201 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/examples/assets/tilemaps/tmx/tile collision test.tmx b/examples/assets/tilemaps/tmx/tile collision test.tmx new file mode 100644 index 00000000..707503d7 --- /dev/null +++ b/examples/assets/tilemaps/tmx/tile collision test.tmx @@ -0,0 +1,22 @@ + + + + + + + + + + + + + + + + + + + GgAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAaAAAAGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAAGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAJAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAGgAAABoAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAsAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAsAAAALAAAAAAAAAAAAAAAAAAAAAAAAABoAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAABoAAAAaAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAACwAAAAsAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAACQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoAAAAaAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAABoAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAaAAAAAAAAAAEAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABoAAAAAAAAAAAAAAAAAAAAAAAAAGgAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAGgAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAACQAAAAEAAAABAAAAAQAAAAEAAAABAAAACQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAAAQAAAAEAAAABAAAA + + + diff --git a/examples/assets/maps/desert2.json b/examples/assets/tilemaps/tmx/unsorted/desert2.json similarity index 100% rename from examples/assets/maps/desert2.json rename to examples/assets/tilemaps/tmx/unsorted/desert2.json diff --git a/examples/assets/wip/karamoon.png b/examples/assets/wip/karamoon.png new file mode 100644 index 00000000..6dca95ab Binary files /dev/null and b/examples/assets/wip/karamoon.png differ diff --git a/examples/audio/protracker.js b/examples/audio/protracker.js new file mode 100644 index 00000000..4ca33bc9 --- /dev/null +++ b/examples/audio/protracker.js @@ -0,0 +1,206 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.script('protracker', '../plugins/ProTracker.js'); + + game.load.image('vu', 'assets/sprites/vu.png'); + game.load.image('logo', 'assets/sprites/soundtracker.png'); + game.load.image('bg', 'assets/skies/sky2.png'); + game.load.image('vulkaiser', 'assets/pics/vulkaiser_red.png'); + + game.load.binary('macrocosm', 'assets/audio/protracker/macrocosm.mod', modLoaded, this); + game.load.binary('impulse', 'assets/audio/protracker/act_of_impulse.mod', modLoaded, this); + game.load.binary('enigma', 'assets/audio/protracker/enigma.mod', modLoaded, this); + game.load.binary('elysium', 'assets/audio/protracker/elysium.mod', modLoaded, this); + game.load.binary('stardust', 'assets/audio/protracker/sd-ingame1.mod', modLoaded, this); + game.load.binary('globaltrash', 'assets/audio/protracker/global_trash_3_v2.mod', modLoaded, this); + +} + +function modLoaded(key, data) { + + mods.push(key); + + var buffer = new Uint8Array(data); + + return buffer; + +} + +var mods = []; +var current = 0; + +var vu1; +var vu2; +var vu3; +var vu4; + +var modsample = []; +var module; + +var sample1; +var sample2; +var sample3; +var sample4; +var sampleName1; +var sampleName2; +var sampleName3; +var sampleName4; + +function create() { + + game.add.sprite(0, 0, 'bg'); + game.add.sprite(500, 32, 'logo'); + game.add.sprite(580, 371, 'vulkaiser'); + + vu1 = game.add.sprite(400, 200, 'vu'); + vu2 = game.add.sprite(400, 250, 'vu'); + vu3 = game.add.sprite(400, 300, 'vu'); + vu4 = game.add.sprite(400, 350, 'vu'); + + vu1.width = 0; + vu2.width = 0; + vu3.width = 0; + vu4.width = 0; + + module = new Protracker(); + module.buffer = game.cache.getBinary('macrocosm'); + module.parse(); + module.play(); + + game.input.onDown.add(nextMod, this); + +} + +function nextMod() { + + current++; + + if (current > mods.length - 1) + { + current = 0; + } + + module.stop(); + module.clearsong(); + + module.buffer = game.cache.getBinary(mods[current]); + module.parse(); + module.play(); + + vu1.width = 0; + vu2.width = 0; + vu3.width = 0; + vu4.width = 0; + +} + +function update() { + + sampleName1 = ''; + sampleName2 = ''; + sampleName3 = ''; + sampleName4 = ''; + + sample1 = module.channel[0].sample; + sample2 = module.channel[1].sample; + sample3 = module.channel[2].sample; + sample4 = module.channel[3].sample; + + /* + module.sample = array of Objects containing: + + data (Float32Array) + finetime + length (ms? bytes?) + looplength + loopstart + name + volume + + arpeggio: 0 + command: 0 + data: 0 + flags: 0 + note: 22 + noteon: 1 + period: 240 + sample: 11 + samplepos: 314.3411880952386 + samplespeed: 0.335118537414966 + semitone: 14 + slidespeed: 0 + slideto: 214 + slidetospeed: 0 + vibratodepth: 0 + vibratopos: 0 + vibratospeed: 0 + vibratowave: 0 + voiceperiod: 240 + volume: 64 + */ + + if (module.sample[sample1]) + { + sampleName1 = module.sample[sample1].name; + } + + if (module.sample[sample2]) + { + sampleName2 = module.sample[sample2].name; + } + + if (module.sample[sample3]) + { + sampleName3 = module.sample[sample3].name; + } + + if (module.sample[sample4]) + { + sampleName4 = module.sample[sample4].name; + } + + if (module.vu[0]) + { + vu1.width = Math.round(module.vu[0] * 1200); + } + + if (module.vu[1]) + { + vu2.width = Math.round(module.vu[1] * 1200); + } + + if (module.vu[2]) + { + vu3.width = Math.round(module.vu[2] * 1200); + } + + if (module.vu[3]) + { + vu4.width = Math.round(module.vu[3] * 1200); + } + +} + +function render() { + + game.debug.renderText('Sample ' + sample1 + ' : ' + sampleName1, 16, 32); + game.debug.renderText('Sample ' + sample2 + ' : ' + sampleName2, 16, 64); + game.debug.renderText('Sample ' + sample3 + ' : ' + sampleName3, 16, 96); + game.debug.renderText('Sample ' + sample4 + ' : ' + sampleName4, 16, 128); + + game.debug.renderText('Position: ' + module.position, 16, 160); + game.debug.renderText('Pattern: ' + module.row, 16, 192); + game.debug.renderText('BPM: ' + module.bpm, 16, 224); + game.debug.renderText('Speed: ' + module.speed, 16, 256); + game.debug.renderText('Name: ' + module.title, 16, 288); + game.debug.renderText('Signature: ' + module.signature, 16, 320); + + game.debug.renderText('vu1: ' + module.vu[0], 16, 352); + game.debug.renderText('vu2: ' + module.vu[1], 16, 384); + game.debug.renderText('vu3: ' + module.vu[2], 16, 416); + game.debug.renderText('vu4: ' + module.vu[3], 16, 448); + +} diff --git a/examples/camera/world sprite.js b/examples/camera/world sprite.js index e96f05ff..ab144fbd 100644 --- a/examples/camera/world sprite.js +++ b/examples/camera/world sprite.js @@ -1,5 +1,5 @@ -var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update,render : render }); +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); function preload() { @@ -9,7 +9,7 @@ function preload() { } var card; -var Keys = Phaser.Keyboard; +var cursors; function create() { @@ -19,27 +19,28 @@ function create() { card = game.add.sprite(200, 200, 'card'); - card.body.velocity.x = 50; - card.scale.setTo(2, 2); + game.camera.follow(card); + + cursors = game.input.keyboard.createCursorKeys(); } function update() { - if (game.input.keyboard.isDown(Keys.LEFT)) + if (cursors.left.isDown) { card.x -= 4; } - else if (game.input.keyboard.isDown(Keys.RIGHT)) + else if (cursors.right.isDown) { card.x += 4; } - if (game.input.keyboard.isDown(Keys.UP)) + if (cursors.up.isDown) { card.y -= 4; } - else if (game.input.keyboard.isDown(Keys.DOWN)) + else if (cursors.down.isDown) { card.y += 4; } @@ -48,7 +49,8 @@ function update() { function render() { - game.debug.renderCameraInfo(game.camera, 32, 32); - game.debug.renderSpriteInfo(card, 32, 200); + game.debug.renderCameraInfo(game.camera, 500, 32); + game.debug.renderSpriteCoords(card, 32, 32); + // game.debug.renderPhysicsBody(card.body); } diff --git a/examples/collision/body scale.js b/examples/collision/body scale.js new file mode 100644 index 00000000..99b86d01 --- /dev/null +++ b/examples/collision/body scale.js @@ -0,0 +1,46 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.spritesheet('gameboy', 'assets/sprites/gameboy_seize_color_40x60.png', 40, 60); + +} + +var sprite; +var sprite2; + +function create() { + + game.stage.backgroundColor = '#124184'; + + // Here we're tweening the scale of the sprite, which translates to the scale of the Body as well + // The collision will carry on working even against the scaled body. + + sprite = game.add.sprite(200, 300, 'gameboy', 2); + sprite.name = 'green'; + sprite.anchor.setTo(0.5, 0.5); + sprite.body.immovable = true; + + sprite2 = game.add.sprite(600, 270, 'gameboy', 3); + sprite2.name = 'yellow'; + sprite2.body.rebound = false; + + game.add.tween(sprite.scale).to( { x: 3, y: 3 }, 2000, Phaser.Easing.Linear.None, true, 0, 1000, true); + +} + +function update() { + + sprite2.body.velocity.x = -200; + + game.physics.collide(sprite, sprite2); + +} + +function render() { + + game.debug.renderPhysicsBody(sprite.body); + game.debug.renderPhysicsBody(sprite2.body); + +} diff --git a/examples/collision/bounding box.js b/examples/collision/bounding box.js index 760e6ce0..7d337697 100644 --- a/examples/collision/bounding box.js +++ b/examples/collision/bounding box.js @@ -14,16 +14,14 @@ function create() { game.stage.backgroundColor = '#2d2d2d'; - sprite1 = game.add.sprite(50, 200, 'atari'); + sprite1 = game.add.sprite(150, 300, 'atari'); sprite1.name = 'atari'; - sprite1.body.velocity.x = 100; - // This adjusts the collision body size. - // 100x100 is the new width/height. - // See the offset bounding box for another example. - sprite1.body.setSize(100, 100, 0, 0); + // Here you can visually see the two bounding boxes the sprites are using for collision. - sprite2 = game.add.sprite(700, 220, 'mushroom'); + sprite1.body.immovable = true; + + sprite2 = game.add.sprite(700, 320, 'mushroom'); sprite2.name = 'mushroom'; sprite2.body.velocity.x = -100; @@ -31,7 +29,6 @@ function create() { function update() { - // object1, object2, collideCallback, processCallback, callbackContext game.physics.collide(sprite1, sprite2, collisionHandler, null, this); } @@ -40,16 +37,13 @@ function collisionHandler (obj1, obj2) { game.stage.backgroundColor = '#992d2d'; - console.log(obj1.name + ' collided with ' + obj2.name); - } function render() { - game.debug.renderSpriteInfo(sprite1, 32, 32); - game.debug.renderSpriteCollision(sprite1, 32, 400); + game.debug.renderBodyInfo(sprite1, 32, 32); - game.debug.renderSpriteBody(sprite1); - game.debug.renderSpriteBody(sprite2); + game.debug.renderPhysicsBody(sprite1.body); + game.debug.renderPhysicsBody(sprite2.body); } diff --git a/examples/collision/circle body.js b/examples/collision/circle body.js new file mode 100644 index 00000000..0b3b9db2 --- /dev/null +++ b/examples/collision/circle body.js @@ -0,0 +1,51 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('wizball', 'assets/sprites/wizball.png'); + game.load.image('mushroom', 'assets/sprites/mushroom2.png'); + +} + +var sprite1; +var sprite2; + +function create() { + + game.stage.backgroundColor = '#2d2d2d'; + + sprite1 = game.add.sprite(130, 250, 'wizball'); + + // Here we've replaced the sprites body with a circle instead of a rectangle + // The value is the radius of the body in pixels + + sprite1.body.setCircle(46); + sprite1.body.immovable = true; + + sprite2 = game.add.sprite(700, 210, 'mushroom'); + sprite2.name = 'mushroom'; + sprite2.body.velocity.x = -100; + +} + +function update() { + + game.physics.collide(sprite1, sprite2, collisionHandler, null, this); + +} + +function collisionHandler (obj1, obj2) { + + game.stage.backgroundColor = '#992d2d'; + +} + +function render() { + + game.debug.renderBodyInfo(sprite2, 32, 32); + + game.debug.renderPhysicsBody(sprite1.body); + game.debug.renderPhysicsBody(sprite2.body); + +} diff --git a/examples/collision/circle vs polygon.js b/examples/collision/circle vs polygon.js new file mode 100644 index 00000000..62805d84 --- /dev/null +++ b/examples/collision/circle vs polygon.js @@ -0,0 +1,64 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('parsec', 'assets/sprites/parsec.png'); + game.load.image('wizball', 'assets/sprites/wizball.png'); + game.load.image('spaceman', 'assets/sprites/exocet_spaceman.png'); + +} + +var sprite1; +var sprite2; +var sprite3; +var sprite4; + +function create() { + + game.stage.backgroundColor = '#2d2d2d'; + + game.physics.gravity.y = 100; + + sprite1 = game.add.sprite(80, 200); + sprite1.body.setPolygon(0,0, 60,0, 100,40, 60,80, 0,80); + sprite1.body.translate(0, 144); + sprite1.body.immovable = true; + sprite1.body.allowGravity = false; + + sprite2 = game.add.sprite(450, 300, 'parsec'); + sprite2.body.setPolygon(56, -1 , 10, -5 , 1, -13 , 0, -34 , 55, -60 , 122, -78 , 165, -80 , 214, -74 , 285, -71 , 296, -44 , 298, -12 , 292, -5 , 168, -3); + sprite2.body.translate(0, 80); + sprite2.body.immovable = true; + sprite2.body.allowGravity = false; + + sprite3 = game.add.sprite(230, 400, 'spaceman'); + sprite3.body.setPolygon(34, -172 , 75, -172 , 87, -145 , 121, -52 , 105, -16 , 55, -3 , 9, -19 , 1, -57 , 24, -145); + sprite3.body.translate(0, 175); + sprite3.body.immovable = true; + sprite3.body.allowGravity = false; + + sprite4 = game.add.sprite(380, 100, 'wizball'); + sprite4.body.setCircle(46); + sprite4.body.collideWorldBounds = true; + sprite4.body.bounce.setTo(0.9, 0.9); + sprite4.body.velocity.setTo(100, 100); + +} + +function update() { + + game.physics.collide(sprite4, [ sprite1, sprite2, sprite3 ]); + +} + +function render() { + + game.debug.renderBodyInfo(sprite4, 32, 32); + + game.debug.renderPhysicsBody(sprite1.body); + game.debug.renderPhysicsBody(sprite2.body); + game.debug.renderPhysicsBody(sprite3.body); + game.debug.renderPhysicsBody(sprite4.body); + +} diff --git a/examples/collision/group vs group.js b/examples/collision/group vs group.js index dc6b4151..c408d9af 100644 --- a/examples/collision/group vs group.js +++ b/examples/collision/group vs group.js @@ -1,5 +1,5 @@ -var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update }); function preload() { @@ -12,8 +12,9 @@ function preload() { var sprite; var bullets; var veggies; -var bulletTime = 0; +var cursors; +var bulletTime = 0; var bullet; function create() { @@ -44,23 +45,26 @@ function create() { sprite = game.add.sprite(400, 550, 'phaser'); - // Stop the following keys from propagating up to the browser - game.input.keyboard.addKeyCapture([ Phaser.Keyboard.LEFT, Phaser.Keyboard.RIGHT, Phaser.Keyboard.SPACEBAR ]); + cursors = game.input.keyboard.createCursorKeys(); + game.input.keyboard.addKeyCapture([ Phaser.Keyboard.SPACEBAR ]); } function update() { + // As we don't need to exchange any velocities or motion we can the 'overlap' check instead of 'collide' + game.physics.overlap(bullets, veggies, collisionHandler, null, this); + sprite.body.velocity.x = 0; sprite.body.velocity.y = 0; - if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + if (cursors.left.isDown) { - sprite.body.velocity.x = -200; + sprite.body.velocity.x = -300; } - else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + else if (cursors.right.isDown) { - sprite.body.velocity.x = 200; + sprite.body.velocity.x = 300; } if (game.input.keyboard.isDown(Phaser.Keyboard.SPACEBAR)) @@ -68,8 +72,6 @@ function update() { fireBullet(); } - game.physics.collide(bullets, veggies, collisionHandler, null, this); - } function fireBullet () { @@ -82,7 +84,7 @@ function fireBullet () { { bullet.reset(sprite.x + 6, sprite.y - 8); bullet.body.velocity.y = -300; - bulletTime = game.time.now + 250; + bulletTime = game.time.now + 150; } } @@ -90,9 +92,12 @@ function fireBullet () { // Called if the bullet goes out of the screen function resetBullet (bullet) { + bullet.kill(); + } +// Called if the bullet hits one of the veg sprites function collisionHandler (bullet, veg) { bullet.kill(); diff --git a/examples/collision/group vs self.js b/examples/collision/group vs self.js new file mode 100644 index 00000000..33ccc1cb --- /dev/null +++ b/examples/collision/group vs self.js @@ -0,0 +1,39 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); + +function preload() { + + game.load.spritesheet('spinner', 'assets/sprites/bluemetal_32x32x4.png', 32, 32); + +} + +var sprites; + +function create() { + + // Here we create a group, populate it with sprites, give them all a random velocity + // and then check the group against itself for collision + + sprites = game.add.group(); + + for (var i = 0; i < 30; i++) + { + var s = sprites.create(game.rnd.integerInRange(100, 700), game.rnd.integerInRange(32, 200), 'spinner'); + s.animations.add('spin', [0,1,2,3]); + s.play('spin', 20, true); + s.body.velocity.x = game.rnd.integerInRange(-200, 200); + s.body.velocity.y = game.rnd.integerInRange(-200, 200); + } + + sprites.setAll('body.collideWorldBounds', true); + sprites.setAll('body.bounce.x', 1); + sprites.setAll('body.bounce.y', 1); + sprites.setAll('body.minBounceVelocity', 0); + +} + +function update() { + + game.physics.collide(sprites); + +} diff --git a/examples/collision/larger bounding box.js b/examples/collision/larger bounding box.js index 3bde58aa..76ce7b4c 100644 --- a/examples/collision/larger bounding box.js +++ b/examples/collision/larger bounding box.js @@ -15,14 +15,14 @@ function create() { game.stage.backgroundColor = '#2d2d2d'; - sprite1 = game.add.sprite(50, 200, 'atari'); + sprite1 = game.add.sprite(130, 200, 'atari'); sprite1.name = 'atari'; - sprite1.body.velocity.x = 100; // In this example the new collision box is much larger than the original sprite - sprite1.body.setSize(400, 50, -100, 20); + sprite1.body.setRectangle(400, 50, -100, 20); + sprite1.body.immovable = true; - sprite2 = game.add.sprite(700, 220, 'mushroom'); + sprite2 = game.add.sprite(700, 210, 'mushroom'); sprite2.name = 'mushroom'; sprite2.body.velocity.x = -100; @@ -30,7 +30,6 @@ function create() { function update() { - // object1, object2, collideCallback, processCallback, callbackContext game.physics.collide(sprite1, sprite2, collisionHandler, null, this); } @@ -39,13 +38,13 @@ function collisionHandler (obj1, obj2) { game.stage.backgroundColor = '#992d2d'; - console.log(obj1.name + ' collided with ' + obj2.name); - } function render() { - game.debug.renderRectangle(sprite1.body); - game.debug.renderRectangle(sprite2.body); + game.debug.renderBodyInfo(sprite1, 32, 32); + + game.debug.renderPhysicsBody(sprite1.body); + game.debug.renderPhysicsBody(sprite2.body); } diff --git a/examples/collision/offset bounding box.js b/examples/collision/offset bounding box.js index 4ae4b1d7..9aa234a1 100644 --- a/examples/collision/offset bounding box.js +++ b/examples/collision/offset bounding box.js @@ -15,15 +15,13 @@ function create() { game.stage.backgroundColor = '#2d2d2d'; - sprite1 = game.add.sprite(50, 200, 'atari'); + sprite1 = game.add.sprite(150, 200, 'atari'); sprite1.name = 'atari'; - sprite1.body.velocity.x = 100; - // This adjusts the collision body size. - // 100x50 is the new width/height. + // This adjusts the collision body size to be a 100x50 box. // 50, 25 is the X and Y offset of the newly sized box. - // In this case the box is 50px in and 25px down. - sprite1.body.setSize(100, 50, 50, 25); + sprite1.body.setRectangle(100, 50, 50, 25); + sprite1.body.immovable = true; sprite2 = game.add.sprite(700, 220, 'mushroom'); sprite2.name = 'mushroom'; @@ -33,7 +31,6 @@ function create() { function update() { - // object1, object2, collideCallback, processCallback, callbackContext game.physics.collide(sprite1, sprite2, collisionHandler, null, this); } @@ -42,13 +39,13 @@ function collisionHandler (obj1, obj2) { game.stage.backgroundColor = '#992d2d'; - console.log(obj1.name + ' collided with ' + obj2.name); - } function render() { - game.debug.renderRectangle(sprite1.body); - game.debug.renderRectangle(sprite2.body); + game.debug.renderBodyInfo(sprite1, 32, 32); + + game.debug.renderPhysicsBody(sprite1.body); + game.debug.renderPhysicsBody(sprite2.body); } diff --git a/examples/collision/one way collision.js b/examples/collision/one way collision.js new file mode 100644 index 00000000..49904c38 --- /dev/null +++ b/examples/collision/one way collision.js @@ -0,0 +1,58 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.spritesheet('gameboy', 'assets/sprites/gameboy_seize_color_40x60.png', 40, 60); + game.load.image('atari', 'assets/sprites/atari130xe.png'); + +} + +var sprite; +var sprite2; +var sprite3; + +function create() { + + game.stage.backgroundColor = '#124184'; + + // In this example the little Gameboy sprite can pass through the top/bottom of the Atari sprite + // Because it's set to ignore collisions on its top/bottom faces. + + sprite = game.add.sprite(300, 200, 'atari'); + sprite.name = 'atari'; + sprite.body.collideWorldBounds = true; + sprite.body.checkCollision.up = false; + sprite.body.checkCollision.down = false; + sprite.body.immovable = true; + + sprite2 = game.add.sprite(350, 400, 'gameboy', 2); + sprite2.name = 'gameboy'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(1, 1); + + sprite3 = game.add.sprite(0, 210, 'gameboy', 4); + sprite3.name = 'gameboy2'; + sprite3.body.collideWorldBounds = true; + sprite3.body.bounce.setTo(1, 1); + + sprite2.body.velocity.y = -200; + sprite3.body.velocity.x = 200; + +} + +function update() { + + game.physics.collide(sprite, sprite2); + game.physics.collide(sprite, sprite3); + +} + +function render() { + + // game.debug.renderBodyInfo(sprite, 16, 24); + + game.debug.renderPhysicsBody(sprite.body); + game.debug.renderPhysicsBody(sprite2.body); + +} diff --git a/examples/collision/polygon body.js b/examples/collision/polygon body.js new file mode 100644 index 00000000..f2cd421e --- /dev/null +++ b/examples/collision/polygon body.js @@ -0,0 +1,50 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('parsec', 'assets/sprites/parsec.png'); + game.load.image('spaceman', 'assets/sprites/exocet_spaceman.png'); + +} + +var sprite1; +var sprite2; + +function create() { + + game.stage.backgroundColor = '#2d2d2d'; + + // Here we've replaced the sprites body with a polygon. + // The point data was generated by tracing the PNGs in Physics Editor: http://www.codeandweb.com/physicseditor + + sprite1 = game.add.sprite(550, 250, 'parsec'); + sprite1.body.setPolygon(56, -1 , 10, -5 , 1, -13 , 0, -34 , 55, -60 , 122, -78 , 165, -80 , 214, -74 , 285, -71 , 296, -44 , 298, -12 , 292, -5 , 168, -3); + sprite1.body.translate(0, 80); + sprite1.body.velocity.x = -100; + + sprite2 = game.add.sprite(0, 200, 'spaceman'); + sprite2.body.setPolygon(34, -172 , 75, -172 , 87, -145 , 121, -52 , 105, -16 , 55, -3 , 9, -19 , 1, -57 , 24, -145); + sprite2.body.translate(0, 175); + sprite2.body.velocity.x = 100; + +} + +function update() { + + game.physics.collide(sprite1, sprite2, collisionHandler, null, this); + +} + +function collisionHandler (obj1, obj2) { + + game.stage.backgroundColor = '#992d2d'; + +} + +function render() { + + game.debug.renderPhysicsBody(sprite1.body); + game.debug.renderPhysicsBody(sprite2.body); + +} diff --git a/examples/collision/process callback.js b/examples/collision/process callback.js new file mode 100644 index 00000000..81347fbe --- /dev/null +++ b/examples/collision/process callback.js @@ -0,0 +1,65 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('atari', 'assets/sprites/atari130xe.png'); + game.load.image('mushroom', 'assets/sprites/mushroom2.png'); + +} + +var sprite1; +var sprite2; + +function create() { + + game.stage.backgroundColor = '#2d2d2d'; + + // This will check Sprite vs. Sprite collision using a custom process callback + sprite1 = game.add.sprite(0, 200, 'atari'); + sprite2 = game.add.sprite(750, 220, 'mushroom'); + + // We'll use random velocities so we can test it in our processCallback + sprite1.body.velocity.x = 50 + Math.random() * 100; + sprite2.body.velocity.x = -(50 + Math.random() * 100); + +} + +function update() { + + game.physics.collide(sprite1, sprite2, collisionCallback, processCallback, this); + +} + +function processCallback (obj1, obj2) { + + // This function can perform your own additional checks on the 2 objects that collided. + // For example you could test for velocity, health, etc. + // This function needs to return either true or false. If it returns true then collision carries on (separating the two objects). + // If it returns false the collision is assumed to have failed and aborts, no further checks or separation happen. + + if (obj1.body.speed > obj2.body.speed) + { + return true; + } + else + { + return false; + } + +} + +function collisionCallback (obj1, obj2) { + + game.stage.backgroundColor = '#992d2d'; + +} + +function render() { + + game.debug.renderText('The processCallback will only collide if sprite1 is going fastest.', 32, 32); + game.debug.renderText('Sprite 1 speed: ' + sprite1.body.speed, 32, 64); + game.debug.renderText('Sprite 2 speed: ' + sprite2.body.speed, 32, 96); + +} + diff --git a/examples/collision/rotated bounding box.js b/examples/collision/rotated bounding box.js new file mode 100644 index 00000000..575187c0 --- /dev/null +++ b/examples/collision/rotated bounding box.js @@ -0,0 +1,52 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('atari', 'assets/sprites/atari130xe.png'); + game.load.image('mushroom', 'assets/sprites/mushroom2.png'); + +} + +var sprite1; +var sprite2; + +function create() { + + game.stage.backgroundColor = '#2d2d2d'; + + sprite1 = game.add.sprite(130, 200, 'atari'); + sprite1.name = 'atari'; + + // Here we're rotated both the sprite and the physics body + + sprite1.rotation = 0.6; + sprite1.body.polygon.rotate(0.6); + sprite1.body.immovable = true; + + sprite2 = game.add.sprite(700, 210, 'mushroom'); + sprite2.name = 'mushroom'; + sprite2.body.velocity.x = -100; + +} + +function update() { + + game.physics.collide(sprite1, sprite2, collisionHandler, null, this); + +} + +function collisionHandler (obj1, obj2) { + + game.stage.backgroundColor = '#992d2d'; + +} + +function render() { + + game.debug.renderBodyInfo(sprite1, 32, 32); + + game.debug.renderPhysicsBody(sprite1.body); + game.debug.renderPhysicsBody(sprite2.body); + +} diff --git a/examples/collision/sprite tiles.js b/examples/collision/sprite tiles.js deleted file mode 100644 index f2fd2d34..00000000 --- a/examples/collision/sprite tiles.js +++ /dev/null @@ -1,69 +0,0 @@ - -var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); - -function preload() { - - game.load.spritesheet('tiles', 'assets/tiles/platformer_tiles.png', 16, 16); - game.load.image('carrot', 'assets/sprites/carrot.png'); - -} - -var tiles; -var sprite; - -function create() { - - game.stage.backgroundColor = '#2d2d2d'; - - tiles = game.add.group(); - - for (var x = 0; x < 40; x++) - { - var tile = tiles.create(100 + (x * 16), 300, 'tiles', 4); - tile.body.immovable = true; - } - - sprite = game.add.sprite(300, 150, 'carrot'); - sprite.name = 'mushroom'; - sprite.body.collideWorldBounds = true; - sprite.body.velocity.x = 40; - sprite.body.velocity.y = 120; - sprite.body.bounce.setTo(1, 1); - - game.input.onDown.add(carryOn, this); - -} - -function carryOn() { - - game.paused = false; - -} - -function update() { - - // object1, object2, collideCallback, processCallback, callbackContext - game.physics.collide(sprite, tiles, collisionHandler, null, this); - -} - -function collisionHandler (s, t) { - - t.alpha = 0.5; - - console.log('---------------------------------------------'); - console.log(t.body); - - game.paused = true; - -} - -function render() { - - // game.debug.renderSpriteInfo(sprite1, 32, 32); - // game.debug.renderSpriteCollision(sprite1, 32, 400); - - game.debug.renderSpriteBody(sprite); - // game.debug.renderSpriteBody(sprite2); - -} diff --git a/examples/collision/sprite vs group.js b/examples/collision/sprite vs group.js index c0f08a6b..223158cf 100644 --- a/examples/collision/sprite vs group.js +++ b/examples/collision/sprite vs group.js @@ -1,5 +1,5 @@ -var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); function preload() { @@ -10,12 +10,13 @@ function preload() { var sprite; var group; +var cursors; function create() { game.stage.backgroundColor = '#2d2d2d'; - // This will check Sprite vs. Group collision + // This example will check Sprite vs. Group collision sprite = game.add.sprite(32, 200, 'phaser'); sprite.name = 'phaser-dude'; @@ -24,7 +25,7 @@ function create() { for (var i = 0; i < 50; i++) { - var c = group.create(100 + Math.random() * 700, game.world.randomY, 'veggies', game.rnd.integerInRange(0, 36)); + var c = group.create(game.rnd.integerInRange(100, 770), game.rnd.integerInRange(0, 570), 'veggies', game.rnd.integerInRange(0, 36)); c.name = 'veg' + i; c.body.immovable = true; } @@ -32,58 +33,52 @@ function create() { for (var i = 0; i < 20; i++) { // Here we'll create some chillis which the player can pick-up. They are still part of the same Group. - var c = group.create(100 + Math.random() * 700, game.world.randomY, 'veggies', 17); + var c = group.create(game.rnd.integerInRange(100, 770), game.rnd.integerInRange(0, 570), 'veggies', 17); c.name = 'chilli' + i; c.body.immovable = true; } - game.input.keyboard.addKeyCapture([ Phaser.Keyboard.LEFT, Phaser.Keyboard.RIGHT, Phaser.Keyboard.UP, Phaser.Keyboard.DOWN ]); + cursors = game.input.keyboard.createCursorKeys(); } function update() { + game.physics.collide(sprite, group, collisionHandler, null, this); + game.physics.collide(group, group); + sprite.body.velocity.x = 0; sprite.body.velocity.y = 0; - if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + if (cursors.left.isDown) { sprite.body.velocity.x = -200; } - else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + else if (cursors.right.isDown) { sprite.body.velocity.x = 200; } - if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + if (cursors.up.isDown) { sprite.body.velocity.y = -200; } - else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) + else if (cursors.down.isDown) { sprite.body.velocity.y = 200; } - game.physics.collide(sprite, group, collisionHandler, null, this); - } -function collisionHandler (obj1, obj2) { +function collisionHandler (player, veg) { // If the player collides with the chillis then they get eaten :) // The chilli frame ID is 17 - console.log('Hit', obj2.name); - - if (obj2.frame == 17) + if (veg.frame == 17) { - obj2.kill(); + veg.kill(); } } -function render () { - - game.debug.renderQuadTree(game.physics.quadTree); - -} diff --git a/examples/collision/sprite vs sprite custom.js b/examples/collision/sprite vs sprite custom.js deleted file mode 100644 index a05f225c..00000000 --- a/examples/collision/sprite vs sprite custom.js +++ /dev/null @@ -1,78 +0,0 @@ - -var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render }); - -function preload() { - - game.load.image('atari', 'assets/sprites/atari130xe.png'); - game.load.image('mushroom', 'assets/sprites/mushroom2.png'); - -} - -var sprite1; -var sprite2; - -function create() { - - game.stage.backgroundColor = '#2d2d2d'; - - // This will check Sprite vs. Sprite collision using a custom process callback - - sprite1 = game.add.sprite(0, 200, 'atari'); - sprite1.name = 'atari'; - // We'll use a random velocity here so we can test it in our processHandler - sprite1.body.velocity.x = 50 + Math.random() * 100; - // This tells phaser to not use the built-in body separation, instead you should handle it in your process callback (see below) - sprite1.body.customSeparateX = true; - - sprite2 = game.add.sprite(750, 220, 'mushroom'); - sprite2.name = 'mushroom'; - // We'll use a random velocity here so we can test it in our processHandler - sprite2.body.velocity.x = -(50 + Math.random() * 100); - // This tells phaser to not use the built-in body separation, instead you should handle it in your process callback (see below) - sprite2.body.customSeparateX = true; - -} - -function update() { - - game.physics.collide(sprite1, sprite2, collisionHandler, processHandler, this); - -} - -function processHandler (obj1, obj2) { - - // This function can perform your own additional checks on the 2 objects that collided. - // For example you could test for velocity, health, etc. - // If you want the collision to be deemed successful this function must return true. - // In which case the collisionHandler will be called, otherwise it won't. - - // Note: the objects will have already been separated by this point unless you have set - // their customSeparateX/Y flags to true. If you do that it's up to you to handle separation. - - // Whichever one is going fastest wins, the other dies :) - if (obj1.body.velocity.x > Math.abs(obj2.body.velocity.x)) - { - obj2.kill(); - obj1.body.velocity.x = 0; - } - else - { - obj1.kill(); - obj2.body.velocity.x = 0; - } - - return true; - -} - -function collisionHandler (obj1, obj2) { - - game.stage.backgroundColor = '#992d2d'; - - console.log(obj1.name + ' collided with ' + obj2.name); - -} - -function render() { -} - diff --git a/examples/collision/sprite vs sprite.js b/examples/collision/sprite vs sprite.js index b344e94e..82e4a0b7 100644 --- a/examples/collision/sprite vs sprite.js +++ b/examples/collision/sprite vs sprite.js @@ -1,5 +1,5 @@ -var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); function preload() { @@ -36,8 +36,14 @@ function update() { function collisionHandler (obj1, obj2) { + // The two sprites are colliding game.stage.backgroundColor = '#992d2d'; - console.log(obj1.name + ' collided with ' + obj2.name); - } + +function render() { + + game.debug.renderPhysicsBody(sprite1.body); + game.debug.renderPhysicsBody(sprite2.body); + +} \ No newline at end of file diff --git a/examples/collision/transform.js b/examples/collision/transform.js deleted file mode 100644 index 2411433b..00000000 --- a/examples/collision/transform.js +++ /dev/null @@ -1,117 +0,0 @@ - -var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); - -function preload() { - - game.load.image('atari', 'assets/sprites/atari130xe.png'); - game.load.image('mushroom', 'assets/sprites/mushroom2.png'); - game.load.image('flectrum', 'assets/sprites/flectrum.png'); - -} - -var testGroup; -var sprite1; -var sprite2; -var sprite3; - -function create() { - - game.stage.backgroundColor = '#2d2d2d'; - - game.world.setBounds(-1000, -1000, 2000, 2000); - - testGroup = game.add.group(); - - test2(); - -} - -function test1 () { - - // Test 1 - 2 sprites in world space (seems to work fine with local transform?) - sprite1 = game.add.sprite(-600, 200, 'atari'); - sprite1.name = 'atari'; - // sprite1.body.setSize(100, 100, 0, 0); - - sprite2 = game.add.sprite(-100, 220, 'mushroom'); - sprite2.name = 'mushroom'; - - game.camera.focusOn(sprite1); - game.camera.x += 300; - - game.input.onDown.add(go1, this); - -} - -function test2 () { - - // 1 sprite in world space (seems to work fine with local transform?) and 1 in a group - - sprite1 = testGroup.create(0, -150, 'atari'); - sprite1.name = 'atari'; - sprite1.body.immovable = true; - // sprite1.body.setSize(100, 100, 0, 0); - - sprite2 = game.add.sprite(-100, 140, 'mushroom'); - sprite2.name = 'mushroom'; - - sprite3 = game.add.sprite(-200, 150, 'flectrum'); - sprite3.name = 'tall'; - - testGroup.x = -600; - testGroup.y = 200; - - game.camera.focusOn(sprite2); - game.camera.x -= 300; - - game.input.onDown.add(go2, this); - -} - -function go1 () { - - sprite1.body.velocity.x = 100; - sprite2.body.velocity.x = -100; - -} - -function go2 () { - - sprite2.body.velocity.x = -100; - -} - -function update () { - - game.physics.collide(sprite1, sprite2, collisionHandler, null, this); - - // sprite3.angle += 0.5; - -} - -function collisionHandler (obj1, obj2) { - - game.stage.backgroundColor = '#992d2d'; - - console.log(obj1.name + ' collided with ' + obj2.name); - -} - -function render() { - - // game.debug.renderSpriteInfo(sprite1, 32, 32); - // game.debug.renderSpriteCollision(sprite1, 32, 400); - - game.debug.renderSpriteCoords(sprite1, 32, 32); - game.debug.renderSpriteCoords(sprite2, 300, 32); - - game.debug.renderCameraInfo(game.camera, 32, 500); - - game.debug.renderSpriteBody(sprite1); - game.debug.renderSpriteBody(sprite2); - game.debug.renderSpriteBody(sprite3); - - game.debug.renderGroupInfo(testGroup, 500, 500); - game.debug.renderPixel(testGroup.x, testGroup.y, 'rgb(255,255,0)'); - -} diff --git a/examples/collision/vertical collision.js b/examples/collision/vertical collision.js index 1d3279ab..79b2a97e 100644 --- a/examples/collision/vertical collision.js +++ b/examples/collision/vertical collision.js @@ -20,20 +20,18 @@ function create() { sprite1.body.velocity.y = 100; // This adjusts the collision body size. - // 100x100 is the new width/height. + // 220x10 is the new width/height. // See the offset bounding box for another example. - sprite1.body.setSize(220, 50, 0, 0); + sprite1.body.setRectangle(220, 10, 0, 0); - sprite2 = game.add.sprite(400, 500, 'mushroom'); + sprite2 = game.add.sprite(400, 450, 'mushroom'); sprite2.name = 'mushroom'; sprite2.body.immovable = true; - // sprite2.body.velocity.x = -100; } function update() { - // object1, object2, collideCallback, processCallback, callbackContext game.physics.collide(sprite1, sprite2, collisionHandler, null, this); } @@ -42,17 +40,11 @@ function collisionHandler (obj1, obj2) { game.stage.backgroundColor = '#992d2d'; - console.log(obj1.name + ' collided with ' + obj2.name); - } function render() { - game.debug.renderSpriteInfo(sprite1, 32, 32); - game.debug.renderSpriteCollision(sprite1, 32, 400); - - game.debug.renderSpriteBody(sprite1); - game.debug.renderSpriteBody(sprite2); + game.debug.renderPhysicsBody(sprite1.body); + game.debug.renderPhysicsBody(sprite2.body); } - diff --git a/examples/debug.php b/examples/debug.php new file mode 100644 index 00000000..0c8f6a9b --- /dev/null +++ b/examples/debug.php @@ -0,0 +1,155 @@ + $value) + { + if (is_array($value) && count($value) > 0) + { + $total += count($value); + } + } + + function dirToArray($dir) { + + $ignore = array('.', '..', '_site', 'assets', 'states', 'book', 'filters'); + $result = array(); + $root = scandir($dir); + $dirs = array_diff($root, $ignore); + + foreach ($dirs as $key => $value) + { + if (is_dir($dir . DIRECTORY_SEPARATOR . $value)) + { + $result[$value] = dirToArray($dir . DIRECTORY_SEPARATOR . $value); + } + else + { + if (substr($value, -3) == '.js') + { + $result[] = $value; + } + } + } + + return $result; + } + + function printJSLinks($section) { + + global $files; + + $output = ""; + + if ($section) + { + $tempFiles = $files[$section]; + } + else + { + $tempFiles = $files; + } + + foreach ($tempFiles as $key => $value) + { + if (is_array($value)) + { + $output .= ""; + $output .= printJSLinks($key); + $output .= ""; + } + else + { + $value2 = substr($value, 0, -3); + $file = urlencode($value); + $output .= ""; + } + } + + return $output; + + } +?> + + + + + phaser + + + + + + +
    + + + + + +

    Debug

    + + + + + + + \ No newline at end of file diff --git a/examples/debug/debug camera.js b/examples/debug/debug camera.js new file mode 100644 index 00000000..8a33c50a --- /dev/null +++ b/examples/debug/debug camera.js @@ -0,0 +1,40 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update:update, render:render }); + +var sprite, spriteB ; +var counter = 0 ; +var step = Math.PI * 2 / 360 ; + + +function preload() { + + // Load images to use as the game sprites + game.load.image('sprite', 'assets/sprites/phaser2.png'); + +} + +function create() { + + // Create sprite and put it in the middle of the stage + sprite = game.add.sprite(0, 0, 'sprite'); + sprite.alpha = 0.5 ; + sprite.x = game.width / 2 ; + sprite.anchor.x = sprite.anchor.y = 0.5 ; + +} + +function update() +{ + // Move sprite up and down smoothly for show + var tStep = Math.sin( counter ) ; + sprite.y = (game.height/2) + tStep * 30 ; + sprite.rotation += Phaser.Math.degToRad( 0.1 * tStep ) ; + counter += step ; +} + +function render() { + + // Camera + game.debug.renderCameraInfo(game.camera, 32, 32); + +} diff --git a/examples/debug/debug display.js b/examples/debug/debug display.js new file mode 100644 index 00000000..6c0a9669 --- /dev/null +++ b/examples/debug/debug display.js @@ -0,0 +1,41 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update:update, render:render }); + +var sprite ; +var counter = 0 ; +var step = Math.PI * 2 / 360 ; + + +function preload() { + + // Load images to use as the game sprites + game.load.image('sprite', 'assets/sprites/phaser2.png'); + +} + +function create() { + + // Create sprite and put it in the middle of the stage + sprite = game.add.sprite(0, 0, 'sprite'); + sprite.alpha = 0.5 ; + sprite.x = game.width / 2 ; + sprite.anchor.x = sprite.anchor.y = 0.5 ; + +} + +function update() +{ + // Move sprite up and down smoothly for show + var tStep = Math.sin( counter ) ; + sprite.y = (game.height/2) + tStep * 30 ; + sprite.rotation += Phaser.Math.degToRad( 0.1 * tStep ) ; + counter += step ; +} + +function render() { + + // Display + game.debug.renderSpriteBounds(sprite); + game.debug.renderSpriteCorners(sprite, true, true); + +} diff --git a/examples/debug/debug draw.js b/examples/debug/debug draw.js new file mode 100644 index 00000000..5c303229 --- /dev/null +++ b/examples/debug/debug draw.js @@ -0,0 +1,18 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { render:render }); + +var rect = new Phaser.Rectangle( 100, 100, 100, 100 ) ; +var circle = new Phaser.Circle( 280, 150, 100 ) ; +var point = new Phaser.Point( 100, 280 ) ; + +function render() { + + // Draw debug tools + game.debug.renderRectangle( rect, 'rgba(255,0,0,1)' ) ; + game.debug.renderCircle( circle, 'rgba(255,255,0,1)' ) ; + game.debug.renderPoint( point, 'rgba(255,255,255,1)' ) ; + game.debug.renderPixel( 200, 280, 'rgba(0,255,255,1)' ) ; + game.debug.renderText( "This is debug text", 100, 380 ); + + +} diff --git a/examples/debug/debug input.js b/examples/debug/debug input.js new file mode 100644 index 00000000..14242a8b --- /dev/null +++ b/examples/debug/debug input.js @@ -0,0 +1,41 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update:update, render:render }); + +var sprite ; +var counter = 0 ; +var step = Math.PI * 2 / 360 ; + +function preload() { + + // Load images to use as the game sprites + game.load.image('sprite', 'assets/sprites/phaser2.png'); + +} + +function create() { + + // Create sprite and put it in the middle of the stage + sprite = game.add.sprite(0, 0, 'sprite'); + sprite.alpha = 0.5 ; + sprite.x = game.width / 2 ; + sprite.anchor.x = sprite.anchor.y = 0.5 ; + sprite.inputEnabled = true ; +} + +function update() +{ + // Move sprite up and down smoothly for show + var tStep = Math.sin( counter ) ; + sprite.y = (game.height/2) + tStep * 30 ; + sprite.rotation += Phaser.Math.degToRad( 0.1 * tStep ) ; + counter += step ; +} + +function render() { + + // Input debug info + game.debug.renderInputInfo(32, 32); + game.debug.renderSpriteInputInfo(sprite, 32, 130); + game.debug.renderPointer( game.input.activePointer ); + +} diff --git a/examples/debug/debug physics.js b/examples/debug/debug physics.js new file mode 100644 index 00000000..01bab7d8 --- /dev/null +++ b/examples/debug/debug physics.js @@ -0,0 +1,53 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update:update, render:render }); + +var sprite, otherSprite ; +var counter = 0 ; +var step = Math.PI * 2 / 360 ; + + +function preload() { + + // Load images to use as the game sprites + game.load.image('sprite', 'assets/sprites/phaser2.png'); + game.load.image('otherSprite', 'assets/sprites/phaser-dude.png'); + +} + +function create() { + + // Create sprite A and put it in the middle of the stage + sprite = game.add.sprite(0, 0, 'sprite'); + sprite.alpha = 0.5 ; + sprite.x = game.width / 2 ; + sprite.anchor.x = sprite.anchor.y = 0.5 ; + + // create sprite B + otherSprite = game.add.sprite(0, 0, 'otherSprite'); + otherSprite.alpha = 0.5 ; + otherSprite.x = (game.width / 2) + 150 ; + otherSprite.y = (game.height / 2) + 150 ; + otherSprite.anchor.x = sprite.anchor.y = 0.5 ; + otherSprite.body.immovable = true ; +} + +function update() +{ + game.physics.collide( sprite, otherSprite ) ; + + // Move sprite up and down smoothly for show + var tStep = Math.sin( counter ) ; + sprite.y = (game.height/2) + tStep * 30 ; + sprite.rotation += Phaser.Math.degToRad( 0.1 * tStep ) ; + counter += step ; +} + +function render() { + + // Physics + game.debug.renderSpriteBody(sprite); + game.debug.renderSpriteCollision(sprite, 32, 32); + + game.debug.renderSpriteBody(otherSprite); + +} diff --git a/examples/debug/debug sprite.js b/examples/debug/debug sprite.js new file mode 100644 index 00000000..4ebfe778 --- /dev/null +++ b/examples/debug/debug sprite.js @@ -0,0 +1,41 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update:update, render:render }); + +var sprite ; +var counter = 0 ; +var step = Math.PI * 2 / 360 ; + + +function preload() { + + // Load images to use as the game sprites + game.load.image('sprite', 'assets/sprites/phaser2.png'); + +} + +function create() { + + // Create sprite and put it in the middle of the stage + sprite = game.add.sprite(0, 0, 'sprite'); + sprite.alpha = 0.5 ; + sprite.x = game.width / 2 ; + sprite.anchor.x = sprite.anchor.y = 0.5 ; +} + +function update() +{ + // Move sprite up and down smoothly for show + var tStep = Math.sin( counter ) ; + sprite.y = (game.height/2) + tStep * 30 ; + sprite.rotation += Phaser.Math.degToRad( 0.1 * tStep ) ; + counter += step ; +} + +function render() { + + // Sprite debug info + game.debug.renderSpriteInfo(sprite, 32, 32); + game.debug.renderLocalTransformInfo(sprite, 32, 160); + game.debug.renderWorldTransformInfo(sprite, 32, 290); + +} diff --git a/examples/display/bitmapdata wobble.js b/examples/display/bitmapdata wobble.js index 53190772..07224ba6 100644 --- a/examples/display/bitmapdata wobble.js +++ b/examples/display/bitmapdata wobble.js @@ -17,7 +17,7 @@ var waveDataCounter; function create() { // Create our BitmapData object at a size of 32x64 - bmd = game.add.bitmapData('ball', 32, 64); + bmd = game.add.bitmapData(32, 64); // And apply it to 100 randomly positioned sprites for (var i = 0; i < 100; i++) @@ -62,7 +62,7 @@ function updateWobblyBall() // Now all the pixel data has been redrawn we render it to the BitmapData object. // In CANVAS mode this doesn't do anything, but on WebGL it pushes the new texture to the GPU. - // If your game is exclusively running under Canvas you ca safely ignore this step. + // If your game is exclusively running under Canvas you can safely ignore this step. bmd.render(); // Cycle through the wave data - this is what causes the image to "undulate" diff --git a/examples/display/fullscreen.js b/examples/display/fullscreen.js index 5f38a7fa..d02dd75c 100644 --- a/examples/display/fullscreen.js +++ b/examples/display/fullscreen.js @@ -13,6 +13,13 @@ function create() { game.stage.backgroundColor = '#e3ed49'; + // Stretch to fill +// game.stage.fullScreenScaleMode = Phaser.StageScaleMode.EXACT_FIT; + // Keep original size +// game.stage.fullScreenScaleMode = Phaser.StageScaleMode.NO_SCALE; + // Maintain aspect ratio + game.stage.fullScreenScaleMode = Phaser.StageScaleMode.SHOW_ALL; + game.input.onDown.add(gofull, this); } diff --git a/examples/display/pixi render texture.js b/examples/display/pixi render texture.js new file mode 100644 index 00000000..0e92b0f6 --- /dev/null +++ b/examples/display/pixi render texture.js @@ -0,0 +1,78 @@ +// Original version by @author Mat Groves http://matgroves.com/ @Doormat23 from the Pixi.js examples +// Ported to Phaser by Richard Davey + +var game = new Phaser.Game(800, 600, Phaser.WEBGL, 'phaser-example', { preload: preload, create: create, update: update }); + +function preload() { + + game.load.image('spin1', 'assets/sprites/spinObj_01.png'); + game.load.image('spin2', 'assets/sprites/spinObj_02.png'); + game.load.image('spin3', 'assets/sprites/spinObj_03.png'); + game.load.image('spin4', 'assets/sprites/spinObj_04.png'); + game.load.image('spin5', 'assets/sprites/spinObj_05.png'); + game.load.image('spin6', 'assets/sprites/spinObj_06.png'); + game.load.image('spin7', 'assets/sprites/spinObj_07.png'); + game.load.image('spin8', 'assets/sprites/spinObj_08.png'); + +} + +var renderTexture; +var renderTexture2; +var currentTexture; +var outputSprite; +var stuffContainer; +var count = 0; + +function create() { + + // create two render textures.. these dynamic textures will be used to draw the scene into itself + renderTexture = game.add.renderTexture('texture1', 800, 600); + renderTexture2 = game.add.renderTexture('textur2e', 800, 600); + currentTexture = renderTexture; + + // create a new sprite that uses the render texture we created above + outputSprite = game.add.sprite(400, 300, currentTexture); + + // align the sprite + outputSprite.anchor.x = 0.5; + outputSprite.anchor.y = 0.5; + + stuffContainer = game.add.group(); + stuffContainer.x = 800/2; + stuffContainer.y = 600/2 + + // now create some items and randomly position them in the stuff container + for (var i = 0; i < 20; i++) + { + var item = stuffContainer.create(Math.random() * 400 - 200, Math.random() * 400 - 200, game.rnd.pick(game.cache.getImageKeys())); + item.anchor.setTo(0.5, 0.5); + } + + // used for spinning! + count = 0; + +} + +function update() { + + stuffContainer.addAll('rotation', 0.1); + + count += 0.01; + + // swap the buffers.. + var temp = renderTexture; + renderTexture = renderTexture2; + renderTexture2 = temp; + + // set the new texture + outputSprite.setTexture(renderTexture); + + // twist this up! + stuffContainer.rotation -= 0.01 + outputSprite.scale.x = outputSprite.scale.y = 1 + Math.sin(count) * 0.2; + + // render the stage to the texture + // the true clears the texture before content is rendered + renderTexture2.renderXY(game.stage.display, 0, 0, true); + +} diff --git a/examples/display/render texture mirror.js b/examples/display/render texture mirror.js index 9517924c..b8331c86 100644 --- a/examples/display/render texture mirror.js +++ b/examples/display/render texture mirror.js @@ -27,9 +27,11 @@ function create() { function update() { - // This time we'll draw the ball sprite twice, in a mirror effect - - texture.renderXY(ball, game.input.activePointer.x, game.input.activePointer.y, false); - texture.renderXY(ball, game.input.activePointer.x, 600 - game.input.activePointer.y, false); + if (!game.input.activePointer.position.isZero()) + { + // This time we'll draw the ball sprite twice, in a mirror effect + texture.renderXY(ball, game.input.activePointer.x, game.input.activePointer.y, false, true); + texture.renderXY(ball, game.input.activePointer.x, 600 - game.input.activePointer.y, false, true); + } } diff --git a/examples/display/render texture starfield.js b/examples/display/render texture starfield.js index 43ab5186..70df1ffe 100644 --- a/examples/display/render texture starfield.js +++ b/examples/display/render texture starfield.js @@ -1,5 +1,5 @@ -var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update }); function preload() { @@ -69,12 +69,12 @@ function update() { if (i == 0 || i == 100 || i == 200) { // If it's the first star of the layer then we clear the texture - stars[i].texture.renderXY(star, stars[i].x, stars[i].y, true); + stars[i].texture.renderXY(star, stars[i].x, stars[i].y, true, true); } else { // Otherwise just draw the star sprite where we need it - stars[i].texture.renderXY(star, stars[i].x, stars[i].y, false); + stars[i].texture.renderXY(star, stars[i].x, stars[i].y, false, true); } } diff --git a/examples/display/render texture trail.js b/examples/display/render texture trail.js index b0c114f8..99b25dba 100644 --- a/examples/display/render texture trail.js +++ b/examples/display/render texture trail.js @@ -27,8 +27,12 @@ function create() { function update() { - // Here we draw the mushroom sprite to the renderTexture at the pointer coordinates. - // The 'false' parameter at the end tells it not to clear itself, causing the trail effect you see. - texture.render(mushroom, game.input.activePointer.position, false); + if (!game.input.activePointer.position.isZero()) + { + // Here we draw the mushroom sprite to the renderTexture at the pointer coordinates. + // The 'false' parameter 2nd from the end tells it not to clear itself, causing the trail effect you see. + // The final 'true' parameter tells it to render sprites even with visible false set. + texture.render(mushroom, game.input.activePointer.position, false, true); + } } diff --git a/examples/games/breakout.js b/examples/games/breakout.js index 6c4c6962..70500aa0 100644 --- a/examples/games/breakout.js +++ b/examples/games/breakout.js @@ -25,8 +25,8 @@ var s; function create() { - // We do this so the ball can still rebound with the world bounds, but it will look like it has gone off the bottom of the screen - game.world.height = 620; + // This tells the world to include walls on the left, right and top, but not the bottom - so the ball can 'fall' away. + game.physics.setBoundsToWorld(true, true, true, false); s = game.add.tileSprite(0, 0, 800, 600, 'starfield'); @@ -54,6 +54,7 @@ function create() { ball.body.collideWorldBounds = true; ball.body.bounce.setTo(1, 1); ball.animations.add('spin', [ 'ball_1.png', 'ball_2.png', 'ball_3.png', 'ball_4.png', 'ball_5.png' ], 50, true, false); + ball.events.onOutOfBounds.add(ballLost, this); scoreText = game.add.text(32, 550, 'score: 0', { font: "20px Arial", fill: "#ffffff", align: "left" }); livesText = game.add.text(680, 550, 'lives: 3', { font: "20px Arial", fill: "#ffffff", align: "left" }); @@ -90,12 +91,6 @@ function update () { game.physics.collide(ball, bricks, ballHitBrick, null, this); } - // Out? - if (ball.y > 600 && ballOnPaddle == false) - { - ballLost(); - } - } function releaseBall () { @@ -115,7 +110,7 @@ function ballLost () { lives--; - if (lives == 0) + if (lives === 0) { gameOver(); } @@ -123,9 +118,9 @@ function ballLost () { { livesText.content = 'lives: ' + lives; ballOnPaddle = true; - ball.body.velocity.setTo(0, 0); ball.x = paddle.x + 16; ball.y = paddle.y - 16; + ball.body.reset(); ball.animations.stop(); } @@ -135,7 +130,7 @@ function gameOver () { ball.body.velocity.setTo(0, 0); - introText.content = "Game Over!"; + introText.content = 'Game Over!'; introText.visible = true; } @@ -154,7 +149,7 @@ function ballHitBrick (_ball, _brick) { // New level starts score += 1000; scoreText.content = 'score: ' + score; - introText = '- Next Level -'; + introText.content = '- Next Level -'; // Let's move the ball back to the paddle ballOnPaddle = true; diff --git a/examples/games/invaders.js b/examples/games/invaders.js index f9e0d216..36f64716 100644 --- a/examples/games/invaders.js +++ b/examples/games/invaders.js @@ -28,13 +28,13 @@ var lives; var enemyBullet; var firingTimer = 0; var stateText; +var livingEnemies = []; function create() { // The scrolling starfield background starfield = game.add.tileSprite(0, 0, 800, 600, 'starfield'); - // Our bullet group bullets = game.add.group(); bullets.createMultiple(30, 'bullet'); @@ -155,8 +155,8 @@ function update() { } // Run collision - game.physics.collide(bullets, aliens, collisionHandler, null, this); - game.physics.collide(enemyBullets, player, enemyHitsPlayer, null, this); + game.physics.overlap(bullets, aliens, collisionHandler, null, this); + game.physics.overlap(enemyBullets, player, enemyHitsPlayer, null, this); } @@ -167,8 +167,8 @@ function collisionHandler (bullet, alien) { alien.kill(); // Increase the score - score+=20; - scoreText.content=scoreString+score; + score += 20; + scoreText.content = scoreString + score; // And create an explosion :) var explosion = explosions.getFirstDead(); @@ -226,7 +226,7 @@ function enemyFires () { // Grab the first bullet we can from the pool enemyBullet = enemyBullets.getFirstExists(false); - var livingEnemies=[]; + livingEnemies.length=0; aliens.forEachAlive(function(alien){ diff --git a/examples/games/matching pairs.js b/examples/games/matching pairs.js new file mode 100644 index 00000000..2d35abd6 --- /dev/null +++ b/examples/games/matching pairs.js @@ -0,0 +1,223 @@ +// mods by Patrick OReilly +// Twitter: @pato_reilly Web: http://patricko.byethost9.com + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.tilemap('matching', 'assets/maps/phaser_tiles.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('tiles', 'assets/tiles/phaser_tiles.png'); + +} + +var timeCheck = 0; +var flipFlag = false; + +var startList = new Array(); +var squareList = new Array(); + +var masterCounter = 0; +var squareCounter = 0; +var square1Num; +var square2Num; +var savedSquareX1; +var savedSquareY1; +var savedSquareX2; +var savedSquareY2; + +var map; +var tileset; +var layer; + +var marker; +var currentTile; +var currentTilePosition; + +var tileBack = 25; +var timesUp = '+'; +var youWin = '+'; + +function create() { + + map = game.add.tilemap('matching'); + + // tileset = game.add.tileset('tiles'); + + // layer = game.add.tilemapLayer(0, 0, 600, 600, tileset, map, 0); + + marker = game.add.graphics(); + marker.lineStyle(2, 0x00FF00, 1); + marker.drawRect(0, 0, 100, 100); + + randomizeTiles(); + +} + +function update() { + + countDownTimer(); + + if (layer.getTileX(game.input.activePointer.worldX) <= 5) // to prevent the marker from going out of bounds + { + marker.x = layer.getTileX(game.input.activePointer.worldX) * 100; + marker.y = layer.getTileY(game.input.activePointer.worldY) * 100; + } + + if (flipFlag == true) + { + if (game.time.now - timeCheck > 1000) + { + flipBack(); + } + } + else + { + processClick(); + } + +} + +function countDownTimer() { + + var timeLimit = 120; + + myTime = game.time.now; + mySeconds = parseInt(myTime / 1000); + myCountdownSeconds = timeLimit - mySeconds; + + if (myCountdownSeconds <= 0) + { + // time is up + timesUp = 'Time is up!'; + } + +} + +function processClick() { + + currentTile = map.getTile(layer.getTileX(marker.x), layer.getTileY(marker.y)); + currentTilePosition = ((layer.getTileY(game.input.activePointer.worldY) + 1) * 6) - (6 - (layer.getTileX(game.input.activePointer.worldX) + 1)); + + if (game.input.mousePointer.isDown) + { + // check to make sure the tile is not already flipped + if (currentTile == tileBack) + { + // get the corresponding item out of squareList + currentNum = squareList[currentTilePosition - 1]; + flipOver(); + squareCounter++; + + // is the second tile of pair flipped? + if (squareCounter == 2) + { + // reset squareCounter + squareCounter = 0; + square2Num = currentNum; + + // check for match + if (square1Num == square2Num) + { + masterCounter++; + + if (masterCounter == 18) + { + // go "win" + youWin = 'Got them all!'; + } + } + else + { + savedSquareX2 = layer.getTileX(marker.x); + savedSquareY2 = layer.getTileY(marker.y); + flipFlag = true; + timeCheck = game.time.now; + } + } + else + { + savedSquareX1 = layer.getTileX(marker.x); + savedSquareY1 = layer.getTileY(marker.y); + square1Num = currentNum; + } + } + } +} + +function flipOver() { + + map.putTile(currentNum, layer.getTileX(marker.x), layer.getTileY(marker.y)); +} + +function flipBack() { + + flipFlag = false; + + map.putTile(tileBack, savedSquareX1, savedSquareY1); + map.putTile(tileBack, savedSquareX2, savedSquareY2); + +} + +function randomizeTiles() { + + for (num = 1; num <= 18; num++) + { + startList.push(num); + } + + for (num = 1; num <= 18; num++) + { + startList.push(num); + } + + // for debugging + myString1 = startList.toString(); + + // randomize squareList + for (i = 1; i <= 36; i++) + { + randomPosition = game.rnd.integerInRange(0, startList.length); + + thisNumber = startList[randomPosition]; + + squareList.push(thisNumber); + + a = startList.indexOf(thisNumber); + + startList.splice(a, 1); + } + + // for debugging + myString2 = squareList.toString(); + + for (col = 0; col < 6; col++) + { + for (row = 0; row < 6; row++) + { + map.putTile(tileBack, col, row); + } + } +} + +function getHiddenTile() { + + thisTile = squareList[currentTilePosition - 1]; + return thisTile; +} + +function render() { + + game.debug.renderText(timesUp, 620, 208, 'rgb(0,255,0)'); + game.debug.renderText(youWin, 620, 240, 'rgb(0,255,0)'); + + game.debug.renderText('Time: ' + myCountdownSeconds, 620, 15, 'rgb(0,255,0)'); + game.debug.renderText('Matched Pairs: ' + masterCounter, 620, 304, 'rgb(0,0,255)'); + game.debug.renderText('Tile: ' + map.getTile(layer.getTileX(marker.x), layer.getTileY(marker.y)), 620, 48, 'rgb(255,0,0)'); + + game.debug.renderText('LayerX: ' + layer.getTileX(marker.x), 620, 80, 'rgb(255,0,0)'); + game.debug.renderText('LayerY: ' + layer.getTileY(marker.y), 620, 112, 'rgb(255,0,0)'); + + game.debug.renderText('Tile Position: ' + currentTilePosition, 620, 144, 'rgb(255,0,0)'); + game.debug.renderText('Hidden Tile: ' + getHiddenTile(), 620, 176, 'rgb(255,0,0)'); + +} diff --git a/examples/games/simon.js b/examples/games/simon.js new file mode 100644 index 00000000..59bc4979 --- /dev/null +++ b/examples/games/simon.js @@ -0,0 +1,214 @@ +// mods by Patrick OReilly +// Twitter: @pato_reilly Web: http://patricko.byethost9.com + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.spritesheet('item', 'assets/buttons/number-buttons.png', 160, 160); +} + +var simon; +var N = 1; +var userCount = 0; +var currentCount = 0; +var sequenceCount = 16; +var sequenceList = []; +var simonSez = false; +var timeCheck; +var litSquare; +var winner; +var loser; +var intro; + +function create() { + + simon = game.add.group(); + var item; + + for (var i = 0; i < 3; i++) + { + item = simon.create(150 + 168 * i, 150, 'item', i); + // Enable input. + item.input.start(0, true); + item.events.onInputDown.add(select); + item.events.onInputUp.add(release); + item.events.onInputOut.add(moveOff); + simon.getAt(i).alpha = 0; + } + + for (var i = 0; i < 3; i++) + { + item = simon.create(150 + 168 * i, 318, 'item', i + 3); + // Enable input. + item.input.start(0, true); + item.events.onInputDown.add(select); + item.events.onInputUp.add(release); + item.events.onInputOut.add(moveOff); + simon.getAt(i + 3).alpha = 0; + } + + introTween(); + setUp(); + setTimeout(function(){simonSequence(); intro = false;}, 5000); + +} + +function restart() { + + N = 1; + userCount = 0; + currentCount = 0; + sequenceList = []; + winner = false; + loser = false; + introTween(); + setUp(); + setTimeout(function(){simonSequence(); intro=false;}, 5000); + +} + +function introTween() { + + intro = true; + + for (var i = 0; i < 6; i++) + { + game.add.tween(simon.getAt(i)).to( { alpha: 1 }, 500, Phaser.Easing.Linear.None, true, 0, 4, true).to( { alpha: .25 }, 500, Phaser.Easing.Linear.None, true); + } + +} + +function update() { + + if (simonSez) + { + if (game.time.now - timeCheck >700-N*40) + { + simon.getAt(litSquare).alpha = .25; + game.paused = true; + + setTimeout(function() + { + if ( currentCount< N) + { + game.paused = false; + simonSequence(); + } + else + { + simonSez = false; + game.paused = false; + } + }, 400 - N * 20); + } + } +} + +function playerSequence(selected) { + + correctSquare = sequenceList[userCount]; + userCount++; + thisSquare = simon.getIndex(selected); + + if (thisSquare == correctSquare) + { + if (userCount == N) + { + if (N == sequenceCount) + { + winner = true; + setTimeout(function(){restart();}, 3000); + } + else + { + userCount = 0; + currentCount = 0; + N++; + simonSez = true; + } + } + } + else + { + loser = true; + setTimeout(function(){restart();}, 3000); + } + +} + +function simonSequence () { + + simonSez = true; + litSquare = sequenceList[currentCount]; + simon.getAt(litSquare).alpha = 1; + timeCheck = game.time.now; + currentCount++; + +} + +function setUp() { + + for (var i = 0; i < sequenceCount; i++) + { + thisSquare = game.rnd.integerInRange(0,6); + sequenceList.push(thisSquare); + } + +} + +function select(item, pointer) { + + if (!simonSez && !intro && !loser && !winner) + { + item.alpha = 1; + } + +} + +function release(item, pointer) { + + if (!simonSez && !intro && !loser && !winner) + { + item.alpha = .25; + playerSequence(item); + } +} + +function moveOff(item, pointer) { + + if (!simonSez && !intro && !loser && !winner) + { + item.alpha = .25; + } + +} + +function render() { + + if (!intro) + { + if (simonSez) + { + game.debug.renderText('Simon Sez', 360, 96, 'rgb(255,0,0)'); + } + else + { + game.debug.renderText('Your Turn', 360, 96, 'rgb(0,255,0)'); + } + } + else + { + game.debug.renderText('Get Ready', 360, 96, 'rgb(0,0,255)'); + } + + if (winner) + { + game.debug.renderText('You Win!', 360, 32, 'rgb(0,0,255)'); + } + else if (loser) + { + game.debug.renderText('You Lose!', 360, 32, 'rgb(0,0,255)'); + } + +} diff --git a/examples/games/starstruck.js b/examples/games/starstruck.js index 5ddf9526..059d0473 100644 --- a/examples/games/starstruck.js +++ b/examples/games/starstruck.js @@ -4,7 +4,7 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: function preload() { game.load.tilemap('level1', 'assets/games/starstruck/level1.json', null, Phaser.Tilemap.TILED_JSON); - game.load.tileset('tiles', 'assets/games/starstruck/tiles-1.png', 16, 16); + game.load.image('tiles-1', 'assets/games/starstruck/tiles-1.png'); game.load.spritesheet('dude', 'assets/games/starstruck/dude.png', 32, 48); game.load.spritesheet('droid', 'assets/games/starstruck/droid.png', 32, 32); game.load.image('starSmall', 'assets/games/starstruck/star.png'); @@ -32,21 +32,28 @@ function create() { map = game.add.tilemap('level1'); - tileset = game.add.tileset('tiles'); + map.addTilesetImage('tiles-1'); - tileset.setCollisionRange(0, tileset.total - 1, true, true, true, true); + map.setCollisionByExclusion([ 13, 14, 15, 16, 46, 47, 48, 49, 50, 51 ]); - tileset.setCollisionRange(12, 16, false, false, false, false); - tileset.setCollisionRange(46, 50, false, false, false, false); + layer = map.createLayer('Tile Layer 1'); + + // Un-comment this on to see the collision tiles + // layer.debug = true; - layer = game.add.tilemapLayer(0, 0, 800, 600, tileset, map, 0); layer.resizeWorld(); + game.physics.gravity.y = 250; + game.physics.setBoundsToWorld(); + player = game.add.sprite(32, 32, 'dude'); player.body.bounce.y = 0.2; + player.body.minVelocity.y = 5; player.body.collideWorldBounds = true; - player.body.gravity.y = 6; - player.body.setSize(16, 32, 8, 16); + player.body.setRectangle(16, 32, 8, 16); + + // Un-comment this on to see the body collision areas / data + // player.debug = true; player.animations.add('left', [0, 1, 2, 3], 10, true); player.animations.add('turn', [4], 20, true); @@ -104,19 +111,20 @@ function update() { } } - if (jumpButton.isDown && player.body.touching.down && game.time.now > jumpTimer) + if (jumpButton.isDown && player.body.onFloor() && game.time.now > jumpTimer) { player.body.velocity.y = -250; jumpTimer = game.time.now + 750; } - // player.scale.x += 0.001; - // player.scale.y += 0.001; - } function render () { - game.debug.renderSpriteBody(player); + if (player.debug) + { + game.debug.renderPhysicsBody(player.body); + game.debug.renderBodyInfo(player, 16, 24); + } } diff --git a/examples/games/tanks.js b/examples/games/tanks.js index 010c58a3..006b6b76 100644 --- a/examples/games/tanks.js +++ b/examples/games/tanks.js @@ -21,7 +21,7 @@ EnemyTank = function (index, game, player, bullets) { this.turret.anchor.setTo(0.3, 0.5); this.tank.name = index.toString(); - this.tank.body.immovable = true; + this.tank.body.immovable = false; this.tank.body.collideWorldBounds = true; this.tank.body.bounce.setTo(1, 1); @@ -77,7 +77,6 @@ EnemyTank.prototype.update = function() { }; var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render }); -// var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); function preload () { @@ -122,10 +121,9 @@ function create () { tank = game.add.sprite(0, 0, 'tank', 'tank1'); tank.anchor.setTo(0.5, 0.5); tank.animations.add('move', ['tank1', 'tank2', 'tank3', 'tank4', 'tank5', 'tank6'], 20, true); - // tank.play('move'); // This will force it to decelerate and limit its speed - tank.body.drag.setTo(200, 200); + tank.body.linearDamping = 0.2; tank.body.maxVelocity.setTo(400, 400); tank.body.collideWorldBounds = true; @@ -194,15 +192,15 @@ function removeLogo () { function update () { - game.physics.collide(enemyBullets, tank, bulletHitPlayer, null, this); + game.physics.overlap(enemyBullets, tank, bulletHitPlayer, null, this); for (var i = 0; i < enemies.length; i++) { if (enemies[i].alive) { - enemies[i].update(); game.physics.collide(tank, enemies[i].tank); - game.physics.collide(bullets, enemies[i].tank, bulletHitEnemy, null, this); + game.physics.overlap(bullets, enemies[i].tank, bulletHitEnemy, null, this); + enemies[i].update(); } } diff --git a/examples/geometry/line intersection.js b/examples/geometry/line intersection.js new file mode 100644 index 00000000..f6134f80 --- /dev/null +++ b/examples/geometry/line intersection.js @@ -0,0 +1,80 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.spritesheet('balls', 'assets/sprites/balls.png', 17, 17); + +} + +var handle1; +var handle2; +var handle3; +var handle4; + +var line1; +var line2; + +function create() { + + game.stage.backgroundColor = '#124184'; + + handle1 = game.add.sprite(100, 200, 'balls', 0); + handle1.inputEnabled = true; + handle1.input.enableDrag(true); + + handle2 = game.add.sprite(400, 300, 'balls', 0); + handle2.inputEnabled = true; + handle2.input.enableDrag(true); + + handle3 = game.add.sprite(200, 400, 'balls', 1); + handle3.inputEnabled = true; + handle3.input.enableDrag(true); + + handle4 = game.add.sprite(500, 500, 'balls', 1); + handle4.inputEnabled = true; + handle4.input.enableDrag(true); + + line1 = new Phaser.Line(handle1.x, handle1.y, handle2.x, handle2.y); + line2 = new Phaser.Line(handle3.x, handle3.y, handle4.x, handle4.y); + +} + +var c = 'rgb(255,255,255)'; +var p = new Phaser.Point(); + +function update() { + + line1.fromSprite(handle1, handle2, true); + line2.fromSprite(handle3, handle4, true); + + p = line1.intersects(line2, true); + + if (p) + { + c = 'rgb(0,255,0)'; + } + else + { + c = 'rgb(255,255,255)'; + } + +} + +function render() { + + game.debug.renderLine(line1, c); + game.debug.renderLine(line2, c); + + game.debug.renderLineInfo(line1, 32, 32); + game.debug.renderLineInfo(line2, 32, 100); + + if (p) + { + game.context.fillStyle = 'rgb(255,0,255)'; + game.context.fillRect(p.x - 2, p.y - 2, 5, 5); + } + + game.debug.renderText("Drag the handles", 32, 550); + +} \ No newline at end of file diff --git a/examples/geometry/line.js b/examples/geometry/line.js index 61b3f502..70a71706 100644 --- a/examples/geometry/line.js +++ b/examples/geometry/line.js @@ -1,17 +1,44 @@ -var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { create: create }); +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.spritesheet('balls', 'assets/sprites/balls.png', 17, 17); + +} + +var handle1; +var handle2; + +var line1; function create() { - var graphics = game.add.graphics(50,50); + game.stage.backgroundColor = '#124184'; - // set a fill and line style - graphics.beginFill(0xFF0000); - graphics.lineStyle(10, 0xFF0000, 1); - - // draw a shape - graphics.moveTo(50,50); - graphics.lineTo(250, 50); - graphics.endFill(); + handle1 = game.add.sprite(100, 200, 'balls', 0); + handle1.inputEnabled = true; + handle1.input.enableDrag(true); + + handle2 = game.add.sprite(400, 300, 'balls', 0); + handle2.inputEnabled = true; + handle2.input.enableDrag(true); + + line1 = new Phaser.Line(handle1.x, handle1.y, handle2.x, handle2.y); } + +function update() { + + line1.fromSprite(handle1, handle2, true); + +} + +function render() { + + game.debug.renderLine(line1); + game.debug.renderLineInfo(line1, 32, 32); + + game.debug.renderText("Drag the handles", 32, 550); + +} \ No newline at end of file diff --git a/examples/groups/bring a group to top.js b/examples/groups/bring a group to top.js index 2a67bf2b..2365053c 100644 --- a/examples/groups/bring a group to top.js +++ b/examples/groups/bring a group to top.js @@ -31,7 +31,6 @@ function create() { // Now let's create some random sprites and enable them all for drag and 'bring to top' for (var i = 0; i < 10; i++) { - var tempSprite = game.add.sprite(game.stage.randomX, game.stage.randomY, 'atari1'); tempSprite.name = 'atari' + i; diff --git a/examples/groups/call all animations.js b/examples/groups/call all animations.js new file mode 100644 index 00000000..e93a7bc0 --- /dev/null +++ b/examples/groups/call all animations.js @@ -0,0 +1,29 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create }); + +function preload() { + + game.load.spritesheet('coin', 'assets/sprites/coin.png', 32, 32); + +} + +var coins; + +function create() { + + // Here we create our coins group + coins = game.add.group(); + + // Now let's add 50 coins into it + for (var i = 0; i < 50; i++) + { + coins.create(game.world.randomX, game.world.randomY, 'coin', 0); + } + + // Now using the power of callAll we can add the same animation to all coins in the group: + coins.callAll('animations.add', 'animations', 'spin', [0, 1, 2, 3, 4, 5], 10, true); + + // And play them + coins.callAll('animations.play', 'animations', 'spin'); + +} diff --git a/examples/groups/call all.js b/examples/groups/call all.js index ac7d1418..250d6fa0 100644 --- a/examples/groups/call all.js +++ b/examples/groups/call all.js @@ -47,6 +47,7 @@ function reviveAll() { function render() { - game.debug.renderText('Tap or click an item to kill it, and press the revive button to revive them all.', 160, 500); + game.debug.renderText('Tap or click an item to kill it', 160, 500); + game.debug.renderText('Press the Revive button to revive them all.', 160, 520); } diff --git a/examples/groups/create group.js b/examples/groups/create group.js index 81af43d2..af17185f 100644 --- a/examples/groups/create group.js +++ b/examples/groups/create group.js @@ -7,30 +7,20 @@ var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: p } -var firstGroup; +var yourGroup; function create() { // Here we'll create a new Group - firstGroup = game.add.group(); + yourGroup = game.add.group(); - // And add some sprites to it + // And add 10 sprites to it for (var i = 0; i < 10; i++) { - // Create a new sprite at a random screen location - var newSprite = new Phaser.Sprite(game, game.stage.randomX, game.stage.randomY, 'sonic'); - - // This set-ups a listener for the event, view your console.log output to see the result - newSprite.events.onAddedToGroup.add(logGroupAdd); - - // Add the sprite to the Group - firstGroup.add(newSprite); + // Create a new sprite at a random world location + yourGroup.create(game.world.randomX, game.world.randomY, 'sonic'); } -} - -function logGroupAdd(sprite, group) { - - console.log('Sprite added to Group', group.ID, 'at z-index:', group.getIndex(sprite)); + // Each sprite is now a member of yourGroup } diff --git a/examples/groups/depth sort.js b/examples/groups/depth sort.js index fc7f319f..05b74511 100644 --- a/examples/groups/depth sort.js +++ b/examples/groups/depth sort.js @@ -3,9 +3,9 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: function preload() { game.load.image('phaser', 'assets/sprites/phaser-dude.png'); - game.load.tilemap('desert', 'assets/maps/burd.json', null, Phaser.Tilemap.TILED_JSON); - game.load.tileset('tiles', 'assets/maps/ground_1x1.png', 32, 32); - game.load.spritesheet('trees', 'assets/maps/walls_1x2.png', 32, 64); + game.load.tilemap('desert', 'assets/tilemaps/maps/depthsort.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png'); + game.load.spritesheet('trees', 'assets/tilemaps/tiles/walls_1x2.png', 32, 64); } @@ -22,8 +22,12 @@ function create() { // Create our tilemap to walk around map = game.add.tilemap('desert'); - tileset = game.add.tileset('tiles'); - layer = game.add.tilemapLayer(0, 0, 800, 600, tileset, map, 0); + + map.addTilesetImage('ground_1x1'); + + layer = map.createLayer('Tile Layer 1'); + + layer.resizeWorld(); // This group will hold the main player + all the tree sprites to depth sort against group = game.add.group(); @@ -51,27 +55,27 @@ function update() { if (cursors.left.isDown) { - sprite.body.velocity.x = -200; + sprite.body.velocity.x = -150; } else if (cursors.right.isDown) { - sprite.body.velocity.x = 200; + sprite.body.velocity.x = 150; } if (cursors.up.isDown) { - sprite.body.velocity.y = -200; + sprite.body.velocity.y = -150; } else if (cursors.down.isDown) { - sprite.body.velocity.y = 200; + sprite.body.velocity.y = 150; } if (sprite.y !== oldY) { // Group.sort() is an expensive operation // You really want to minimise how often it is called as much as possible. - // So this little check helps at least, but if you can do it even less than this. + // So this little check helps at least, but if you can, do it even less than this. group.sort(); oldY = sprite.y; } diff --git a/examples/groups/display order.js b/examples/groups/display order.js index f9ae1c13..dddec864 100644 --- a/examples/groups/display order.js +++ b/examples/groups/display order.js @@ -20,7 +20,8 @@ function create() { card = items.create(240, 80, 'card'); items.create(280, 100, 'atari2'); - game.input.onTap.addOnce(removeCard, this);// obviously the event can be fired only once + // This event will be fired only once + game.input.onTap.addOnce(removeCard, this); } @@ -35,9 +36,9 @@ function removeCard() { function replaceCard() { - // And bring it back to life again - I assume it will render in the same place as before? - var bob = items.getFirstDead(); + // And bring it back to life again. It will render in the same place as before? + var deadCard = items.getFirstDead(); - bob.revive(); + deadCard.revive(); } diff --git a/examples/groups/extending a group.js b/examples/groups/extending a group.js index cd5fb896..343c9ce3 100644 --- a/examples/groups/extending a group.js +++ b/examples/groups/extending a group.js @@ -1,49 +1,45 @@ -window.onload = function() { +// Here is a custom group +// It will automatically create 30 sprites of the given image when created. - // Here is a custom group - // It will automatically create 30 sprites of the given image when created. +MonsterGroup = function (game, image, action) { - MonsterGroup = function (game, image, action) { + Phaser.Group.call(this, game); - Phaser.Group.call(this, game); + for (var i = 0; i < 30; i++) + { + var sprite = this.create(game.world.randomX, game.world.randomY, image); - for (var i = 0; i < 30; i++) + if (action == 'bounce') { - var sprite = this.create(game.world.randomX, game.world.randomY, image); - - if (action == 'bounce') - { - game.add.tween(sprite).to({ y: sprite.y - 100 }, 2000, Phaser.Easing.Elastic.Out, true, 0, 1000, true); - } - else if (action == 'slide') - { - game.add.tween(sprite).to({ x: sprite.x + 200 }, 4000, Phaser.Easing.Elastic.Out, true, 0, 1000, true); - } - + game.add.tween(sprite).to({ y: sprite.y - 100 }, 2000, Phaser.Easing.Elastic.Out, true, 0, 1000, true); + } + else if (action == 'slide') + { + game.add.tween(sprite).to({ x: sprite.x + 200 }, 4000, Phaser.Easing.Elastic.Out, true, 0, 1000, true); } - }; - - MonsterGroup.prototype = Object.create(Phaser.Group.prototype); - MonsterGroup.prototype.constructor = MonsterGroup; - - var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create }); - - var customGroup1; - var customGroup2; - - function preload() { - - game.load.image('ufo', 'assets/sprites/ufo.png'); - game.load.image('baddie', 'assets/sprites/space-baddie.png'); - } - function create() { +}; - customGroup1 = new MonsterGroup(game, 'ufo', 'bounce'); - customGroup2 = new MonsterGroup(game, 'baddie', 'slide'); +MonsterGroup.prototype = Object.create(Phaser.Group.prototype); +MonsterGroup.prototype.constructor = MonsterGroup; - } +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create }); -}(); +var customGroup1; +var customGroup2; + +function preload() { + + game.load.image('ufo', 'assets/sprites/ufo.png'); + game.load.image('baddie', 'assets/sprites/space-baddie.png'); + +} + +function create() { + + customGroup1 = new MonsterGroup(game, 'ufo', 'bounce'); + customGroup2 = new MonsterGroup(game, 'baddie', 'slide'); + +} diff --git a/examples/groups/for each.js b/examples/groups/for each.js index 705422d3..0e6e177b 100644 --- a/examples/groups/for each.js +++ b/examples/groups/for each.js @@ -1,7 +1,7 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); -var baseAlphaIncSpeed= 0.006; +var baseAlphaIncSpeed = 0.006; function preload() { game.load.spritesheet('item', 'assets/buttons/number-buttons-90x90.png', 90, 90); diff --git a/examples/groups/group transform - rotate.js b/examples/groups/group transform - rotate.js index e310ee5c..c307d247 100644 --- a/examples/groups/group transform - rotate.js +++ b/examples/groups/group transform - rotate.js @@ -2,12 +2,6 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); var robot; -var eye; -var body; -var leftArm; -var rightArm; -var leftLeg; -var rightLeg; function preload() { @@ -26,20 +20,25 @@ function create() { // Robot itself, you can subclass group class in a real game. robot = game.add.group(); + robot.x = 300; + robot.y = 200; + + robot.pivot.x = 300; + robot.pivot.y = 300; + // Robot components. - leftArm = robot.create(90, 175, 'arm-l'); - rightArm = robot.create(549, 175, 'arm-r'); - leftLeg = robot.create(270, 325, 'leg-l'); - rightLeg = robot.create(410, 325, 'leg-r'); - body = robot.create(219, 32, 'body'); - eye = robot.create(335, 173,'eye'); + robot.create(90, 175, 'arm-l'); + robot.create(549, 175, 'arm-r'); + robot.create(270, 325, 'leg-l'); + robot.create(410, 325, 'leg-r'); + robot.create(219, 32, 'body'); + robot.create(335, 173,'eye'); } function update() { - // Change parent's rotation to change all the childs. - robot.angle += 2; + robot.rotation += 0.02; } diff --git a/examples/groups/group transform.js b/examples/groups/group transform.js index 07c3cec4..5860e4c9 100644 --- a/examples/groups/group transform.js +++ b/examples/groups/group transform.js @@ -2,12 +2,6 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, render: render }); var robot; -var eye; -var body; -var leftArm; -var rightArm; -var leftLeg; -var rightLeg; function preload() { @@ -22,44 +16,31 @@ function preload() { function create() { + game.stage.backgroundColor = '#124184'; + // Use groups of sprites to create a big robot. // Robot itself, you can subclass group class in a real game. robot = game.add.group(); // Robot components. - leftArm = robot.create(90, 175, 'arm-l'); - rightArm = robot.create(549, 175, 'arm-r'); - leftLeg = robot.create(270, 325, 'leg-l'); - rightLeg = robot.create(410, 325, 'leg-r'); - body = robot.create(219, 32, 'body'); - eye = robot.create(335, 173,'eye'); + robot.create(90, 175, 'arm-l'); + robot.create(549, 175, 'arm-r'); + robot.create(270, 325, 'leg-l'); + robot.create(410, 325, 'leg-r'); + robot.create(219, 32, 'body'); + robot.create(335, 173,'eye'); - leftArm.input.start(0, false, true); - leftArm.input.enableDrag(); - rightArm.input.start(0, false, true); - rightArm.input.enableDrag(); - leftLeg.input.start(0, false, true); - leftLeg.input.enableDrag(); - rightLeg.input.start(0, false, true); - rightLeg.input.enableDrag(); - body.input.start(0, false, true); - body.input.enableDrag(); - eye.input.start(0, false, true); - eye.input.enableDrag(); + // Make them all input enabled + robot.setAll('inputEnabled', true); + + // And allow them all to be dragged + robot.callAll('input.enableDrag', 'input'); } function render() { - game.debug.renderSpriteInfo(leftArm, 32, 30); - game.debug.renderSpriteInfo(rightArm, 32, 180); - game.debug.renderSpriteInfo(leftLeg, 32, 325); - game.debug.renderSpriteInfo(rightLeg, 32, 470); - game.debug.renderSpriteInfo(rightLeg, 450, 30); - game.debug.renderSpriteInfo(rightLeg, 450, 180); - - game.debug.renderText('The robot is a group and every component is a sprite.', 240, 580); - game.debug.renderText('Drag each part to re-position them. ', 288, 592); + game.debug.renderText('The robot is a group and every component is a sprite.', 16, 20); + game.debug.renderText('Drag parts to re-position them. ', 16, 40); } - diff --git a/examples/groups/nested groups.js b/examples/groups/nested groups.js new file mode 100644 index 00000000..c204b9f5 --- /dev/null +++ b/examples/groups/nested groups.js @@ -0,0 +1,40 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); + +function preload() { + + game.load.image('ball', 'assets/sprites/pangball.png'); + game.load.image('arrow', 'assets/sprites/asteroids_ship.png'); + +} + +var ballsGroup; +var shipsGroup; + +function create() { + + ballsGroup = game.add.group(); + shipsGroup = game.add.group(); + + for (var i = 0; i < 20; i++) + { + // Create some randomly placed sprites in both Groups + ballsGroup.create(game.rnd.integerInRange(0, 128), game.world.randomY, 'ball'); + shipsGroup.create(game.rnd.integerInRange(0, 128), game.world.randomY, 'arrow'); + } + + // Now make the ships group a child of the balls group - so anything that happens to the balls group + // will happen to the ships group too + ballsGroup.add(shipsGroup); + +} + +function update() { + + ballsGroup.x += 0.1; + + // Because shipsGroup is a child of ballsGroup it has already been moved 0.1px by the line above + // So the following line of code will make it appear to move twice as fast as ballsGroup + shipsGroup.x += 0.1; + +} diff --git a/examples/index.html b/examples/index.html index e6d47fa1..6f8c1fc5 100644 --- a/examples/index.html +++ b/examples/index.html @@ -12,7 +12,7 @@
    - Phaser Version: 1.1.3 + Phaser Version: 1.1.4 New version:
    @@ -24,7 +24,7 @@ - +
    diff --git a/examples/groups/bring a child to top.js b/examples/input/bring a child to top.js similarity index 86% rename from examples/groups/bring a child to top.js rename to examples/input/bring a child to top.js index 425524ba..de80a920 100644 --- a/examples/groups/bring a child to top.js +++ b/examples/input/bring a child to top.js @@ -2,12 +2,6 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: function preload() { - // Enable scaling - game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL; - game.stage.scale.maxWidth = 1024; - game.stage.scale.maxHeight = 672; - game.stage.scale.refresh(); - game.load.image('atari1', 'assets/sprites/atari130xe.png'); game.load.image('atari2', 'assets/sprites/atari800xl.png'); game.load.image('atari4', 'assets/sprites/atari800.png'); diff --git a/examples/input/gamepad analog button.js b/examples/input/gamepad analog button.js new file mode 100644 index 00000000..ad24622f --- /dev/null +++ b/examples/input/gamepad analog button.js @@ -0,0 +1,93 @@ +// Try this demo on Chrome with an XBOX 360 controller. +// Use left and right triggers. + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update:update }); + +function preload() { + + game.load.spritesheet('controller-indicator', 'assets/misc/controller-indicator.png', 16,16); + +} + +var leftTriggerButton; +var leftTriggerGfx; +var rightTriggerGfx; + +var indicator; + +function create() { + + game.stage.backgroundColor = '#736357'; + game.input.gamepad.start(); + + setupScene(); + + /* + Here we see two ways to get similar result. Left trigger is via 'hotkey button' style and using Phaser Signals. + Right trigger is via callbacks. NOTE the difference in the callback functions - right trigger must make a check + for which button we're listening to. + */ + + leftTriggerButton = game.input.gamepad.pad1.addButton(Phaser.Gamepad.XBOX360_LEFT_TRIGGER); + leftTriggerButton.onDown.add(onLeftTrigger); + leftTriggerButton.onUp.add(onLeftTrigger); + leftTriggerButton.onFloat.add(onLeftTrigger); + + game.input.gamepad.pad1.addCallbacks(this, { + onFloat:onRightTrigger, + onUp: onRightTrigger, + onDown: onRightTrigger + }); + + + +} + +function onLeftTrigger(button, value) { + leftTriggerGfx.clear(); + leftTriggerGfx.beginFill(0xFF700B, 1); + leftTriggerGfx.lineStyle(2, 0xFFFFFF, 1); + leftTriggerGfx.drawRect(0, -value*500, 50, value*500 + 5); + leftTriggerGfx.endFill(); +} + +function onRightTrigger(buttonCode,value) { + if(buttonCode !== Phaser.Gamepad.XBOX360_RIGHT_TRIGGER) { + return; + } + + rightTriggerGfx.clear(); + rightTriggerGfx.beginFill(0xFF700B, 1); + rightTriggerGfx.lineStyle(2, 0xFFFFFF, 1); + rightTriggerGfx.drawRect(0, -value*500, 50, value*500 + 5); + rightTriggerGfx.endFill(); +} + +function update() { + // Pad "connected or not" indicator + if(game.input.gamepad.supported && game.input.gamepad.active && game.input.gamepad.pad1.connected) { + indicator.animations.frame = 0; + } else { + indicator.animations.frame = 1; + } + +} + +function setupScene() { + indicator = game.add.sprite(10,10, 'controller-indicator'); + indicator.scale.x = indicator.scale.y = 2; + indicator.animations.frame = 1; + + leftTriggerGfx = game.add.graphics(300,550); + leftTriggerGfx.beginFill(0xFF700B, 1); + leftTriggerGfx.lineStyle(2, 0xFFFFFF, 1); + leftTriggerGfx.drawRect(0, 0, 50, 5); + leftTriggerGfx.endFill(); + + rightTriggerGfx = game.add.graphics(450,550); + rightTriggerGfx.beginFill(0xFF700B, 1); + rightTriggerGfx.lineStyle(2, 0xFFFFFF, 1); + rightTriggerGfx.drawRect(0, 0, 50, 5); + rightTriggerGfx.endFill(); +} + diff --git a/examples/input/gamepad debug.js b/examples/input/gamepad debug.js new file mode 100644 index 00000000..ce29764f --- /dev/null +++ b/examples/input/gamepad debug.js @@ -0,0 +1,189 @@ +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); + +function preload() { + game.load.spritesheet('start-input-button', 'assets/buttons/gamepad-input-start.png', 168,70); + game.load.image('reset-buttons','assets/buttons/gamepad-reset-buttons.png'); +} + +var startInputButton; +var resetButton; + +var supportedText; +var activeText; +var gamepadCountText; + +var pad1; +var pad1Text; +var pad2; +var pad2Text; +var pad3; +var pad3Text; +var pad4; +var pad4Text; + +var activityPad1Text; +var activityPad2Text; +var activityPad3Text; +var activityPad4Text; +var activityGlobalText; + +var pad1StateText; +var pad2StateText; +var pad3StateText; +var pad4StateText; + +function create() { + + game.stage.backgroundColor = '#222222'; + startInputButton = game.add.button(625, 5, 'start-input-button', onStartInput, this, 0, 0, 0); + resetButton = game.add.button(425, 5, 'reset-buttons', onResetButtons, this); + + pad1 = game.input.gamepad.pad1; + pad2 = game.input.gamepad.pad2; + pad3 = game.input.gamepad.pad3; + pad4 = game.input.gamepad.pad4; + + setupText(); +} + +function onStartInput() { + if(game.input.gamepad.active) { + game.input.gamepad.stop(); + startInputButton.setFrames(0,0,0); + } else { + game.input.gamepad.start(); + startInputButton.setFrames(1,1,1); + } +} + +function onResetButtons() { + game.input.gamepad.reset(); +} + +function update() { + supportedText.setText('Gamepad supported in this browser: '+game.input.gamepad.supported); + activeText.setText('Gamepad input active: '+game.input.gamepad.active); + gamepadCountText.setText('Gamepads connected: '+game.input.gamepad.padsConnected); + + updatePadStatusText(pad1._rawPad, pad1Text, 1); + updatePadStatusText(pad2._rawPad, pad2Text, 2); + updatePadStatusText(pad3._rawPad, pad3Text, 3); + updatePadStatusText(pad4._rawPad, pad4Text, 4); + + updatePadsButtonsAxes(pad1._rawPad, pad1StateText, 1); + updatePadsButtonsAxes(pad2._rawPad, pad2StateText, 2); + updatePadsButtonsAxes(pad3._rawPad, pad3StateText, 3); + updatePadsButtonsAxes(pad4._rawPad, pad4StateText, 4); +} + +function updatePadStatusText(rawPad, padText, num) { + if(rawPad) { + padText.setText('Pad '+num+': [ index: '+rawPad['index']+' | id: '+rawPad['id'] + +' | timestamp: '+rawPad['timestamp']+']' + +' | buttons: '+rawPad.buttons.length + +' | axes: '+rawPad.axes.length + ); + } else { + padText.setText('Pad '+num+': Not connected'); + } +} + +function updatePadsButtonsAxes(rawPad, padStateText, num) { + if(rawPad) { + var txt = 'Pad '+num+' buttons/axes: \n'; + for (var i = 0; i < rawPad.buttons.length; i += 1) { + txt += 'Button '+i+': '+rawPad.buttons[i]+'\n'; + } + for (var i = 0; i < rawPad.axes.length; i += 1) { + txt += 'Axis '+i+': '+rawPad.axes[i]+'\n'; + } + padStateText.setText(txt); + } +} + +function setupText() { + + var style = { font: "12px Arial", fill: "#ffffff", align: "left" }; + var tinyStyle = { font: "10px Arial", fill: "#ffffff", align: "left" }; + supportedText = game.add.text(10, 10, 'Gamepad supported in this browser: '+game.input.gamepad.supported, style); + activeText = game.add.text(10, 30, 'Gamepad input active: '+game.input.gamepad.active, style); + gamepadCountText = game.add.text(10, 50, 'Gamepads connected: '+game.input.gamepad.padsConnected, style); + pad1StateText = game.add.text(10, 300, 'Pad 1 buttons/axes: ', tinyStyle); + pad2StateText = game.add.text(200, 300, 'Pad 2 buttons/axes: ', tinyStyle); + pad3StateText = game.add.text(390, 300, 'Pad 3 buttons/axes: ', tinyStyle); + pad4StateText = game.add.text(580, 300, 'Pad 4 buttons/axes: ', tinyStyle); + + // Setting up infotext and callbacks for all separate four gamepads + + pad1 = game.input.gamepad.pad1; + pad1Text = game.add.text(10, 80, 'Pad 1: ', style); + pad2 = game.input.gamepad.pad2; + pad2Text = game.add.text(10, 100, 'Pad 2: ', style); + pad3 = game.input.gamepad.pad3; + pad3Text = game.add.text(10, 120, 'Pad 3: ', style); + pad4 = game.input.gamepad.pad4; + pad4Text = game.add.text(10, 140, 'Pad 4: ', style); + + activityPad1Text = game.add.text(10, 180, 'Last activity pad 1: ', style); + addPadCallbacks(pad1, activityPad1Text, 1); + + activityPad2Text = game.add.text(10, 200, 'Last activity pad 2: ', style); + addPadCallbacks(pad2, activityPad2Text, 2); + + activityPad3Text = game.add.text(10, 220, 'Last activity pad 3: ', style); + addPadCallbacks(pad3, activityPad3Text, 3); + + activityPad4Text = game.add.text(10, 240, 'Last activity pad 4: ', style); + addPadCallbacks(pad4, activityPad4Text, 4); + + activityGlobalText = game.add.text(10, 270, 'Last activity all pads: ', style); + + + + // Here we're setting callbacks that will trigger from ALL gamepads connected + game.input.gamepad.addCallbacks(this, { + onConnect: function(padIndex){ + activityGlobalText.setText('Last activity all pads: Connected with pad index '+padIndex); + }, + onDisconnect: function(padIndex){ + activityGlobalText.setText('Last activity all pads: Disconnected with pad index '+padIndex); + }, + onDown: function(buttonCode, value, padIndex){ + activityGlobalText.setText('Last activity all pads: Pad index '+padIndex+' buttonCode: '+buttonCode+' | value: '+value); + }, + onUp: function(buttonCode, value, padIndex){ + activityGlobalText.setText('Last activity all pads: Pad index '+padIndex+' buttonCode: '+buttonCode+' | value: '+value); + }, + onAxis: function(axisState, padIndex) { + activityGlobalText.setText('Last activity all pads: Pad index '+padIndex+': axis '+axisState.axis+': '+axisState.value); + }, + onFloat: function(buttonCode, value, padIndex) { + activityGlobalText.setText('Last activity all pads: Pad index '+padIndex+' buttonCode: '+buttonCode+' | value (float): '+value); + } + }); +} + + + +function addPadCallbacks(pad, text, index) { + pad.addCallbacks(this, { + onConnect: function(){ + text.setText('Last activity pad '+index+': Connected'); + }, + onDisconnect: function(){ + text.setText('Last activity pad '+index+': Disconnected'); + }, + onDown: function(buttonCode, value){ + text.setText('Last activity pad '+index+': buttonCode: '+buttonCode+' | value: '+value); + }, + onUp: function(buttonCode, value){ + text.setText('Last activity pad '+index+': buttonCode: '+buttonCode+' | value: '+value); + }, + onAxis: function(axisState) { + text.setText('Last activity pad '+index+': axis '+axisState.axis+': '+axisState.value); + }, + onFloat: function(buttonCode, value) { + text.setText('Last activity pad '+index+': buttonCode: '+buttonCode+' | value (float): '+value); + } + }); +} \ No newline at end of file diff --git a/examples/input/gamepad hotkeys.js b/examples/input/gamepad hotkeys.js new file mode 100644 index 00000000..e2eff097 --- /dev/null +++ b/examples/input/gamepad hotkeys.js @@ -0,0 +1,61 @@ +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update:update }); + +function preload() { + + game.load.image('phaser', 'assets/sprites/phaser-dude.png'); + game.load.image('logo', 'assets/sprites/phaser_tiny.png'); + game.load.image('pineapple', 'assets/sprites/pineapple.png'); + game.load.spritesheet('controller-indicator', 'assets/misc/controller-indicator.png', 16,16); + +} + +var button1; +var button2; +var button3; + +var indicator; + +function update() { + // Pad "connected or not" indicator + if(game.input.gamepad.supported && game.input.gamepad.active && game.input.gamepad.pad1.connected) { + indicator.animations.frame = 0; + } else { + indicator.animations.frame = 1; + } +} + +function create() { + + game.stage.backgroundColor = '#736357'; + + game.input.gamepad.start(); + + + indicator = game.add.sprite(10,10, 'controller-indicator'); + indicator.scale.x = indicator.scale.y = 2; + indicator.animations.frame = 1; + + // Here we create 3 "hotkey buttons" for Gamepad #1, buttons 0-2 and bind them all to their own functions + + button1 = game.input.gamepad.pad1.addButton(Phaser.Gamepad.BUTTON_0); + button1.onDown.add(addPhaserDude, this); + + button2 = game.input.gamepad.pad1.addButton(Phaser.Gamepad.BUTTON_1); + button2.onDown.add(addPhaserLogo, this); + + button3 = game.input.gamepad.pad1.addButton(Phaser.Gamepad.BUTTON_2); + button3.onDown.add(addPineapple, this); + +} + +function addPhaserDude () { + game.add.sprite(game.world.randomX, game.world.randomY, 'phaser'); +} + +function addPhaserLogo () { + game.add.sprite(game.world.randomX, game.world.randomY, 'logo'); +} + +function addPineapple () { + game.add.sprite(game.world.randomX, game.world.randomY, 'pineapple'); +} diff --git a/examples/input/gamepad multiple pads.js b/examples/input/gamepad multiple pads.js new file mode 100644 index 00000000..d6de6996 --- /dev/null +++ b/examples/input/gamepad multiple pads.js @@ -0,0 +1,120 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update:update }); + +function preload() { + + game.load.image('phaser', 'assets/sprites/phaser-dude.png'); + game.load.image('melon', 'assets/sprites/melon.png'); + game.load.spritesheet('controller-indicator', 'assets/misc/controller-indicator.png', 16,16); + +} + +var pad1; +var pad2; + +var indicator1; +var indicator2; + +var player1; +var player2; + +var melon; + + +function create() { + + game.stage.backgroundColor = '#736357'; + game.input.gamepad.start(); + + + indicator1 = game.add.sprite(10,10, 'controller-indicator'); + indicator1.scale.x = indicator1.scale.y = 2; + indicator1.animations.frame = 1; + + indicator2 = game.add.sprite(10,50, 'controller-indicator'); + indicator2.scale.x = indicator2.scale.y = 2; + indicator2.animations.frame = 1; + + player1 = game.add.sprite(300, 300, 'phaser'); + player1.anchor.setTo(0.5,0.5); + + player2 = game.add.sprite(450, 300, 'phaser'); + player2.anchor.setTo(0.5,0.5); + + // This little melon dude is controlled by all gamepads! + melon = game.add.sprite(375, 350, 'melon'); + melon.anchor.setTo(0.5,0.5); + + pad1 = game.input.gamepad.pad1; + pad2 = game.input.gamepad.pad2; +} + +function update() { + // Pad "connected or not" indicator + if(game.input.gamepad.supported && game.input.gamepad.active && game.input.gamepad.pad1.connected) { + indicator1.animations.frame = 0; + } else { + indicator1.animations.frame = 1; + } + if(game.input.gamepad.supported && game.input.gamepad.active && game.input.gamepad.pad2.connected) { + indicator2.animations.frame = 0; + } else { + indicator2.animations.frame = 1; + } + + if (pad1.isDown(Phaser.Gamepad.XBOX360_DPAD_LEFT) || pad1.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_X) < -0.1) + { + player1.x--; + } + if (pad1.isDown(Phaser.Gamepad.XBOX360_DPAD_RIGHT) || pad1.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_X) > 0.1) + { + player1.x++; + } + if (pad1.isDown(Phaser.Gamepad.XBOX360_DPAD_UP) || pad1.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_Y) < -0.1) + { + player1.y--; + } + if (pad1.isDown(Phaser.Gamepad.XBOX360_DPAD_DOWN) || pad1.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_Y) > 0.1) + { + player1.y++; + } + + if (pad2.isDown(Phaser.Gamepad.XBOX360_DPAD_LEFT) || pad2.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_X) < -0.1) + { + player2.x--; + } + if (pad2.isDown(Phaser.Gamepad.XBOX360_DPAD_RIGHT) || pad2.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_X) > 0.1) + { + player2.x++; + } + if (pad2.isDown(Phaser.Gamepad.XBOX360_DPAD_UP) || pad2.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_Y) < -0.1) + { + player2.y--; + } + if (pad2.isDown(Phaser.Gamepad.XBOX360_DPAD_DOWN) || pad2.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_Y) > 0.1) + { + player2.y++; + } + + + // isDown on game.input.gamepad checks ALL gamepad buttons + if (game.input.gamepad.isDown(Phaser.Gamepad.XBOX360_DPAD_LEFT)) + { + melon.x--; + } + if (game.input.gamepad.isDown(Phaser.Gamepad.XBOX360_DPAD_RIGHT)) + { + melon.x++; + } + if (game.input.gamepad.isDown(Phaser.Gamepad.XBOX360_DPAD_UP)) + { + melon.y--; + } + if (game.input.gamepad.isDown(Phaser.Gamepad.XBOX360_DPAD_DOWN)) + { + melon.y++; + } + + +} + diff --git a/examples/input/gamepad tanks.js b/examples/input/gamepad tanks.js new file mode 100644 index 00000000..79e912d5 --- /dev/null +++ b/examples/input/gamepad tanks.js @@ -0,0 +1,335 @@ +// Try this demo on Chrome with an XBOX 360 controller. +// Steer with left analog, accelerate/brake with analog triggers, +// fire with A and steer turret with left and right 'bumper' (shoulder) buttons. + +EnemyTank = function (index, game, player, bullets) { + + var x = game.world.randomX; + var y = game.world.randomY; + + this.game = game; + this.health = 3; + this.player = player; + this.bullets = bullets; + this.fireRate = 1000; + this.nextFire = 0; + this.alive = true; + + this.shadow = game.add.sprite(x, y, 'enemy', 'shadow'); + this.tank = game.add.sprite(x, y, 'enemy', 'tank1'); + this.turret = game.add.sprite(x, y, 'enemy', 'turret'); + + this.shadow.anchor.setTo(0.5, 0.5); + this.tank.anchor.setTo(0.5, 0.5); + this.turret.anchor.setTo(0.3, 0.5); + + this.tank.name = index.toString(); + this.tank.body.immovable = true; + this.tank.body.collideWorldBounds = true; + this.tank.body.bounce.setTo(1, 1); + + this.tank.angle = game.rnd.angle(); + + game.physics.velocityFromRotation(this.tank.rotation, 100, this.tank.body.velocity); + +}; + +EnemyTank.prototype.damage = function() { + + this.health -= 1; + + if (this.health <= 0) + { + this.alive = false; + + this.shadow.kill(); + this.tank.kill(); + this.turret.kill(); + + return true; + } + + return false; + +}; + +EnemyTank.prototype.update = function() { + + this.shadow.x = this.tank.x; + this.shadow.y = this.tank.y; + this.shadow.rotation = this.tank.rotation; + + this.turret.x = this.tank.x; + this.turret.y = this.tank.y; + this.turret.rotation = this.game.physics.angleBetween(this.tank, this.player); + + if (this.game.physics.distanceBetween(this.tank, this.player) < 300) + { + if (this.game.time.now > this.nextFire && this.bullets.countDead() > 0) + { + this.nextFire = this.game.time.now + this.fireRate; + + var bullet = this.bullets.getFirstDead(); + + bullet.reset(this.turret.x, this.turret.y); + + bullet.rotation = this.game.physics.moveToObject(bullet, this.player, 500); + } + } + +}; + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); + +function preload () { + + game.load.atlas('tank', 'assets/games/tanks/tanks.png', 'assets/games/tanks/tanks.json'); + game.load.atlas('enemy', 'assets/games/tanks/enemy-tanks.png', 'assets/games/tanks/tanks.json'); + game.load.image('logo', 'assets/games/tanks/logo-gamepad.png'); + game.load.image('bullet', 'assets/games/tanks/bullet.png'); + game.load.image('earth', 'assets/games/tanks/scorched_earth.png'); + game.load.spritesheet('kaboom', 'assets/games/tanks/explosion.png', 64, 64, 23); + game.load.spritesheet('controller-indicator', 'assets/misc/controller-indicator.png', 16,16); + +} + +var land; + +var shadow; +var tank; +var turret; + +var enemies; +var enemyBullets; +var explosions; + +var logo; + +var currentSpeed = 0; +var cursors; + +var bullets; +var fireRate = 200; +var nextFire = 0; + +var indicator; +var pad1; + +var turretOffset = 0; + +function create () { + + // Resize our game world to be a 2000 x 2000 square + game.world.setBounds(-1000, -1000, 2000, 2000); + + // Our tiled scrolling background + land = game.add.tileSprite(0, 0, 800, 600, 'earth'); + land.fixedToCamera = true; + + // The base of our tank + tank = game.add.sprite(0, 0, 'tank', 'tank1'); + tank.anchor.setTo(0.5, 0.5); + tank.animations.add('move', ['tank1', 'tank2', 'tank3', 'tank4', 'tank5', 'tank6'], 20, true); + // tank.play('move'); + + // This will force it to decelerate and limit its speed + tank.body.linearDamping = 0.2; + tank.body.maxVelocity.setTo(400, 400); + tank.body.collideWorldBounds = true; + + // Finally the turret that we place on-top of the tank body + turret = game.add.sprite(0, 0, 'tank', 'turret'); + turret.anchor.setTo(0.3, 0.5); + + // The enemies bullet group + enemyBullets = game.add.group(); + enemyBullets.createMultiple(100, 'bullet'); + enemyBullets.setAll('anchor.x', 0.5); + enemyBullets.setAll('anchor.y', 0.5); + enemyBullets.setAll('outOfBoundsKill', true); + + // Create some baddies to waste :) + enemies = []; + + for (var i = 0; i < 20; i++) + { + enemies.push(new EnemyTank(i, game, tank, enemyBullets)); + } + + // A shadow below our tank + shadow = game.add.sprite(0, 0, 'tank', 'shadow'); + shadow.anchor.setTo(0.5, 0.5); + + // Our bullet group + bullets = game.add.group(); + bullets.createMultiple(30, 'bullet'); + bullets.setAll('anchor.x', 0.5); + bullets.setAll('anchor.y', 0.5); + bullets.setAll('outOfBoundsKill', true); + + // Explosion pool + explosions = game.add.group(); + + for (var i = 0; i < 10; i++) + { + var explosionAnimation = explosions.create(0, 0, 'kaboom', [0], false); + explosionAnimation.anchor.setTo(0.5, 0.5); + explosionAnimation.animations.add('kaboom'); + } + + tank.bringToTop(); + turret.bringToTop(); + + logo = game.add.sprite(0, 200, 'logo'); + logo.fixedToCamera = true; + + game.camera.follow(tank); + game.camera.deadzone = new Phaser.Rectangle(150, 150, 500, 300); + game.camera.focusOnXY(0, 0); + + pad1 = game.input.gamepad.pad1; + pad1.addCallbacks(this, {onDown:function(){ + removeLogo(); + }}); + + indicator = game.add.sprite(10,10, 'controller-indicator'); + indicator.scale.x = indicator.scale.y = 2; + indicator.animations.frame = 1; + indicator.fixedToCamera = true; + + game.input.gamepad.start(); + + // showing you can set the deadZone for all pads + // you can also set it like game.input.gamepad.pad1.deadZone = 0.25 + // default is 0.26 and is sensible enough for an xbox 360 controller as the + // axes seems to hickup at quite high values at times (your mileage may vary) + game.input.gamepad.setDeadZones(0.25); +} + +function removeLogo () { + + game.input.onDown.remove(removeLogo, this); + logo.kill(); + +} + +function update () { + + // Pad "connected or not" indicator + if(game.input.gamepad.supported && game.input.gamepad.active && pad1.connected) { + indicator.animations.frame = 0; + } else { + indicator.animations.frame = 1; + } + + game.physics.collide(enemyBullets, tank, bulletHitPlayer, null, this); + + for (var i = 0; i < enemies.length; i++) + { + if (enemies[i].alive) + { + enemies[i].update(); + game.physics.collide(tank, enemies[i].tank); + game.physics.collide(bullets, enemies[i].tank, bulletHitEnemy, null, this); + } + } + + if (pad1.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_X) < -0.3) + { + tank.angle -= 4 * -pad1.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_X); + } + if (pad1.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_X) > 0.3) + { + tank.angle += 4 * pad1.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_X); + } + + var rightTriggerValue = pad1.buttonValue(Phaser.Gamepad.XBOX360_RIGHT_TRIGGER); + if(rightTriggerValue && rightTriggerValue > 0) { + currentSpeed = 300 * rightTriggerValue; + } else { + if (currentSpeed > 0) + { + currentSpeed -= 4; + } + } + + var leftTriggerValue = pad1.buttonValue(Phaser.Gamepad.XBOX360_LEFT_TRIGGER); + if(leftTriggerValue && leftTriggerValue > 0) { + currentSpeed = 150 * -leftTriggerValue; + } else { + if (currentSpeed < 0) + { + currentSpeed += 4; + currentSpeed = (currentSpeed > 0) ? 0 : currentSpeed; + } + } + +// if (currentSpeed > 0) +// { + game.physics.velocityFromRotation(tank.rotation, currentSpeed, tank.body.velocity); +// } + + land.tilePosition.x = -game.camera.x; + land.tilePosition.y = -game.camera.y; + + // Position all the parts and align rotations + shadow.x = tank.x; + shadow.y = tank.y; + shadow.rotation = tank.rotation; + + turret.x = tank.x; + turret.y = tank.y; + + if (pad1.isDown(Phaser.Gamepad.XBOX360_LEFT_BUMPER)) { + turretOffset -= 3; + } + if (pad1.isDown(Phaser.Gamepad.XBOX360_RIGHT_BUMPER)) { + turretOffset += 3; + } + + turret.rotation = tank.rotation; + turret.angle += turretOffset; +// turret.rotation = game.physics.angleToPointer(turret); + + if (pad1.isDown(Phaser.Gamepad.XBOX360_A)) + { + fire(); + } + +} + +function bulletHitPlayer (tank, bullet) { + + bullet.kill(); + +} + +function bulletHitEnemy (tank, bullet) { + + bullet.kill(); + + var destroyed = enemies[tank.name].damage(); + + if (destroyed) + { + var explosionAnimation = explosions.getFirstDead(); + explosionAnimation.reset(tank.x, tank.y); + explosionAnimation.play('kaboom', 30, false, true); + } + +} + +function fire () { + + if (game.time.now > nextFire && bullets.countDead() > 0) + { + nextFire = game.time.now + fireRate; + + var bullet = bullets.getFirstDead(); + + bullet.reset(turret.x, turret.y); + bullet.rotation = turret.rotation; + game.physics.velocityFromAngle(bullet.angle, 1000, bullet.body.velocity); + } + +} diff --git a/examples/input/gamepad.js b/examples/input/gamepad.js new file mode 100644 index 00000000..d6b729ff --- /dev/null +++ b/examples/input/gamepad.js @@ -0,0 +1,80 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); + +function preload() { + + game.load.image('phaser', 'assets/sprites/phaser-dude.png'); + game.load.spritesheet('controller-indicator', 'assets/misc/controller-indicator.png', 16,16); +} + +var sprite; + +var pad1; + +var indicator; + +function create() { + + game.stage.backgroundColor = '#736357'; + + sprite = game.add.sprite(300, 300, 'phaser'); + sprite.anchor.setTo(0.5,0.5); + + indicator = game.add.sprite(10,10, 'controller-indicator'); + indicator.scale.x = indicator.scale.y = 2; + indicator.animations.frame = 1; + + game.input.gamepad.start(); + + // To listen to buttons from a specific pad listen directly on that pad game.input.gamepad.padX, where X = pad 1-4 + pad1 = game.input.gamepad.pad1; +} + +function update() { + + // Pad "connected or not" indicator + if(game.input.gamepad.supported && game.input.gamepad.active && pad1.connected) { + indicator.animations.frame = 0; + } else { + indicator.animations.frame = 1; + } + + // Controls + if (pad1.isDown(Phaser.Gamepad.XBOX360_DPAD_LEFT) || pad1.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_X) < -0.1) + { + sprite.x--; + } + if (pad1.isDown(Phaser.Gamepad.XBOX360_DPAD_RIGHT) || pad1.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_X) > 0.1) + { + sprite.x++; + } + if (pad1.isDown(Phaser.Gamepad.XBOX360_DPAD_UP) || pad1.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_Y) < -0.1) + { + sprite.y--; + } + if (pad1.isDown(Phaser.Gamepad.XBOX360_DPAD_DOWN) || pad1.axis(Phaser.Gamepad.XBOX360_STICK_LEFT_Y) > 0.1) + { + sprite.y++; + } + if (pad1.justPressed(Phaser.Gamepad.XBOX360_A)) + { + sprite.angle += 5; + } + if (pad1.justReleased(Phaser.Gamepad.XBOX360_B)) + { + sprite.scale.x += 0.01; + sprite.scale.y = sprite.scale.x; + } + + if(pad1.connected) { + var rightStickX = pad1.axis(Phaser.Gamepad.XBOX360_STICK_RIGHT_X); + var rightStickY = pad1.axis(Phaser.Gamepad.XBOX360_STICK_RIGHT_Y); + + if(rightStickX) { + sprite.x += rightStickX * 10; + } + if(rightStickY) { + sprite.y += rightStickY * 10; + } + } +} diff --git a/examples/loader/load tilemap json.js b/examples/loader/load tilemap json.js index 9447c153..eae8be89 100644 --- a/examples/loader/load tilemap json.js +++ b/examples/loader/load tilemap json.js @@ -3,7 +3,6 @@ var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: p function preload() { - // Tilemaps are split into two parts: The actual map data (usually stored in a CSV or JSON file) // and the tileset/s used to render the map. @@ -16,27 +15,33 @@ function preload() { // The final one tells Phaser the foramt of the map data, in this case it's a JSON file exported from the Tiled map editor. // This could be Phaser.Tilemap.CSV too. - game.load.tilemap('mario', 'assets/maps/mario1.json', null, Phaser.Tilemap.TILED_JSON); + game.load.tilemap('mario', 'assets/tilemaps/maps/super_mario.json', null, Phaser.Tilemap.TILED_JSON); - // Next we load the tileset. This consists of an image and a set of values that determine the size of the tiles within the image. - // In this case we give it a unique key, the URL to the PNG file and tell Phaser the tiles are all 16x16 pixels in size. + // Next we load the tileset. This is just an image, loaded in via the normal way we load images: - game.load.tileset('tiles', 'assets/maps/mario1.png', 16, 16); + game.load.image('tiles', 'assets/tilemaps/tiles/super_mario.png'); } var map; -var tileset; var layer; function create() { game.stage.backgroundColor = '#787878'; + // The 'mario' key here is the Loader key given in game.load.tilemap map = game.add.tilemap('mario'); - - tileset = game.add.tileset('tiles'); - layer = game.add.tilemapLayer(0, 0, 800, 600, tileset, map, 0); + // The first parameter is the tileset name, as specified in the Tiled map editor (and in the tilemap json file) + // The second parameter maps this name to the Phaser.Cache key 'tiles' + map.addTilesetImage('SuperMarioBros-World1-1', 'tiles'); + + // Creates a layer from the World1 layer in the map data. + // A Layer is effectively like a Phaser.Sprite, so is added to the display list. + layer = map.createLayer('World1'); + + // This resizes the game world to match the layer dimensions + layer.resizeWorld(); } diff --git a/examples/particles/click burst.js b/examples/particles/click burst.js index 955dfdd2..e3a36ded 100644 --- a/examples/particles/click burst.js +++ b/examples/particles/click burst.js @@ -16,7 +16,7 @@ function create() { emitter = game.add.emitter(0, 0, 200); emitter.makeParticles('diamond'); - emitter.gravity = 10; + emitter.gravity = 200; game.input.onDown.add(particleBurst, this); diff --git a/examples/particles/collision.js b/examples/particles/collision.js index a2dab06a..cc9fdfb7 100644 --- a/examples/particles/collision.js +++ b/examples/particles/collision.js @@ -17,9 +17,8 @@ function create() { emitter.minParticleSpeed.setTo(-200, -300); emitter.maxParticleSpeed.setTo(200, -400); - emitter.gravity = 8; + emitter.gravity = 150; emitter.bounce.setTo(0.5, 0.5); - emitter.particleDrag.x = 10; emitter.angularDrag = 30; emitter.start(false, 8000, 400); @@ -28,6 +27,6 @@ function create() { function update() { - game.physics.collide(emitter, emitter); + game.physics.collide(emitter); } diff --git a/examples/particles/rain.js b/examples/particles/rain.js new file mode 100644 index 00000000..06aa3dae --- /dev/null +++ b/examples/particles/rain.js @@ -0,0 +1,27 @@ +// This example was created by Jens Anders Bakke + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create }); + +function preload() { + + game.load.spritesheet('rain', 'assets/sprites/rain.png', 17, 17); + +} + +function create() { + + var emitter = game.add.emitter(game.world.centerX, 0, 400); + emitter.width = game.world.width; + // emitter.angle = 30; // uncomment to set an angle for the rain. + + emitter.makeParticles('rain'); + emitter.maxParticleScale = 0.5; + emitter.minParticleScale = 0.1; + emitter.setYSpeed(300, 500); + emitter.setXSpeed(-5, 5); + emitter.minRotation = 0; + emitter.maxRotation = 0; + + emitter.start(false, 1600, 5, 0); + +} diff --git a/examples/particles/snow.js b/examples/particles/snow.js new file mode 100644 index 00000000..5dafe04a --- /dev/null +++ b/examples/particles/snow.js @@ -0,0 +1,100 @@ +// This example was created by Jens Anders Bakke + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create }); + +function preload() { + + game.load.spritesheet('snowflakes', 'assets/sprites/snowflakes.png', 17, 17); + game.load.spritesheet('snowflakes_large', 'assets/sprites/snowflakes_large.png', 64, 64); + +} + +var max = 0; +var front_emitter; +var mid_emitter; +var back_emitter; +var update_interval = 4 * 60; +var i = 0; + +function create() { + + back_emitter = game.add.emitter(game.world.centerX, -32, 600); + back_emitter.makeParticles('snowflakes', [0, 1, 2, 3, 4, 5]); + back_emitter.maxParticleScale = 0.6; + back_emitter.minParticleScale = 0.2; + back_emitter.setYSpeed(20, 100); + back_emitter.gravity = 0; + back_emitter.width = game.world.width * 1.5; + back_emitter.minRotation = 0; + back_emitter.maxRotation = 40; + + + mid_emitter = game.add.emitter(game.world.centerX, -32, 250); + mid_emitter.makeParticles('snowflakes', [0, 1, 2, 3, 4, 5]); + mid_emitter.maxParticleScale = 1.2; + mid_emitter.minParticleScale = 0.8; + mid_emitter.setYSpeed(50, 150); + mid_emitter.gravity = 0; + mid_emitter.width = game.world.width * 1.5; + mid_emitter.minRotation = 0; + mid_emitter.maxRotation = 40; + + + front_emitter = game.add.emitter(game.world.centerX, -32, 50); + front_emitter.makeParticles('snowflakes_large', [0, 1, 2, 3, 4, 5]); + front_emitter.maxParticleScale = 1; + front_emitter.minParticleScale = 0.5; + front_emitter.setYSpeed(100, 200); + front_emitter.gravity = 0; + front_emitter.width = game.world.width * 1.5; + front_emitter.minRotation = 0; + front_emitter.maxRotation = 40; + + changeWindDirection(); + + back_emitter.start(false, 14000, 20); + mid_emitter.start(false, 12000, 40); + front_emitter.start(false, 6000, 1000); + +} + +function update() { + + i++; + + if (i === update_interval) + { + changeWindDirection(); + update_interval = Math.floor(Math.random() * 20) * 60; // 0 - 20sec @ 60fps + i = 0; + } + +} + +function changeWindDirection() { + + var multi = Math.floor((max + 200) / 4), + frag = (Math.floor(Math.random() * 100) - multi); + max = max + frag; + + if (max > 200) max = 150; + if (max < -200) max = -150; + + setXSpeed(back_emitter, max); + setXSpeed(mid_emitter, max); + setXSpeed(front_emitter, max); + +} + +function setXSpeed(emitter, max) { + + emitter.setXSpeed(max - 20, max); + emitter.forEachAlive(setParticleXSpeed, this, max); + +} + +function setParticleXSpeed(particle, max) { + + particle.body.velocity.x = max - Math.floor(Math.random() * 30); + +} diff --git a/examples/physics/bounce accelerator.js b/examples/physics/bounce accelerator.js new file mode 100644 index 00000000..1fb7d53f --- /dev/null +++ b/examples/physics/bounce accelerator.js @@ -0,0 +1,94 @@ +// mods by Patrick OReilly +// Twitter: @pato_reilly Web: http://patricko.byethost9.com + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.spritesheet('dude', 'assets/games/starstruck/dude.png', 32, 48); + +} + +var flyer; + +function create() { + + cursors = game.input.keyboard.createCursorKeys(); + + flyer = game.add.sprite(400, 200, 'dude'); + + flyer.animations.add('left', [0, 1, 2, 3], 10, true); + flyer.animations.add('right', [5, 6, 7, 8], 10, true); + + // This gets it moving + flyer.body.velocity.setTo(200, 200); + + // This makes the game world bounce-able + flyer.body.collideWorldBounds = true; + + // This sets the image bounce energy for the horizontal + // and vertical vectors (as an x,y point). "1" is 100% energy return + flyer.body.bounce.setTo(0.8, 0.8); + + // This sets the gravity the sprite responds to in the world, as a point + // Leave x=0 and set y=80 to simulate falling + flyer.body.gravity.setTo(0, 80); + +} + +// Change the vertical and horizontal acceleration property accordingly with the key pressed +// Also turn on and off the animation. Dude should have wings ;) + +function update () { + + if (cursors.up.isDown) + { + flyer.body.acceleration.y = -600; + + if (flyer.body.velocity.x > 0) + { + flyer.animations.play('right'); + } + else + { + flyer.animations.play('left'); + } + } + else if (cursors.down.isDown) + { + flyer.body.acceleration.y = 600; + + if (flyer.body.velocity.x > 0) + { + flyer.animations.play('right'); + } + else + { + flyer.animations.play('left'); + } + } + else if (cursors.left.isDown) + { + flyer.body.acceleration.x = -500; + flyer.animations.play('left'); + } + else if (cursors.right.isDown) + { + flyer.body.acceleration.x = 500; + flyer.animations.play('right'); + } + else + { + flyer.frame = 4; + flyer.body.acceleration.setTo(0,0); + flyer.animations.stop(); + } + +} + +function render () { + + //debug helper + game.debug.renderSpriteInfo(flyer,32,32); + +} \ No newline at end of file diff --git a/examples/physics/bounce knock.js b/examples/physics/bounce knock.js new file mode 100644 index 00000000..35245652 --- /dev/null +++ b/examples/physics/bounce knock.js @@ -0,0 +1,77 @@ +// mods by Patrick OReilly +// Twitter: @pato_reilly Web: http://patricko.byethost9.com + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('dude', 'assets/sprites/phaser-dude.png'); + game.load.image('ball', 'assets/sprites/pangball.png'); + +} + +var image; + +function create() { + + cursors = game.input.keyboard.createCursorKeys(); + + // This creates a simple sprite that is using our loaded image and + // displays it on-screen + // and assign it to a variable + ball = game.add.sprite(400, 200, 'ball'); + + knocker = game.add.sprite(400, 200, 'dude'); + knocker.body.immovable = true; + + // This gets it moving + ball.body.velocity.setTo(200, 200); + + // This makes the game world bounce-able + ball.body.collideWorldBounds = true; + + // This sets the image bounce energy for the horizontal + // and vertical vectors (as an x,y point). "1" is 100% energy return + ball.body.bounce.setTo(1, 1); + + // This sets the gravity the sprite responds to in the world, as a point + // Here we leave x=0 and set y=80 to simulate falling + ball.body.gravity.setTo(0, 80); + +} + +// Move the knocker with the arrow keys +function update () { + + // Enable physics between the knocker and the ball + game.physics.collide(knocker, ball); + + if (cursors.up.isDown) + { + knocker.body.velocity.y = -300; + } + else if (cursors.down.isDown) + { + knocker.body.velocity.y = 300; + } + else if (cursors.left.isDown) + { + knocker.body.velocity.x = -300; + } + else if (cursors.right.isDown) + { + knocker.body.velocity.x = 300; + } + else + { + knocker.body.velocity.setTo(0, 0); + } + +} + +function render () { + + //debug helper + game.debug.renderSpriteInfo(ball, 32, 32); + +} diff --git a/examples/physics/bounce with gravity.js b/examples/physics/bounce with gravity.js new file mode 100644 index 00000000..78b7063c --- /dev/null +++ b/examples/physics/bounce with gravity.js @@ -0,0 +1,50 @@ +// mods by Patrick OReilly +// Twitter: @pato_reilly Web: http://patricko.byethost9.com + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + // You can fill the preloader with as many assets as your game requires + + // Here we are loading an image. The first parameter is the unique + // string by which we'll identify the image later in our code. + + // The second parameter is the URL of the image (relative) + game.load.image('flyer', 'assets/sprites/phaser-dude.png'); +} + +var image; + +function create() { + + // This creates a simple sprite that is using our loaded image and displays it on-screen and assign it to a variable + image = game.add.sprite(400, 200, 'flyer'); + + // This gets it moving + image.body.velocity.setTo(200, 200); + + // This makes the game world bounce-able + image.body.collideWorldBounds = true; + + // This sets the image bounce energy for the horizontal and vertical vectors (as an x,y point). "1" is 100% energy return + image.body.bounce.setTo(0.8, 0.8); + + // This sets the gravity the sprite responds to in the world, as a point + // Leave x=0 and set y=180 to simulate falling + image.body.gravity.setTo(0, 180); + +} + +function update () { + + // nothing required here + +} + +function render () { + + //debug helper + game.debug.renderSpriteInfo(image,32,32); + +} diff --git a/examples/physics/bounce.js b/examples/physics/bounce.js new file mode 100644 index 00000000..08047ad9 --- /dev/null +++ b/examples/physics/bounce.js @@ -0,0 +1,47 @@ +// mods by Patrick OReilly +// Twitter: @pato_reilly Web: http://patricko.byethost9.com + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + // You can fill the preloader with as many assets as your game requires + + // Here we are loading an image. The first parameter is the unique + // string by which we'll identify the image later in our code. + + // The second parameter is the URL of the image (relative) + game.load.image('flyer', 'assets/sprites/phaser-dude.png'); +} + +var image; + +function create() { + + // This creates a simple sprite that is using our loaded image and + // displays it on-screen + // and assign it to a variable + image = game.add.sprite(0, 0, 'flyer'); + + // This gets it moving + image.body.velocity.setTo(200,200); + + // This makes the game world bounce-able + image.body.collideWorldBounds = true; + + // This sets the image bounce energy for the horizontal + // and vertical vectors. "1" is 100% energy return + image.body.bounce.setTo(1,1); + +} + +function update () { + +//nothing required here + +} + +function render () { + //debug helper + game.debug.renderSpriteInfo(image,32,32); +} \ No newline at end of file diff --git a/examples/physics/framerate independence.js b/examples/physics/framerate independence.js new file mode 100644 index 00000000..94e7814e --- /dev/null +++ b/examples/physics/framerate independence.js @@ -0,0 +1,137 @@ +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +// This example pokes around with the internal Phaser time and physics systems +// just to demonstrate collision and physics behaviour with different framerates. +// Doing this in your game is not recommended + +function preload() { + + game.load.image('sprite', 'assets/sprites/diamond.png'); + +} + +var sprite, box; + +var configurations = [ + { + framerate: null, + description: 'Default (as fast as possible)', + color: 0x999999 + }, + { + framerate: 120, + color: 0x0000FF + }, + { + framerate: 60, + color: 0x00FF00 + }, + { + framerate: 30, + color: 0x00CCCC + }, + { + framerate: 11, + color: 0xFF0000 + }, + { + framerate: 7, + color: 0xCC00CC + }, + { + framerate: 5, + color: 0xCCCC00 + }, + { + framerate: function() { return Math.random() * 30 + 30; }, + description: 'Jittered 30-60hz', + color: 0x333399 + }, + { + framerate: function() { return Math.random() * 119 + 1; }, + description: 'Jittered 1-120hz', + color: 0x339933 + } + +]; + +var configurationIndex = 0; +var currentConfiguration = configurations[0]; + +var floor = game.height - 40; + +// Here we keep a copy of the original framerate update method +Phaser.Time.prototype.originalUpdate = Phaser.Time.prototype.update; + +// And replace it with one that overrides the framerate +Phaser.Time.prototype.update = function (time) { + + this.originalUpdate(time); + + if(currentConfiguration.framerate) + { + if(typeof(currentConfiguration.framerate) == 'function') + { + this.physicsElapsed = 1.0 / currentConfiguration.framerate(); + } else { + this.physicsElapsed = 1.0 / currentConfiguration.framerate; + } + } +}; + +function resetSprite() +{ + sprite.body.x = 40; + sprite.body.y = floor; + sprite.body.velocity.x = 300; + sprite.body.velocity.y = -900; + sprite.body.gravity.y = 20; + +}; + +function create() { + + sprite = game.add.sprite(40, floor, 'sprite'); + sprite.body.bounce.y = 0.5; + resetSprite(); + + for(var i = 0; i < configurations.length; i++) + { + configurations[i].graphics = game.add.graphics(0, 0); + configurations[i].points = []; + } + + box = game.add.sprite(450, floor - 40, 'missing'); + box.width = 100; + box.body.immovable = true; +}; + +function update() { + + game.physics.collide(sprite, box); + + currentConfiguration.points.push([sprite.center.x, sprite.center.y]); + + if(sprite.body.velocity.y > 0 && sprite.body.y > floor) + { + currentConfiguration.graphics.clear(); + currentConfiguration.graphics.lineStyle(1, currentConfiguration.color, 1) + currentConfiguration.graphics.moveTo(currentConfiguration.points[0][0], currentConfiguration.points[0][1]); + + for(var i = 1; i < currentConfiguration.points.length; i++) + { + currentConfiguration.graphics.lineTo(currentConfiguration.points[i][0], currentConfiguration.points[i][1]); + } + + currentConfiguration.points.length = 0; + + configurationIndex = (configurationIndex + 1) % configurations.length; + currentConfiguration = configurations[configurationIndex]; + + resetSprite(); + } +}; + +function render() { + game.debug.renderText("Framerate: " + (currentConfiguration.description || (currentConfiguration.framerate + 'hz')), 10, 40); +}; \ No newline at end of file diff --git a/examples/physics/gravity.js b/examples/physics/gravity.js new file mode 100644 index 00000000..a741a997 --- /dev/null +++ b/examples/physics/gravity.js @@ -0,0 +1,39 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create }); + +function preload() { + + game.load.image('ilkke', 'assets/sprites/ilkke.png'); + +} + +var sprite1; +var sprite2; +var sprite3; + +function create() { + + game.stage.backgroundColor = '#2d2d2d'; + + // Set the world (global) gravity + game.physics.gravity.y = 100; + + // Sprite 1 will use the World (global) gravity + sprite1 = game.add.sprite(300, 32, 'ilkke'); + sprite1.body.collideWorldBounds = true; + sprite1.body.bounce.y = 0.8; + + // Sprite 2 is set to ignore the global gravity and use its own value + sprite2 = game.add.sprite(400, 32, 'ilkke'); + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.y = 0.8; + sprite2.body.allowGravity = false; + sprite2.body.gravity.y = 100; + + // Sprite 3 will use both the global gravity and its own value + sprite3 = game.add.sprite(500, 32, 'ilkke'); + sprite3.body.collideWorldBounds = true; + sprite3.body.bounce.y = 0.8; + sprite3.body.gravity.y = 100; + +} diff --git a/examples/physics/launcher follow world.js b/examples/physics/launcher follow world.js new file mode 100644 index 00000000..e29bdbc1 --- /dev/null +++ b/examples/physics/launcher follow world.js @@ -0,0 +1,149 @@ +// mods by Patrick OReilly +// twitter: @pato_reilly + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('background','assets/misc/starfield.jpg'); + game.load.image('player','assets/sprites/phaser-dude.png'); + game.load.image('analog', 'assets/tests/fusia.png'); + game.load.image('arrow', 'assets/sprites/longarrow2.png'); +} + +var myTween; +var player; +var cursors; +var arrow; +var catchFlag = false; +var launchVelocity = 0; +var launched; + +function create() { + + game.world.setBounds(0, 0, 5000, 600); + game.add.tileSprite(0, 0, 5000, 600, 'background'); + + var graphics = game.add.graphics(0,0); + graphics.beginFill(0x049e0c); + graphics.drawRect(395, 400, 10, 250); + + analog = game.add.sprite(400, 400, 'analog'); + analog.width = 8; + analog.rotation = 220; + analog.alpha = 0; + analog.anchor.setTo(0.5, 0.0); + + arrow = game.add.sprite(400, 400, 'arrow'); + arrow.anchor.setTo(0.1, 0.5); + arrow.alpha = 0; + + player = game.add.sprite(150, 320, 'player'); + player.anchor.setTo(0.5, 0.5); + player.body.collideWorldBounds = true; + player.body.bounce.setTo(0.9, 0.9); + player.body.linearDamping = 0.2; + player.body.gravity.setTo(0, 8); + + // Enable input. + player.inputEnabled = true; + player.input.start(0, true); + player.events.onInputDown.add(set); + player.events.onInputUp.add(launch); + //player.events.onInputOut.add(launch); + + // this tween is to make the camera return to left side of world when done launching + // so it is not used until then + myTween = game.add.tween(player).to({x: 150}, 5000, Phaser.Easing.Linear.None); + myTween.onComplete.add(reappear, this); + game.camera.follow(player, Phaser.Camera.FOLLOW_TOPDOWN); +} + +function reappear() { + + launched = false; + player.alpha = 1; +} + +function set(player,pointer) { + + //disallow launching until reset + if (!launched) + { + catchFlag = true; + game.camera.follow(null); + player.body.gravity.setTo(0,0); + player.body.velocity.setTo(0,0); + } +} + +function launch() { + + if (catchFlag) + { + catchFlag = false; + launched = true; + game.camera.follow(player, Phaser.Camera.FOLLOW_TOPDOWN); + + arrow.alpha = 0; + analog.alpha = 0; + Xvector = (arrow.x - player.x)*3.8; + Yvector = (arrow.y - player.y)*3.8; + player.body.gravity.setTo(0,8); + player.body.velocity.setTo(Xvector,Yvector); + } +} + +function update() { + + arrow.rotation = game.physics.angleBetween(arrow, player); + + // Track the player sprite to the mouse + if (catchFlag) + { + distance = game.physics.distanceToPointer(arrow); + theta = game.physics.angleToPointer(arrow); + + // Govern the distance the sprite is dragged away from launch post + if (distance > 300) + { + distance = 300; + adjacentX = Math.cos(theta) * distance; + oppositeY = Math.sin(theta) * distance; + player.x = 400 + adjacentX; + player.y = 400 + oppositeY; + analog.height = distance; + } + else + { + player.x = game.input.activePointer.worldX; + player.y = game.input.activePointer.worldY; + analog.height = distance; + } + + arrow.alpha = 1; + analog.alpha = 0.5; + analog.rotation = arrow.rotation - Math.PI/2; + launchVelocity = analog.height; + } + + //check sprite motion and if done, return camera to left side of world + var tweening = myTween.isRunning; + + if (!tweening && launched && (player.x >= game.world.width-20 || player.body.deltaX() == 0)) + { + player.body.velocity.setTo(0, 0); + player.alpha = 0; + myTween.start(); + } + +} + +function render() { + + game.debug.renderText("Drag the sprite and release to launch", 32, 32, 'rgb(0,255,0)'); + game.debug.renderCameraInfo(game.camera, 32, 64); + game.debug.renderSpriteCoords(player, 32, 150); + game.debug.renderText("Launch Velocity: " + parseInt(launchVelocity), 550, 32, 'rgb(0,255,0)'); + +} diff --git a/examples/physics/launcher follow.js b/examples/physics/launcher follow.js new file mode 100644 index 00000000..43478243 --- /dev/null +++ b/examples/physics/launcher follow.js @@ -0,0 +1,102 @@ +// mods by Patrick OReilly +// twitter: @pato_reilly + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('background','assets/misc/starfield.jpg'); + game.load.image('player','assets/sprites/phaser-dude.png'); + game.load.image('analog', 'assets/tests/fusia.png'); + game.load.image('arrow', 'assets/sprites/longarrow2.png'); + +} + +var player; +var cursors; +var arrow; +var catchFlag = false; +var launchVelocity = 0; + +function create() { + + game.world.setBounds(0, 0, 3400, 1000); + game.add.tileSprite(0, 0, 3400, 1000, 'background'); + + analog = game.add.sprite(200, 450, 'analog'); + analog.width = 8; + analog.rotation = 220; + analog.alpha = 0; + analog.anchor.setTo(0.5, 0.0); + + arrow = game.add.sprite(200, 450, 'arrow'); + arrow.anchor.setTo(0.1, 0.5); + arrow.alpha = 0; + + player = game.add.sprite(150, 320, 'player'); + player.anchor.setTo(0.5, 0.5); + player.body.collideWorldBounds = true; + player.body.bounce.setTo(0.9, 0.9); + player.body.linearDamping = 0.2; + + // Enable input. + player.inputEnabled = true; + player.input.start(0, true); + player.events.onInputDown.add(set); + player.events.onInputUp.add(launch); + + game.camera.follow(player, Phaser.Camera.FOLLOW_TOPDOWN); + +} + +function set(player,pointer) { + + catchFlag = true; + game.camera.follow(null); + + player.body.velocity.setTo(0, 0); + arrow.reset(player.x, player.y); + analog.reset(player.x, player.y); + +} + +function launch() { + + catchFlag = false; + game.camera.follow(player, Phaser.Camera.FOLLOW_TOPDOWN); + + arrow.alpha = 0; + analog.alpha = 0; + Xvector = (arrow.x - player.x) * 4.1; + Yvector = (arrow.y - player.y) * 4.1; + player.body.velocity.setTo(Xvector,Yvector); + +} + +function update() { + + arrow.rotation = game.physics.angleBetween(arrow, player); + + if (catchFlag == true) + { + // Track the ball sprite to the mouse + player.x = game.input.activePointer.worldX; + player.y = game.input.activePointer.worldY; + + arrow.alpha = 1; + analog.alpha = 0.5; + analog.rotation = arrow.rotation - 3.14 / 2; + analog.height = game.physics.distanceBetween(arrow, player); + launchVelocity = analog.height; + } + +} + +function render() { + + game.debug.renderText("Drag the sprite and release to launch", 32, 32, 'rgb(0,255,0)'); + game.debug.renderCameraInfo(game.camera, 32, 64); + game.debug.renderSpriteCoords(player, 32, 150); + game.debug.renderText("Launch Velocity: " + parseInt(launchVelocity), 550, 32, 'rgb(0,255,0)'); + +} diff --git a/examples/physics/launcher.js b/examples/physics/launcher.js new file mode 100644 index 00000000..590a6fe7 --- /dev/null +++ b/examples/physics/launcher.js @@ -0,0 +1,103 @@ +// mods by Patrick OReilly +// twitter: @pato_reilly + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('analog', 'assets/tests/fusia.png'); + game.load.image('arrow', 'assets/sprites/longarrow2.png'); + game.load.image('ball', 'assets/sprites/pangball.png'); + +} + +var arrow; +var ball; +var catchFlag = false; +var launchVelocity = 0; + +function create() { + + // set global gravity + game.physics.gravity.y = 200; + game.stage.backgroundColor = '#0072bc'; + + var graphics = game.add.graphics(0,0); + graphics.beginFill(0x049e0c); + graphics.drawRect(395, 350, 10, 250); + + analog = game.add.sprite(400, 350, 'analog'); + analog.body.allowGravity = false; + analog.width = 8; + analog.rotation = 220; + analog.alpha = 0; + analog.anchor.setTo(0.5, 0.0); + + arrow = game.add.sprite(400, 350, 'arrow'); + arrow.anchor.setTo(0.1, 0.5); + arrow.body.allowGravity = false; + arrow.alpha = 0; + + ball = game.add.sprite(100, 400, 'ball'); + ball.anchor.setTo(0.5, 0.5); + ball.body.collideWorldBounds = true; + ball.body.bounce.setTo(0.9, 0.9); + + // Enable input. + ball.inputEnabled = true; + ball.input.start(0, true); + ball.events.onInputDown.add(set); + ball.events.onInputUp.add(launch); + +} + +function set(ball, pointer) { + + ball.body.velocity.setTo(0, 0); + ball.body.allowGravity = false; + catchFlag = true; + +} + +function launch() { + + catchFlag = false; + + arrow.alpha = 0; + analog.alpha = 0; + Xvector = (arrow.x - ball.x) * 3; + Yvector = (arrow.y - ball.y) * 3; + ball.body.allowGravity = true; + ball.body.velocity.setTo(Xvector, Yvector); + +} + +function update() { + + arrow.rotation = game.physics.angleBetween(arrow, ball); + + if (catchFlag == true) + { + // Track the ball sprite to the mouse + ball.x = game.input.activePointer.worldX; + ball.y = game.input.activePointer.worldY; + + arrow.alpha = 1; + analog.alpha = 0.5; + analog.rotation = arrow.rotation - 3.14 / 2; + analog.height = game.physics.distanceToPointer(arrow); + launchVelocity = analog.height; + } + +} + +function render() { + + game.debug.renderText("Drag the ball and release to launch", 32, 32); + + game.debug.renderBodyInfo(ball, 32, 64); + + // game.debug.renderSpriteInfo(ball, 32, 64); + // game.debug.renderText("Launch Velocity: " + parseInt(launchVelocity), 32, 250); + +} diff --git a/examples/physics/mass velocity test.js b/examples/physics/mass velocity test.js index 400716d9..433b6040 100644 --- a/examples/physics/mass velocity test.js +++ b/examples/physics/mass velocity test.js @@ -15,25 +15,34 @@ function create() { aliens = game.add.group(); + game.physics.gravity.y = 100; + for (var i = 0; i < 50; i++) { var s = aliens.create(game.world.randomX, game.world.randomY, 'baddie'); s.name = 'alien' + s; s.body.collideWorldBounds = true; s.body.bounce.setTo(0.8, 0.8); + s.body.linearDamping = 0; + s.body.minVelocity.setTo(0, 0); s.body.velocity.setTo(10 + Math.random() * 40, 10 + Math.random() * 40); } car = game.add.sprite(400, 300, 'car'); + car.name = 'car'; car.anchor.setTo(0.5, 0.5); car.body.collideWorldBounds = true; - car.body.bounce.setTo(0.8, 0.8); + // car.body.bounce.setTo(0.8, 0.8); car.body.allowRotation = true; + // car.body.immovable = true; + // car.body.minBounceVelocity = 0; } function update() { + game.physics.collide(car, aliens); + car.body.velocity.x = 0; car.body.velocity.y = 0; car.body.angularVelocity = 0; @@ -52,12 +61,21 @@ function update() { car.body.velocity.copyFrom(game.physics.velocityFromAngle(car.angle, 300)); } - game.physics.collide(car, aliens); - } function render() { - game.debug.renderSpriteInfo(car, 32, 32); + for (var i = 0; i < aliens._container.children.length; i++) + { + game.debug.renderPolygon(aliens._container.children[i].body.polygons); + } + + game.debug.renderPolygon(car.body.polygons); + + // game.debug.renderBodyInfo(aliens._container.children[0], 32, 32); + game.debug.renderBodyInfo(aliens._container.children[0], 32, 32); + + // game.debug.renderBodyInfo(car, 16, 24); + // game.debug.renderBodyInfo(aliens.getFirstAlive(), 16, 24); } diff --git a/examples/physics/ship trail.js b/examples/physics/ship trail.js new file mode 100644 index 00000000..43f79c05 --- /dev/null +++ b/examples/physics/ship trail.js @@ -0,0 +1,65 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('chunk', 'assets/sprites/chunk.png'); + game.load.image('arrow', 'assets/sprites/asteroids_ship.png'); + +} + +var sprite; +var bmd; + +function create() { + + // Click on the left or right of the game to shoot the space ship in that direction + + game.stage.backgroundColor = '#124184'; + + bmd = game.add.bitmapData(800, 600); + bmd.fillStyle('#ffffff'); + var bg = game.add.sprite(0, 0, bmd); + bg.body.moves = false; + + game.physics.gravity.y = 100; + + sprite = game.add.sprite(32, 450, 'arrow'); + sprite.anchor.setTo(0.5, 0.5); + + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(0.8, 0.8); + + sprite.body.linearDamping = 0.1; + + game.input.onDown.add(launch, this); + +} + +function launch() { + + if (game.input.x < 400) + { + sprite.body.velocity.setTo(-200, -200); + } + else + { + sprite.body.velocity.setTo(200, -200); + } + +} + +function update() { + + sprite.rotation = sprite.body.angle; + + bmd.fillStyle('#ffff00'); + bmd.fillRect(sprite.x, sprite.y, 2, 2); + +} + +function render() { + + game.debug.renderBodyInfo(sprite, 16, 24); + +} diff --git a/examples/physics/snake.js b/examples/physics/snake.js new file mode 100644 index 00000000..b303cb88 --- /dev/null +++ b/examples/physics/snake.js @@ -0,0 +1,82 @@ +// Snake by Patrick OReilly and Richard Davey +// Twitter: @pato_reilly Web: http://patricko.byethost9.com + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update,render : render }); + +function preload() { + + game.load.image('ball','assets/sprites/shinyball.png'); + +} + +var snakeHead; //head of snake sprite +var snakeSection = new Array(); //array of sprites that make the snake body sections +var snakePath = new Array(); //arrary of positions(points) that have to be stored for the path the sections follow +var numSnakeSections = 30; //number of snake body sections +var snakeSpacer = 6; //parameter that sets the spacing between sections + +function create() { + + game.world.setBounds(0, 0, 800, 600); + + cursors = game.input.keyboard.createCursorKeys(); + + snakeHead = game.add.sprite(400, 300, 'ball'); + snakeHead.anchor.setTo(0.5, 0.5); + + // Init snakeSection array + for (var i = 1; i <= numSnakeSections-1; i++) + { + snakeSection[i] = game.add.sprite(400, 300, 'ball'); + snakeSection[i].anchor.setTo(0.5, 0.5); + } + + // Init snakePath array + for (var i = 0; i <= numSnakeSections * snakeSpacer; i++) + { + snakePath[i] = new Phaser.Point(400, 300); + } + +} + +function update() { + + snakeHead.body.velocity.setTo(0, 0); + snakeHead.body.angularVelocity = 0; + + if (cursors.up.isDown) + { + snakeHead.body.velocity.copyFrom(game.physics.velocityFromAngle(snakeHead.angle, 300)); + + // Everytime the snake head moves, insert the new location at the start of the array, + // and knock the last position off the end + + var part = snakePath.pop(); + + part.setTo(snakeHead.x, snakeHead.y); + + snakePath.unshift(part); + + for (var i = 1; i <= numSnakeSections - 1; i++) + { + snakeSection[i].x = (snakePath[i * snakeSpacer]).x; + snakeSection[i].y = (snakePath[i * snakeSpacer]).y; + } + } + + if (cursors.left.isDown) + { + snakeHead.body.angularVelocity = -300; + } + else if (cursors.right.isDown) + { + snakeHead.body.angularVelocity = 300; + } + +} + +function render() { + + game.debug.renderSpriteInfo(snakeHead, 32, 32); + +} \ No newline at end of file diff --git a/examples/sideview.html b/examples/sideview.html index 8861fd44..3b2cfd4c 100644 --- a/examples/sideview.html +++ b/examples/sideview.html @@ -19,11 +19,11 @@ - + \ No newline at end of file diff --git a/examples/tile sprites/animated tiling sprite.js b/examples/tile sprites/animated tiling sprite.js index 9977d266..21989bbc 100644 --- a/examples/tile sprites/animated tiling sprite.js +++ b/examples/tile sprites/animated tiling sprite.js @@ -5,39 +5,44 @@ function preload() { game.load.image('disk', 'assets/sprites/p2.jpeg'); } -var s; +var tilesprite; +var cursors; var count = 0; function create() { - s = game.add.tileSprite(0, 0, 512, 512, 'disk'); + + tilesprite = game.add.tileSprite(0, 0, 512, 512, 'disk'); + + cursors = game.input.keyboard.createCursorKeys(); + } function update() { count += 0.005 - s.tileScale.x = 2 + Math.sin(count); - s.tileScale.y = 2 + Math.cos(count); + tilesprite.tileScale.x = 2 + Math.sin(count); + tilesprite.tileScale.y = 2 + Math.cos(count); - s.tilePosition.x += 1; - s.tilePosition.y += 1; + tilesprite.tilePosition.x += 1; + tilesprite.tilePosition.y += 1; - if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + if (cursors.left.isDown) { - s.x -= 4; + tilesprite.x -= 4; } - else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + else if (cursors.right.isDown) { - s.x += 4; + tilesprite.x += 4; } - if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + if (cursors.up.isDown) { - s.y -= 4; + tilesprite.y -= 4; } - else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) + else if (cursors.down.isDown) { - s.y += 4; + tilesprite.y += 4; } } diff --git a/examples/tile sprites/colliding with tiling sprite.js b/examples/tile sprites/colliding with tiling sprite.js new file mode 100644 index 00000000..7f95f935 --- /dev/null +++ b/examples/tile sprites/colliding with tiling sprite.js @@ -0,0 +1,60 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +var ball; +var tilesprite; +var cursors; + +function preload() { + + game.load.image('starfield', 'assets/misc/starfield.jpg'); + game.load.image('ball', 'assets/sprites/pangball.png'); + +} + +function create() { + + ball = game.add.sprite(400, 0, 'ball'); + + ball.body.gravity.y = 200; + ball.body.bounce.y = 1; + + tilesprite = game.add.tileSprite(300, 450, 200, 100, 'starfield'); + tilesprite.body.immovable = true; + tilesprite.body.setRectangle(200, 100, 0, 0); + + cursors = game.input.keyboard.createCursorKeys(); + +} + +function update() { + + game.physics.collide(ball, tilesprite); + + if (cursors.left.isDown) + { + tilesprite.x -= 8; + tilesprite.tilePosition.x -= 8; + } + else if (cursors.right.isDown) + { + tilesprite.x += 8; + tilesprite.tilePosition.x += 8; + } + + if (cursors.up.isDown) + { + tilesprite.tilePosition.y += 8; + } + else if (cursors.down.isDown) + { + tilesprite.tilePosition.y -= 8; + } + +} + +function render() { + + game.debug.renderPhysicsBody(tilesprite.body); + +} \ No newline at end of file diff --git a/examples/tile sprites/tiling sprite.js b/examples/tile sprites/tiling sprite.js index 97485825..89e671f3 100644 --- a/examples/tile sprites/tiling sprite.js +++ b/examples/tile sprites/tiling sprite.js @@ -1,34 +1,41 @@ var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); -var s; +var tilesprite; +var cursors; function preload() { + game.load.image('starfield', 'assets/misc/starfield.jpg'); + } function create() { - s = game.add.tileSprite(0, 0, 800, 600, 'starfield'); + + tilesprite = game.add.tileSprite(0, 0, 800, 600, 'starfield'); + + cursors = game.input.keyboard.createCursorKeys(); + } function update() { - if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + if (cursors.left.isDown) { - s.tilePosition.x += 8; + tilesprite.tilePosition.x += 8; } - else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + else if (cursors.right.isDown) { - s.tilePosition.x -= 8; + tilesprite.tilePosition.x -= 8; } - if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + if (cursors.up.isDown) { - s.tilePosition.y += 8; + tilesprite.tilePosition.y += 8; } - else if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) + else if (cursors.down.isDown) { - s.tilePosition.y -= 8; + tilesprite.tilePosition.y -= 8; } } diff --git a/examples/tilemaps/create from objects.js b/examples/tilemaps/create from objects.js new file mode 100644 index 00000000..ce918d3c --- /dev/null +++ b/examples/tilemaps/create from objects.js @@ -0,0 +1,104 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.tilemap('map', 'assets/tilemaps/maps/features_test.json', null, Phaser.Tilemap.TILED_JSON); + + game.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png'); + game.load.image('walls_1x2', 'assets/tilemaps/tiles/walls_1x2.png'); + game.load.image('tiles2', 'assets/tilemaps/tiles/tiles2.png'); + + game.load.image('phaser', 'assets/sprites/arrow.png'); + game.load.spritesheet('coin', 'assets/sprites/coin.png', 32, 32); + +} + +var cursors; +var map; +var coins; + +var layer; +var sprite; + +function create() { + + map = game.add.tilemap('map'); + + map.addTilesetImage('ground_1x1'); + map.addTilesetImage('walls_1x2'); + map.addTilesetImage('tiles2'); + + map.setCollisionBetween(1, 12); + + layer = map.createLayer('Tile Layer 1'); + + // layer.debug = true; + + layer.resizeWorld(); + + // Here we create our coins group + coins = game.add.group(); + + // And now we convert all of the Tiled objects with an ID of 34 into sprites within the coins group + map.createFromObjects('Object Layer 1', 34, 'coin', 0, true, false, coins); + + // Add animations to all of the coin sprites + coins.callAll('animations.add', 'animations', 'spin', [0, 1, 2, 3, 4, 5], 10, true); + coins.callAll('animations.play', 'animations', 'spin'); + + sprite = game.add.sprite(260, 100, 'phaser'); + sprite.anchor.setTo(0.5, 0.5); + + // This adjusts the collision body size. + sprite.body.setRectangle(16, 16, 25, 15); + + // We'll set a lower max angular velocity here to keep it from going totally nuts + sprite.body.maxAngular = 500; + + // Apply a drag otherwise the sprite will just spin and never slow down + sprite.body.angularDrag = 50; + + game.camera.follow(sprite); + + cursors = game.input.keyboard.createCursorKeys(); + +} + +function update() { + + game.physics.collide(sprite, layer); + game.physics.overlap(sprite, coins, collectCoin, null, this); + + sprite.body.velocity.x = 0; + sprite.body.velocity.y = 0; + sprite.body.angularVelocity = 0; + + if (cursors.left.isDown) + { + sprite.body.angularVelocity = -300; + } + else if (cursors.right.isDown) + { + sprite.body.angularVelocity = 300; + } + + if (cursors.up.isDown) + { + game.physics.velocityFromAngle(sprite.angle, 300, sprite.body.velocity); + } + + +} + +function collectCoin(player, coin) { + + coin.kill(); + +} + +function render() { + + game.debug.renderPhysicsBody(sprite.body); + +} \ No newline at end of file diff --git a/examples/tilemaps/fill tiles.js b/examples/tilemaps/fill tiles.js index 9670ce19..6f022f8b 100644 --- a/examples/tilemaps/fill tiles.js +++ b/examples/tilemaps/fill tiles.js @@ -3,14 +3,13 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: function preload() { - game.load.tilemap('desert', 'assets/maps/desert.json', null, Phaser.Tilemap.TILED_JSON); - game.load.tileset('tiles', 'assets/tiles/tmw_desert_spacing.png', 32, 32, -1, 1, 1); + game.load.tilemap('desert', 'assets/tilemaps/maps/desert.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('tiles', 'assets/tilemaps/tiles/tmw_desert_spacing.png'); game.load.image('car', 'assets/sprites/car90.png'); } var map; -var tileset; var layer; var cursors; @@ -20,9 +19,9 @@ function create() { map = game.add.tilemap('desert'); - tileset = game.add.tileset('tiles'); - - layer = game.add.tilemapLayer(0, 0, 800, 600, tileset, map, 0); + map.addTilesetImage('Desert', 'tiles'); + + layer = map.createLayer('Ground'); layer.resizeWorld(); @@ -39,7 +38,7 @@ function create() { function fillTiles() { - map.fill(31, layer.getTileX(sprite.x), layer.getTileY(sprite.y), 6, 6); + map.fill(31, layer.getTileX(sprite.x), layer.getTileY(sprite.y), 8, 8); } diff --git a/examples/tilemaps/mapcollide.js b/examples/tilemaps/mapcollide.js index 8e1726db..b5b3ece4 100644 --- a/examples/tilemaps/mapcollide.js +++ b/examples/tilemaps/mapcollide.js @@ -3,8 +3,8 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: function preload() { - game.load.tilemap('mario', 'assets/maps/mario1.json', null, Phaser.Tilemap.TILED_JSON); - game.load.tileset('marioTiles', 'assets/maps/mario1.png',16,16); + game.load.tilemap('mario', 'assets/tilemaps/maps/super_mario.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('tiles', 'assets/tilemaps/tiles/super_mario.png'); game.load.image('player', 'assets/sprites/phaser-dude.png'); } @@ -21,30 +21,31 @@ function create() { map = game.add.tilemap('mario'); - tileset = game.add.tileset('marioTiles'); + map.addTilesetImage('SuperMarioBros-World1-1', 'tiles'); - // floor - tileset.setCollisionRange(80, 97, true, true, true, true); - - // one-ways - tileset.setCollisionRange(15, 17, true, true, false, true); - - layer = game.add.tilemapLayer(0, 0, map.layers[0].width*tileset.tileWidth, 600, tileset, map, 0); - - layer.fixedToCamera=false; - - layer.resizeWorld(); + // 14 = ? block + // map.setCollisionBetween(14, 15); + map.setCollisionBetween(15, 16); + map.setCollisionBetween(20, 25); + map.setCollisionBetween(27, 29); + map.setCollision(40); + layer = map.createLayer('World1'); + + // Un-comment this on to see the collision tiles + // layer.debug = true; + + layer.resizeWorld(); p = game.add.sprite(32, 32, 'player'); - p.body.gravity.y = 10; - p.body.bounce.y = 0.4; + game.physics.gravity.y = 250; + + p.body.bounce.y = 0.2; + p.body.linearDamping = 1; p.body.collideWorldBounds = true; - - game.camera.follow(p); cursors = game.input.keyboard.createCursorKeys(); @@ -53,21 +54,17 @@ function create() { function update() { - game.physics.collide(p,layer); + game.physics.collide(p, layer); p.body.velocity.x = 0; if (cursors.up.isDown) { - if (p.body.touching.down) + if (p.body.onFloor()) { - p.body.velocity.y = -400; + p.body.velocity.y = -200; } } - else if (cursors.down.isDown) - { - // game.camera.y += 4; - } if (cursors.left.isDown) { @@ -82,8 +79,7 @@ function update() { function render() { - game.debug.renderCameraInfo(game.camera, 32, 32); - // game.debug.renderSpriteCorners(p); - game.debug.renderSpriteCollision(p, 32, 320); + game.debug.renderCameraInfo(game.camera, 420, 320); + game.debug.renderPhysicsBody(p.body); } diff --git a/examples/tilemaps/mario.js b/examples/tilemaps/mario.js index 01cdb58a..dc207145 100644 --- a/examples/tilemaps/mario.js +++ b/examples/tilemaps/mario.js @@ -3,14 +3,13 @@ var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: p function preload() { - game.load.tilemap('mario', 'assets/maps/mario1.json', null, Phaser.Tilemap.TILED_JSON); - game.load.tileset('tiles', 'assets/maps/mario1.png',16,16); + game.load.tilemap('mario', 'assets/tilemaps/maps/super_mario.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('tiles', 'assets/tilemaps/tiles/super_mario.png'); game.load.image('player', 'assets/sprites/phaser-dude.png'); } var map; -var tileset; var layer; var p; var cursors; @@ -21,18 +20,13 @@ function create() { map = game.add.tilemap('mario'); - + map.addTilesetImage('SuperMarioBros-World1-1', 'tiles'); - tileset = game.add.tileset('tiles'); + layer = map.createLayer('World1'); - - layer = game.add.tilemapLayer(0, 0, map.layers[0].width*tileset.tileWidth, 600, tileset, map, 0); - - layer.fixedToCamera=false; - layer.resizeWorld(); - cursors=game.input.keyboard.createCursorKeys(); + cursors = game.input.keyboard.createCursorKeys(); } diff --git a/examples/tilemaps/paint tiles.js b/examples/tilemaps/paint tiles.js index 65bc94c0..a51df92b 100644 --- a/examples/tilemaps/paint tiles.js +++ b/examples/tilemaps/paint tiles.js @@ -3,25 +3,26 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: function preload() { - game.load.tilemap('desert', 'assets/maps/desert.json', null, Phaser.Tilemap.TILED_JSON); - game.load.tileset('tiles', 'assets/tiles/tmw_desert_spacing.png', 32, 32, -1, 1, 1); + game.load.tilemap('desert', 'assets/tilemaps/maps/desert.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('tiles', 'assets/tilemaps/tiles/tmw_desert_spacing.png'); } var map; -var tileset; var layer; var marker; -var currentTile = 0; +var currentTile; function create() { map = game.add.tilemap('desert'); - tileset = game.add.tileset('tiles'); - - layer = game.add.tilemapLayer(0, 0, 800, 600, tileset, map, 0); + map.addTilesetImage('Desert', 'tiles'); + + currentTile = map.getTile(2, 3); + + layer = map.createLayer('Ground'); layer.resizeWorld(); diff --git a/examples/tilemaps/randomise tiles.js b/examples/tilemaps/randomise tiles.js index 1adf705e..1eb356cd 100644 --- a/examples/tilemaps/randomise tiles.js +++ b/examples/tilemaps/randomise tiles.js @@ -3,29 +3,33 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: function preload() { - game.load.tilemap('desert', 'assets/maps/desert.json', null, Phaser.Tilemap.TILED_JSON); - game.load.tileset('tiles', 'assets/tiles/tmw_desert_spacing.png', 32, 32, -1, 1, 1); + game.load.tilemap('desert', 'assets/tilemaps/maps/desert.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('tiles', 'assets/tilemaps/tiles/tmw_desert_spacing.png'); game.load.image('car', 'assets/sprites/car90.png'); } var map; -var tileset; var layer; var cursors; var sprite; +var marker; function create() { map = game.add.tilemap('desert'); - tileset = game.add.tileset('tiles'); - - layer = game.add.tilemapLayer(0, 0, 800, 600, tileset, map, 0); + map.addTilesetImage('Desert', 'tiles'); + + layer = map.createLayer('Ground'); layer.resizeWorld(); + marker = game.add.graphics(); + marker.lineStyle(2, 0x00bff3, 1); + marker.drawRect(0, 0, 32 * 6, 32 * 6); + sprite = game.add.sprite(450, 80, 'car'); sprite.anchor.setTo(0.5, 0.5); @@ -33,24 +37,21 @@ function create() { cursors = game.input.keyboard.createCursorKeys(); + game.input.onDown.add(randomiseTiles, this); } function randomiseTiles() { - // This will replace every instance of tile 31 (cactus plant) with tile 46 (the sign post). - // It does this across the whole layer of the map unless a region is specified. - - // You can also pass in x, y, width, height values to control the area in which the replace happens - - map.shuffle(layer.getTileX(sprite.x), layer.getTileY(sprite.y), 6, 6); + map.random(layer.getTileX(sprite.x), layer.getTileY(sprite.y), 6, 6); } function update() { - game.physics.collide(sprite, layer); + marker.x = layer.getTileX(sprite.x) * 32; + marker.y = layer.getTileY(sprite.y) * 32; sprite.body.velocity.x = 0; sprite.body.velocity.y = 0; diff --git a/examples/tilemaps/replace tiles.js b/examples/tilemaps/replace tiles.js index 45dd75cb..b3df0c24 100644 --- a/examples/tilemaps/replace tiles.js +++ b/examples/tilemaps/replace tiles.js @@ -3,14 +3,13 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: function preload() { - game.load.tilemap('desert', 'assets/maps/desert.json', null, Phaser.Tilemap.TILED_JSON); - game.load.tileset('tiles', 'assets/tiles/tmw_desert_spacing.png', 32, 32, -1, 1, 1); + game.load.tilemap('desert', 'assets/tilemaps/maps/desert.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('tiles', 'assets/tilemaps/tiles/tmw_desert_spacing.png'); game.load.image('car', 'assets/sprites/car90.png'); } var map; -var tileset; var layer; var cursors; @@ -20,9 +19,9 @@ function create() { map = game.add.tilemap('desert'); - tileset = game.add.tileset('tiles'); - - layer = game.add.tilemapLayer(0, 0, 800, 600, tileset, map, 0); + map.addTilesetImage('Desert', 'tiles'); + + layer = map.createLayer('Ground'); layer.resizeWorld(); @@ -50,8 +49,6 @@ function replaceTiles() { function update() { - game.physics.collide(sprite, layer); - sprite.body.velocity.x = 0; sprite.body.velocity.y = 0; sprite.body.angularVelocity = 0; diff --git a/examples/tilemaps/sci fly.js b/examples/tilemaps/sci fly.js index c0e15f28..2e2d502d 100644 --- a/examples/tilemaps/sci fly.js +++ b/examples/tilemaps/sci fly.js @@ -1,81 +1,60 @@ -var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); function preload() { - game.load.tilemap('level3', 'assets/maps/cybernoid.json', null, Phaser.Tilemap.TILED_JSON); - game.load.tileset('tiles', 'assets/maps/cybernoid.png', 16, 16); + game.load.tilemap('level3', 'assets/tilemaps/maps/cybernoid.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('tiles', 'assets/tilemaps/tiles/cybernoid.png', 16, 16); game.load.image('phaser', 'assets/sprites/phaser-ship.png'); - game.load.image('diamond', 'assets/sprites/chunk.png'); + game.load.image('chunk', 'assets/sprites/chunk.png'); } var map; -var tileset; var layer; var cursors; -var overlap; var sprite; var emitter; function create() { - game.stage.backgroundColor = '#3d3d3d'; - // A Tilemap object just holds the data needed to describe the map (i.e. the json exported from Tiled, or the CSV exported from elsewhere). // You can add your own data or manipulate the data (swap tiles around, etc) but in order to display it you need to create a TilemapLayer. map = game.add.tilemap('level3'); - // A Tileset is a single image containing a strip of tiles. Each tile is broken down into its own Phaser.Tile object on import. - // You can set properties on the Tile objects, such as collision, n-way movement and meta data. - // A Tilemap uses a Tileset to render. The indexes in the map corresponding to the Tileset indexes. - // This way multiple levels can share the same single Tileset without requiring one each. - tileset = game.add.tileset('tiles'); - + map.addTilesetImage('CybernoidMap3BG_bank.png', 'tiles'); + + layer = map.createLayer(0); + // Basically this sets EVERY SINGLE tile to fully collide on all faces - tileset.setCollisionRange(0, tileset.total - 1, true, true, true, true); + map.setCollisionByExclusion([7, 32, 35, 36, 47]); - // And this turns off collision on the only tile we don't want collision on :) - tileset.setCollision(6, false, false, false, false); - tileset.setCollision(31, false, false, false, false); - tileset.setCollision(34, false, false, false, false); - tileset.setCollision(35, false, false, false, false); - tileset.setCollision(46, false, false, false, false); - - // A TilemapLayer consists of an x,y coordinate (position), a width and height, a Tileset and a Tilemap which it uses for map data. - // The x/y coordinates are in World space and you can place the tilemap layer anywhere in the world. - // The width/height is the rendered size of the layer in pixels, not the size of the map data itself. - - layer = game.add.tilemapLayer(0, 0, 800, 600, tileset, map, 0); + // layer.debug = true; layer.resizeWorld(); - sprite = game.add.sprite(450, 80, 'phaser'); - sprite.anchor.setTo(0.5, 0.5); - // sprite.angle = 45; - - game.camera.follow(sprite); - // game.camera.deadzone = new Phaser.Rectangle(160, 160, layer.renderWidth-320, layer.renderHeight-320); - cursors = game.input.keyboard.createCursorKeys(); emitter = game.add.emitter(0, 0, 200); - emitter.makeParticles('diamond'); + emitter.makeParticles('chunk'); emitter.minRotation = 0; emitter.maxRotation = 0; - emitter.gravity = 5; + emitter.gravity = 150; emitter.bounce.setTo(0.5, 0.5); - game.input.onDown.add(particleBurst, this); + sprite = game.add.sprite(200, 70, 'phaser'); + sprite.anchor.setTo(0.5, 0.5); + + game.camera.follow(sprite); } function particleBurst() { - emitter.x = game.input.worldX; - emitter.y = game.input.worldY; - emitter.start(true, 4000, null, 10); + emitter.x = sprite.x; + emitter.y = sprite.y; + emitter.start(true, 2000, null, 1); } @@ -90,30 +69,25 @@ function update() { if (cursors.up.isDown) { sprite.body.velocity.y = -150; + particleBurst(); } else if (cursors.down.isDown) { sprite.body.velocity.y = 150; + particleBurst(); } if (cursors.left.isDown) { sprite.body.velocity.x = -150; sprite.scale.x = -1; + particleBurst(); } else if (cursors.right.isDown) { sprite.body.velocity.x = 150; sprite.scale.x = 1; + particleBurst(); } } - - -function render() { - - game.debug.renderSpriteBounds(sprite); - // game.debug.renderSpriteInfo(sprite, 32, 32); - // game.debug.renderSpriteCoords(sprite, 32, 32); - -} \ No newline at end of file diff --git a/examples/tilemaps/shuffle tiles.js b/examples/tilemaps/shuffle tiles.js new file mode 100644 index 00000000..7ef6bfcf --- /dev/null +++ b/examples/tilemaps/shuffle tiles.js @@ -0,0 +1,82 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.tilemap('desert', 'assets/tilemaps/maps/desert.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('tiles', 'assets/tilemaps/tiles/tmw_desert_spacing.png'); + game.load.image('car', 'assets/sprites/car90.png'); + +} + +var map; +var layer; + +var cursors; +var sprite; +var marker; + +function create() { + + map = game.add.tilemap('desert'); + + map.addTilesetImage('Desert', 'tiles'); + + layer = map.createLayer('Ground'); + + layer.resizeWorld(); + + marker = game.add.graphics(); + marker.lineStyle(2, 0x00bff3, 1); + marker.drawRect(0, 0, 32 * 6, 32 * 6); + + sprite = game.add.sprite(450, 80, 'car'); + sprite.anchor.setTo(0.5, 0.5); + + game.camera.follow(sprite); + + cursors = game.input.keyboard.createCursorKeys(); + + + game.input.onDown.add(randomiseTiles, this); + +} + +function randomiseTiles() { + + map.shuffle(layer.getTileX(sprite.x), layer.getTileY(sprite.y), 6, 6); + +} + +function update() { + + marker.x = layer.getTileX(sprite.x) * 32; + marker.y = layer.getTileY(sprite.y) * 32; + + sprite.body.velocity.x = 0; + sprite.body.velocity.y = 0; + sprite.body.angularVelocity = 0; + + if (cursors.left.isDown) + { + sprite.body.angularVelocity = -200; + } + else if (cursors.right.isDown) + { + sprite.body.angularVelocity = 200; + } + + if (cursors.up.isDown) + { + sprite.body.velocity.copyFrom(game.physics.velocityFromAngle(sprite.angle, 300)); + } + +} + +function render() { + + game.debug.renderText('Click to randomise tiles', 32, 32, 'rgb(0,0,0)'); + game.debug.renderText('Tile X: ' + layer.getTileX(sprite.x), 32, 48, 'rgb(0,0,0)'); + game.debug.renderText('Tile Y: ' + layer.getTileY(sprite.y), 32, 64, 'rgb(0,0,0)'); + +} diff --git a/examples/tilemaps/swap tiles.js b/examples/tilemaps/swap tiles.js index 55c2bdd2..b8c3c669 100644 --- a/examples/tilemaps/swap tiles.js +++ b/examples/tilemaps/swap tiles.js @@ -3,14 +3,13 @@ var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: function preload() { - game.load.tilemap('desert', 'assets/maps/desert.json', null, Phaser.Tilemap.TILED_JSON); - game.load.tileset('tiles', 'assets/tiles/tmw_desert_spacing.png', 32, 32, -1, 1, 1); + game.load.tilemap('desert', 'assets/tilemaps/maps/desert.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('tiles', 'assets/tilemaps/tiles/tmw_desert_spacing.png'); game.load.image('car', 'assets/sprites/car90.png'); } var map; -var tileset; var layer; var cursors; @@ -20,9 +19,9 @@ function create() { map = game.add.tilemap('desert'); - tileset = game.add.tileset('tiles'); - - layer = game.add.tilemapLayer(0, 0, 800, 600, tileset, map, 0); + map.addTilesetImage('Desert', 'tiles'); + + layer = map.createLayer('Ground'); layer.resizeWorld(); @@ -50,8 +49,6 @@ function swapTiles() { function update() { - game.physics.collide(sprite, layer); - sprite.body.velocity.x = 0; sprite.body.velocity.y = 0; sprite.body.angularVelocity = 0; diff --git a/examples/tilemaps/tile callbacks.js b/examples/tilemaps/tile callbacks.js new file mode 100644 index 00000000..2bee92e4 --- /dev/null +++ b/examples/tilemaps/tile callbacks.js @@ -0,0 +1,102 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.tilemap('map', 'assets/tilemaps/maps/tile_collision_test.json', null, Phaser.Tilemap.TILED_JSON); + + game.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png'); + game.load.image('phaser', 'assets/sprites/arrow.png'); + game.load.spritesheet('coin', 'assets/sprites/coin.png', 32, 32); + +} + +var map; +var layer; + +var sprite; +var cursors; + +function create() { + + map = game.add.tilemap('map'); + + map.addTilesetImage('ground_1x1'); + map.addTilesetImage('coin'); + + map.setCollisionBetween(1, 12); + + map.setTileIndexCallback(26, hitCoin, this); + + map.setTileLocationCallback(2, 0, 1, 1, hitCoin, this); + + layer = map.createLayer('Tile Layer 1'); + + // layer.debug = true; + + layer.resizeWorld(); + + game.physics.gravity.y = 100; + + sprite = game.add.sprite(260, 100, 'phaser'); + sprite.anchor.setTo(0.5, 0.5); + + sprite.body.setRectangle(16, 16, 8, 8); + + // We'll set a lower max angular velocity here to keep it from going totally nuts + sprite.body.maxAngular = 500; + + // Apply a drag otherwise the sprite will just spin and never slow down + sprite.body.angularDrag = 50; + + // sprite.body.bounce.x = 0.8; + // sprite.body.bounce.y = 0.8; + + debugSprite = sprite; + + game.camera.follow(sprite); + + cursors = game.input.keyboard.createCursorKeys(); + +} + +function hitCoin(sprite, tile) { + + tile.tile.alpha = 0.2; + + layer.dirty = true; + + return false; + +} + +function update() { + + game.physics.collide(sprite, layer); + + sprite.body.velocity.x = 0; + sprite.body.velocity.y = 0; + sprite.body.angularVelocity = 0; + + if (cursors.left.isDown) + { + sprite.body.angularVelocity = -300; + } + else if (cursors.right.isDown) + { + sprite.body.angularVelocity = 300; + } + + if (cursors.up.isDown) + { + game.physics.velocityFromAngle(sprite.angle, 300, sprite.body.velocity); + } + +} + +function render() { + + // game.debug.renderBodyInfo(sprite, 16, 24); + // game.debug.renderPhysicsBody(sprite.body); + +} \ No newline at end of file diff --git a/examples/time/basic looped event.js b/examples/time/basic looped event.js new file mode 100644 index 00000000..67deca0c --- /dev/null +++ b/examples/time/basic looped event.js @@ -0,0 +1,43 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, render: render }); + +function preload() { + + game.load.image('ball', 'assets/sprites/pangball.png'); + +} + +var counter = 0; +var text = 0; + +function create() { + + game.stage.backgroundColor = '#6688ee'; + + text = game.add.text(game.world.centerX, game.world.centerY, 'Counter: 0', { font: "64px Arial", fill: "#ffffff", align: "center" }); + text.anchor.setTo(0.5, 0.5); + + // Here we'll create a basic looped event. + // A looped event is like a repeat event but with no limit, it will literally repeat itself forever, or until + + // The first parameter is how long to wait before the event fires. In this case 1 second (you could pass in 1000 as the value as well.) + // The next two parameters are the function to call ('updateCounter') and the context under which that will happen. + + game.time.events.loop(Phaser.Timer.SECOND, updateCounter, this); + +} + +function updateCounter() { + + counter++; + + text.content = 'Counter: ' + counter; + +} + +function render() { + + game.debug.renderText("Time until event: " + game.time.events.duration.toFixed(0), 32, 32); + game.debug.renderText("Next tick: " + game.time.events.next.toFixed(0), 32, 64); + +} diff --git a/examples/time/basic repeat event.js b/examples/time/basic repeat event.js new file mode 100644 index 00000000..63f15bee --- /dev/null +++ b/examples/time/basic repeat event.js @@ -0,0 +1,47 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, render: render }); + +function preload() { + + game.load.image('ball', 'assets/sprites/pangball.png'); + +} + +function create() { + + game.stage.backgroundColor = '#6688ee'; + + // Here we'll create a basic repeating event. + + // The way a repeating event works is that it is placed into the queue once, + // and when it runs its 'repeatCounter' is reduced by 1 and it's moved back into the queue again. + // To this end the queue will only ever have 1 event actually in it. + + // The first parameter is how long to wait before the event fires. In this case 2 seconds (you could pass in 2000 as the value as well.) + // The second parameter is how many times the event will run in total. Here we'll run it 10 times. + // The next two parameters are the function to call ('createBall') and the context under which that will happen. + + // Once the event has been called 10 times it will never be called again. + + game.time.events.repeat(Phaser.Timer.SECOND * 2, 10, createBall, this); + +} + +function createBall() { + + // A bouncey ball sprite just to visually see what's going on. + + var ball = game.add.sprite(game.world.randomX, 0, 'ball'); + + ball.body.gravity.y = 200; + ball.body.bounce.y = 0.5; + ball.body.collideWorldBounds = true; + +} + +function render() { + + game.debug.renderText("Time until event: " + game.time.events.duration.toFixed(0), 32, 32); + game.debug.renderText("Next tick: " + game.time.events.next.toFixed(0), 32, 64); + +} diff --git a/examples/time/basic timed event.js b/examples/time/basic timed event.js new file mode 100644 index 00000000..7c1ab20c --- /dev/null +++ b/examples/time/basic timed event.js @@ -0,0 +1,37 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, render: render }); + +function preload() { + + game.load.image('bisley', 'assets/pics/alex-bisleys_horsy_5.png'); + +} + +var picture; + +function create() { + + game.stage.backgroundColor = '#6688ee'; + + picture = game.add.sprite(game.world.centerX, game.world.centerY, 'bisley'); + picture.anchor.setTo(0.5, 0.5); + + // Here we'll create a basic timed event. This is a one-off event, it won't repeat or loop: + // The first parameter is how long to wait before the event fires. In this case 4 seconds (you could pass in 4000 as the value as well.) + // The next parameter is the function to call ('fadePicture') and finally the context under which that will happen. + + game.time.events.add(Phaser.Timer.SECOND * 4, fadePicture, this); + +} + +function fadePicture() { + + game.add.tween(picture).to( { alpha: 0 }, 2000, Phaser.Easing.Linear.None, true); + +} + +function render() { + + game.debug.renderText("Time until event: " + game.time.events.duration, 32, 32); + +} diff --git a/examples/time/remove event.js b/examples/time/remove event.js new file mode 100644 index 00000000..ce755721 --- /dev/null +++ b/examples/time/remove event.js @@ -0,0 +1,55 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { create: create, render: render }); + +var counters = []; +var text = []; +var timerEvents = []; +var i = 9; + +function create() { + + game.stage.backgroundColor = '#6688ee'; + + for (var i = 0; i < 10; i++) + { + counters[i] = 0; + text[i] = game.add.text(game.world.centerX, 80 + (40 * i), 'Counter ' + i + ' = 0', { font: "32px Arial", fill: "#ffffff", align: "center" }); + text[i].anchor.setTo(0.5, 0); + + // Here we create our timer events. They will be set to loop at a random value between 250ms and 1000ms + timerEvents[i] = game.time.events.loop(game.rnd.integerInRange(250, 1000), updateCounter, this, i); + } + + // Click to remove + game.input.onDown.add(removeCounter, this); + +} + +function updateCounter(idx) { + + counters[idx]++; + + text[idx].content = 'Counter ' + idx + ' = ' + counters[idx]; + +} + +function removeCounter() { + + if (i >= 0) + { + // Removes the timer, starting with the top one and working down + game.time.events.remove(timerEvents[i]); + + // Just updates the text + text[i].style.fill = '#3344aa'; + text[i].content = 'Counter ' + i + ' removed'; + i--; + } + +} + +function render() { + + game.debug.renderText("Queued events: " + game.time.events.length + ' - click to remove', 32, 32); + +} diff --git a/examples/time/timed slideshow.js b/examples/time/timed slideshow.js new file mode 100644 index 00000000..b8e6b11c --- /dev/null +++ b/examples/time/timed slideshow.js @@ -0,0 +1,94 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, render: render }); + +function preload() { + + game.load.image('picture1', 'assets/pics/cougar_sanity_train.png'); + game.load.image('picture2', 'assets/pics/cougar-face_of_nature.png'); + game.load.image('picture3', 'assets/pics/destop-rewarding.png'); + game.load.image('picture4', 'assets/pics/destop-unknown.png'); + game.load.image('picture5', 'assets/pics/questar.png'); + game.load.image('picture6', 'assets/pics/seven_seas_andromeda_fairfax.png'); + game.load.image('picture7', 'assets/pics/slayer-sorry_im_the_beast.png'); + +} + +var pictureA; +var pictureB; +var timer; +var current = 3; + +function create() { + + game.stage.backgroundColor = '#000'; + + pictureA = game.add.sprite(game.world.centerX, game.world.centerY, 'picture1'); + pictureA.anchor.setTo(0.5, 0.5); + pictureA.scale.setTo(2, 2); + + pictureB = game.add.sprite(game.world.centerX, game.world.centerY, 'picture2'); + pictureB.anchor.setTo(0.5, 0.5); + pictureB.scale.setTo(2, 2); + pictureB.alpha = 0; + + // Create our Timer + timer = game.time.create(false); + + // Set a TimerEvent to occur after 3 seconds + timer.add(3000, fadePictures, this); + + // Start the timer running - this is important! + // It won't start automatically, allowing you to hook it to button events and the like. + timer.start(); + +} + +function fadePictures() { + + // Cross-fade the two pictures + var tween; + + if (pictureA.alpha === 1) + { + tween = game.add.tween(pictureA).to( { alpha: 0 }, 2000, Phaser.Easing.Linear.None, true); + game.add.tween(pictureB).to( { alpha: 1 }, 2000, Phaser.Easing.Linear.None, true); + } + else + { + game.add.tween(pictureA).to( { alpha: 1 }, 2000, Phaser.Easing.Linear.None, true); + tween = game.add.tween(pictureB).to( { alpha: 0 }, 2000, Phaser.Easing.Linear.None, true); + } + + // When the cross-fade is complete we swap the image being shown by the now hidden picture + tween.onComplete.add(changePicture, this); + +} + +function changePicture() { + + if (pictureA.alpha === 0) + { + pictureA.loadTexture('picture' + current); + } + else + { + pictureB.loadTexture('picture' + current); + } + + current++; + + if (current > 7) + { + current = 1; + } + + // And set a new TimerEvent to occur after 3 seconds + timer.add(3000, fadePictures, this); + +} + +function render() { + + game.debug.renderText("Time until event: " + timer.duration.toFixed(0), 10, 20); + +} diff --git a/examples/tweens/tween loop event.js b/examples/tweens/tween loop event.js new file mode 100644 index 00000000..9d5473f7 --- /dev/null +++ b/examples/tweens/tween loop event.js @@ -0,0 +1,63 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, render: render }); + +function preload() { + + game.load.spritesheet('balls', 'assets/sprites/balls.png', 17, 17); + +} + +var ball; +var tween; +var bounces = 10; + +function create() { + + ball = game.add.sprite(400, 0, 'balls', 0); + + tween = game.add.tween(ball).to( { y: game.world.height - ball.height }, 1500, Phaser.Easing.Bounce.Out, true, 2500, 10); + + // There is a 2.5 second delay at the start, then it calls this function + tween.onStart.add(onStart, this); + + // This tween will loop 10 times, calling this function every time it loops + tween.onLoop.add(onLoop, this); + + // When it completes it will call this function + tween.onComplete.add(onComplete, this); + +} + +function onStart() { + + // Turn off the delay, so it loops seamlessly from here on + tween.delay(0); + +} + +function onLoop() { + + bounces--; + + if (ball.frame === 5) + { + ball.frame = 0; + } + else + { + ball.frame++; + } + +} + +function onComplete() { + + tween = game.add.tween(ball).to( { x: 800 - ball.width }, 2000, Phaser.Easing.Exponential.Out, true); + +} + +function render() { + + game.debug.renderText('Bounces: ' + bounces, 32, 32); + +} \ No newline at end of file diff --git a/examples/tweens/tween relative.js b/examples/tweens/tween relative.js new file mode 100644 index 00000000..38fb243f --- /dev/null +++ b/examples/tweens/tween relative.js @@ -0,0 +1,57 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, render: render }); + +function preload() { + + game.load.image('phaser', 'assets/sprites/phaser1.png'); + game.load.spritesheet('arrows', 'assets/sprites/arrows.png', 23, 31); + +} + +var arrowStart; +var arrowEnd; +var sprite; + +function create() { + + game.stage.backgroundColor = '#2384e7'; + + arrowStart = game.add.sprite(100, 100, 'arrows', 0); + + arrowEnd = game.add.sprite(400, 100, 'arrows', 1); + + sprite = game.add.sprite(100, 164, 'phaser'); + sprite.inputEnabled = true; + + sprite.events.onInputDown.add(move, this); + +} + +function move() { + + if (sprite.x === 100) + { + // Here you'll notice we are using a relative value for the tween. + // You can specify a number as a string with either + or - at the start of it. + // When the tween starts it will take the sprites current X value and add +300 to it. + + game.add.tween(sprite).to( { x: '+300' }, 2000, Phaser.Easing.Linear.None, true); + } + else if (sprite.x === 400) + { + game.add.tween(sprite).to( { x: '-300' }, 2000, Phaser.Easing.Linear.None, true); + } + +} + +function render() { + + if (sprite.x === 100 || sprite.x === 400) + { + game.debug.renderText('Click sprite to tween', 32, 32); + } + + game.debug.renderText('x: ' + arrowStart.x, arrowStart.x, arrowStart.y - 4); + game.debug.renderText('x: ' + arrowEnd.x, arrowEnd.x, arrowEnd.y - 4); + +} diff --git a/examples/wip/2ball.js b/examples/wip/2ball.js new file mode 100644 index 00000000..8740322e --- /dev/null +++ b/examples/wip/2ball.js @@ -0,0 +1,422 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('chunk', 'assets/sprites/chunk.png'); + game.load.image('arrow', 'assets/sprites/asteroids_ship.png'); + game.load.image('mushroom', 'assets/sprites/mushroom2.png'); + game.load.image('ball', 'assets/sprites/shinyball.png'); + game.load.spritesheet('gameboy', 'assets/sprites/gameboy_seize_color_40x60.png', 40, 60); + +} + +var sprite; +var sprite2; +var sprite3; +var group; +var flag = false; + +var bmd; + +function create() { + + game.stage.backgroundColor = '#124184'; + + bmd = game.add.bitmapData(800, 600); + bmd.fillStyle('#ffffff'); + var bg = game.add.sprite(0, 0, bmd); + bg.body.moves = false; + + test12(); + +} + +function test12() { + + // game.physics.gravity.y = 150; + + sprite = game.add.sprite(200, 300, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.checkCollision.right = false; + // sprite.body.checkCollision.up = false; + // sprite.body.immovable = true; + + sprite2 = game.add.sprite(400, 358, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.9, 0.9); + + game.input.onDown.add(launch12, this); + +} + +function launch12() { + + sprite2.body.velocity.x = -200; + // sprite2.body.velocity.y = -60; + +} + +function test11() { + + // game.physics.gravity.y = 150; + + sprite = game.add.sprite(300, 200, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + // sprite.body.checkCollision.down = false; + // sprite.body.checkCollision.up = false; + sprite.body.checkCollision.right = false; + // sprite.body.immovable = true; + + sprite2 = game.add.sprite(290, 400, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.9, 0.9); + + game.input.onDown.add(launch11, this); + +} + +function launch11() { + + sprite2.body.velocity.y = -200; + +} + +function test10() { + + // game.physics.gravity.y = 150; + + sprite = game.add.sprite(300, 200, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.checkCollision.down = false; + + sprite2 = game.add.sprite(330, 400, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.9, 0.9); + + game.input.onDown.add(launch10, this); + +} + +function launch10() { + + sprite2.body.velocity.y = -100; + +} + +function test9() { + + // game.physics.gravity.y = 150; + + sprite = game.add.sprite(300, 400, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.checkCollision.up = false; + // sprite.body.checkCollision.right = false; + + sprite2 = game.add.sprite(330, 100, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.9, 0.9); + + game.input.onDown.add(launch9, this); + +} + +function launch9() { + + sprite2.body.velocity.y = 100; + +} + +function test8() { + + game.physics.gravity.y = 150; + + sprite = game.add.sprite(300, 400, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.checkCollision.left = false; + sprite.body.checkCollision.right = false; + + sprite2 = game.add.sprite(500, 400, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.9, 0.9); + + game.input.onDown.add(launch8, this); + +} + +function launch8() { + + sprite.body.velocity.x = -50; + sprite2.body.velocity.x = -200; + +} + + + +function test7() { + + game.physics.gravity.y = 200; + + sprite = game.add.sprite(0, 300, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(0.8, 0.8); + + // sprite.body.velocity.y = 100; + + // sprite.body.gravity.y = 200; + + // sprite.body.linearDamping = 0.2; + + game.input.onDown.add(launch7, this); + +} + +function launch7() { + + sprite.body.velocity.x = -200; + sprite.body.velocity.y = 200; + +} + + + + +function test6() { + + game.physics.gravity.y = 100; + + sprite = game.add.sprite(300, 200, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(0.5, 0.5); + + game.input.onDown.add(launch6, this); + +} + +function launch6() { + + sprite.body.velocity.x = 200; + sprite.body.velocity.y = -200; + +} + + + + +function test5() { + + sprite = game.add.sprite(0, 600, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + // sprite.body.bounce.setTo(0.9, 0.9); + + game.input.onDown.add(launch5, this); + +} + +function launch5() { + + sprite.body.velocity.x = 100; + sprite.body.velocity.y = -100; + game.time.events.add(Phaser.Timer.SECOND * 4, stop5, this); + +} + +function stop5() { + + sprite.body.velocity.x = -100; + // sprite.body.velocity.y = 100; + console.log(sprite.x, sprite.body.x); + +} + + + + + + + +function test4() { + + game.physics.gravity.y = 150; + + sprite = game.add.sprite(300, 0, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(0.9, 0.9); + + sprite2 = game.add.sprite(310, 500, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + // sprite2.body.bounce.setTo(0.9, 0.9); + + game.input.onDown.add(launch4, this); + +} + +function launch4() { + + sprite.body.velocity.y = 200; + +} + +function test3() { + + game.physics.gravity.y = 50; + + // group = game.add.group(); + + sprite = game.add.sprite(500, 400, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(0.9, 0.9); + + sprite2 = game.add.sprite(100, 400, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.9, 0.9); + + // sprite2.body.immovable = true; + // sprite2.body.bounce.setTo(0.5, 0.5); + + sprite3 = game.add.sprite(700, 400, 'gameboy', 3); + sprite3.name = 'yellow'; + sprite3.body.collideWorldBounds = true; + sprite3.body.bounce.setTo(0.5, 0.5); + + // sprite.body.velocity.x = -300; + // sprite.body.velocity.y = -200; + + // group.add(sprite); + // group.add(sprite2); + // group.add(sprite3); + + game.input.onDown.add(launch3, this); + +} + +function launch3() { + + sprite.body.velocity.x = -200; + sprite.body.velocity.y = -200; + +} + +function test2() { + + // game.physics.gravity.y = 100; + + sprite = game.add.sprite(700, 400, 'ball'); + sprite.name = 'sprite1'; + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(0.8, 0.8); + + sprite2 = game.add.sprite(100, 400, 'ball'); + sprite2.name = 'sprite2'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.8, 0.8); + sprite2.body.immovable = true; + + // sprite.body.velocity.x = -225; + // sprite2.body.velocity.x = 225; + + + game.input.onDown.addOnce(launch2, this); + +} + +function launch2() { + + sprite.body.velocity.x = -225; + sprite2.body.velocity.x = 225; + +} + +function test1() { + + // game.physics.gravity.y = 100; + + sprite = game.add.sprite(100, 400, 'ball'); + sprite.name = 'sprite1'; + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(0.8, 0.8); + + sprite2 = game.add.sprite(700, 400, 'ball'); + sprite2.name = 'sprite2'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.8, 0.8); + + game.input.onDown.add(launch1, this); + +} + +function launch1() { + + sprite.body.velocity.x = 225; + // sprite2.body.velocity.x = -225; + +} + +function update() { + + // game.physics.collide(group, group); + + if (sprite3) + { + game.physics.collide(sprite, [sprite2, sprite3]); + game.physics.collide(sprite2, sprite3); + } + else + { + game.physics.collide(sprite, sprite2); + } + + + if (sprite) + { + bmd.fillStyle('#ffff00'); + bmd.fillRect(sprite.body.center.x, sprite.body.center.y, 2, 2); + } + + if (sprite2) + { + bmd.fillStyle('#ff00ff'); + bmd.fillRect(sprite2.body.center.x, sprite2.body.center.y, 2, 2); + } + + if (sprite3) + { + bmd.fillStyle('#0000ff'); + bmd.fillRect(sprite3.body.center.x, sprite3.body.center.y, 2, 2); + } + +} + +function render() { + + if (sprite) + { + game.debug.renderBodyInfo(sprite2, 16, 24); + // game.debug.renderText(sprite.name + ' x: ' + sprite.x.toFixed(2) + ' dx: ' + sprite.body._dx.toFixed(2), 16, 500); + // game.debug.renderText(sprite.name + ' y: ' + sprite.y.toFixed(2) + ' dy: ' + sprite.body._dy.toFixed(2), 16, 520); + } + + if (sprite2) + { + // game.debug.renderBodyInfo(sprite2, 16, 190); + // game.debug.renderText(sprite2.name + ' x: ' + sprite2.x, 400, 500); + } + +} diff --git a/examples/wip/SAT.js b/examples/wip/SAT.js new file mode 100644 index 00000000..63570ece --- /dev/null +++ b/examples/wip/SAT.js @@ -0,0 +1,862 @@ +// Version 0.2 - Copyright 2013 - Jim Riecken +// +// Released under the MIT License - https://github.com/jriecken/sat-js +// +// A simple library for determining intersections of circles and +// polygons using the Separating Axis Theorem. +/** @preserve SAT.js - Version 0.2 - Copyright 2013 - Jim Riecken - released under the MIT License. https://github.com/jriecken/sat-js */ + +/*global define: false, module: false*/ +/*jshint shadow:true, sub:true, forin:true, noarg:true, noempty:true, + eqeqeq:true, bitwise:true, strict:true, undef:true, + curly:true, browser:true */ + +// Create a UMD wrapper for SAT. Works in: +// +// - Plain browser via global SAT variable +// - AMD loader (like require.js) +// - Node.js +// +// The quoted properties all over the place are used so that the Closure Compiler +// does not mangle the exposed API in advanced mode. +/** + * @param {*} root - The global scope + * @param {Function} factory - Factory that creates SAT module + */ +(function (root, factory) { + "use strict"; + if (typeof define === 'function' && define['amd']) { + define(factory); + } else if (typeof exports === 'object') { + module['exports'] = factory(); + } else { + root['SAT'] = factory(); + } +}(this, function () { + "use strict"; + + var SAT = {}; + + // + // ## Vector + // + // Represents a vector in two dimensions with `x` and `y` properties. + + + // Create a new Vector, optionally passing in the `x` and `y` coordinates. If + // a coordinate is not specified, it will be set to `0` + /** + * @param {?number=} x The x position. + * @param {?number=} y The y position. + * @constructor + */ + function Vector(x, y) { + this['x'] = x || 0; + this['y'] = y || 0; + } + SAT['Vector'] = Vector; + // Alias `Vector` as `V` + SAT['V'] = Vector; + + + // Copy the values of another Vector into this one. + /** + * @param {Vector} other The other Vector. + * @return {Vector} This for chaining. + */ + Vector.prototype['copy'] = Vector.prototype.copy = function(other) { + this['x'] = other['x']; + this['y'] = other['y']; + return this; + }; + + // Change this vector to be perpendicular to what it was before. (Effectively + // roatates it 90 degrees in a clockwise direction) + /** + * @return {Vector} This for chaining. + */ + Vector.prototype['perp'] = Vector.prototype.perp = function() { + var x = this['x']; + this['x'] = this['y']; + this['y'] = -x; + return this; + }; + + // Rotate this vector (counter-clockwise) by the specified angle (in radians). + /** + * @param {number} angle The angle to rotate (in radians) + * @return {Vector} This for chaining. + */ + Vector.prototype['rotate'] = Vector.prototype.rotate = function (angle) { + var x = this['x']; + var y = this['y']; + this['x'] = x * Math.cos(angle) - y * Math.sin(angle); + this['y'] = x * Math.sin(angle) + y * Math.cos(angle); + return this; + }; + + // Rotate this vector (counter-clockwise) by the specified angle (in radians) which has already been calculated into sin and cos. + /** + * @param {number} sin - The Math.sin(angle) + * @param {number} cos - The Math.cos(angle) + * @return {Vector} This for chaining. + */ + Vector.prototype['rotatePrecalc'] = Vector.prototype.rotatePrecalc = function (sin, cos) { + var x = this['x']; + var y = this['y']; + this['x'] = x * cos - y * sin; + this['y'] = x * sin + y * cos; + return this; + }; + + // Reverse this vector. + /** + * @return {Vector} This for chaining. + */ + Vector.prototype['reverse'] = Vector.prototype.reverse = function() { + this['x'] = -this['x']; + this['y'] = -this['y']; + return this; + }; + + + // Normalize this vector. (make it have length of `1`) + /** + * @return {Vector} This for chaining. + */ + Vector.prototype['normalize'] = Vector.prototype.normalize = function() { + var d = this.len(); + if(d > 0) { + this['x'] = this['x'] / d; + this['y'] = this['y'] / d; + } + return this; + }; + + // Add another vector to this one. + /** + * @param {Vector} other The other Vector. + * @return {Vector} This for chaining. + */ + Vector.prototype['add'] = Vector.prototype.add = function(other) { + this['x'] += other['x']; + this['y'] += other['y']; + return this; + }; + + // Subtract another vector from this one. + /** + * @param {Vector} other The other Vector. + * @return {Vector} This for chaiing. + */ + Vector.prototype['sub'] = Vector.prototype.sub = function(other) { + this['x'] -= other['x']; + this['y'] -= other['y']; + return this; + }; + + // Scale this vector. An independant scaling factor can be provided + // for each axis, or a single scaling factor that will scale both `x` and `y`. + /** + * @param {number} x The scaling factor in the x direction. + * @param {?number=} y The scaling factor in the y direction. If this + * is not specified, the x scaling factor will be used. + * @return {Vector} This for chaining. + */ + Vector.prototype['scale'] = Vector.prototype.scale = function(x,y) { + this['x'] *= x; + this['y'] *= y || x; + return this; + }; + + // Project this vector on to another vector. + /** + * @param {Vector} other The vector to project onto. + * @return {Vector} This for chaining. + */ + Vector.prototype['project'] = Vector.prototype.project = function(other) { + var amt = this.dot(other) / other.len2(); + this['x'] = amt * other['x']; + this['y'] = amt * other['y']; + return this; + }; + + // Project this vector onto a vector of unit length. This is slightly more efficient + // than `project` when dealing with unit vectors. + /** + * @param {Vector} other The unit vector to project onto. + * @return {Vector} This for chaining. + */ + Vector.prototype['projectN'] = Vector.prototype.projectN = function(other) { + var amt = this.dot(other); + this['x'] = amt * other['x']; + this['y'] = amt * other['y']; + return this; + }; + + // Reflect this vector on an arbitrary axis. + /** + * @param {Vector} axis The vector representing the axis. + * @return {Vector} This for chaining. + */ + Vector.prototype['reflect'] = Vector.prototype.reflect = function(axis) { + var x = this['x']; + var y = this['y']; + this.project(axis).scale(2); + this['x'] -= x; + this['y'] -= y; + return this; + }; + + // Reflect this vector on an arbitrary axis (represented by a unit vector). This is + // slightly more efficient than `reflect` when dealing with an axis that is a unit vector. + /** + * @param {Vector} axis The unit vector representing the axis. + * @return {Vector} This for chaining. + */ + Vector.prototype['reflectN'] = Vector.prototype.reflectN = function(axis) { + var x = this['x']; + var y = this['y']; + this.projectN(axis).scale(2); + this['x'] -= x; + this['y'] -= y; + return this; + }; + + // Get the dot product of this vector and another. + /** + * @param {Vector} other The vector to dot this one against. + * @return {number} The dot product. + */ + Vector.prototype['dot'] = Vector.prototype.dot = function(other) { + return this['x'] * other['x'] + this['y'] * other['y']; + }; + + // Get the squared length of this vector. + /** + * @return {number} The length^2 of this vector. + */ + Vector.prototype['len2'] = Vector.prototype.len2 = function() { + return this.dot(this); + }; + + // Get the length of this vector. + /** + * @return {number} The length of this vector. + */ + Vector.prototype['len'] = Vector.prototype.len = function() { + return Math.sqrt(this.len2()); + }; + + // ## Circle + // + // Represents a circle with a position and a radius. + + // Create a new circle, optionally passing in a position and/or radius. If no position + // is given, the circle will be at `(0,0)`. If no radius is provided, the circle will + // have a radius of `0`. + /** + * @param {Vector=} pos A vector representing the position of the center of the circle + * @param {?number=} r The radius of the circle + * @constructor + */ + function Circle(pos, r) { + this['pos'] = pos || new Vector(); + this['r'] = r || 0; + } + SAT['Circle'] = Circle; + + // ## Polygon + // + // Represents a *convex* polygon with any number of points (specified in counter-clockwise order) + // + // The edges/normals of the polygon will be calculated on creation and stored in the + // `edges` and `normals` properties. If you change the polygon's points, you will need + // to call `recalc` to recalculate the edges/normals. + + // Create a new polygon, passing in a position vector, and an array of points (represented + // by vectors relative to the position vector). If no position is passed in, the position + // of the polygon will be `(0,0)`. + /** + * @param {Vector=} pos A vector representing the origin of the polygon. (all other + * points are relative to this one) + * @param {Array.=} points An array of vectors representing the points in the polygon, + * in counter-clockwise order. + * @constructor + */ + function Polygon(pos, points) { + this['pos'] = pos || new Vector(); + this['points'] = points || []; + this.recalc(); + } + SAT['Polygon'] = Polygon; + + // Recalculates the edges and normals of the polygon. This **must** be called + // if the `points` array is modified at all and the edges or normals are to be + // accessed. + /** + * @return {Polygon} This for chaining. + */ + Polygon.prototype['recalc'] = Polygon.prototype.recalc = function() { + // The edges here are the direction of the `n`th edge of the polygon, relative to + // the `n`th point. If you want to draw a given edge from the edge value, you must + // first translate to the position of the starting point. + this['edges'] = []; + // The normals here are the direction of the normal for the `n`th edge of the polygon, relative + // to the position of the `n`th point. If you want to draw an edge normal, you must first + // translate to the position of the starting point. + this['normals'] = []; + var points = this['points']; + var len = points.length; + for (var i = 0; i < len; i++) { + var p1 = points[i]; + var p2 = i < len - 1 ? points[i + 1] : points[0]; + var e = new Vector().copy(p2).sub(p1); + var n = new Vector().copy(e).perp().normalize(); + this['edges'].push(e); + this['normals'].push(n); + } + return this; + }; + + // Rotates this polygon counter-clockwise around the origin of *its local coordinate system* (i.e. `pos`). + // + // Note: You do **not** need to call `recalc` after rotation. + /** + * @param {number} angle The angle to rotate (in radians) + * @return {Polygon} This for chaining. + */ + Polygon.prototype['rotate'] = Polygon.prototype.rotate = function(angle) { + var i; + var points = this['points']; + var edges = this['edges']; + var normals = this['normals']; + var len = points.length; + + // Calc it just the once, rather than 4 times per array element + var cos = Math.cos(angle); + var sin = Math.sin(angle); + + for (i = 0; i < len; i++) { + points[i].rotatePrecalc(sin, cos); + edges[i].rotatePrecalc(sin, cos); + normals[i].rotatePrecalc(sin, cos); + } + return this; + }; + + // Rotates this polygon counter-clockwise around the origin of *its local coordinate system* (i.e. `pos`). + // + // Note: You do **not** need to call `recalc` after rotation. + /** + * @param {number} angle The angle to rotate (in radians) + * @return {Polygon} This for chaining. + */ + Polygon.prototype['scale'] = Polygon.prototype.scale = function(x, y) { + var i; + var points = this['points']; + var edges = this['edges']; + var normals = this['normals']; + var len = points.length; + for (i = 0; i < len; i++) { + points[i].scale(x,y); + edges[i].scale(x,y); + normals[i].scale(x,y); + } + return this; + }; + + // Translates the points of this polygon by a specified amount relative to the origin of *its own coordinate + // system* (i.e. `pos`). + // + // This is most useful to change the "center point" of a polygon. + // + // Note: You do **not** need to call `recalc` after translation. + /** + * @param {number} x The horizontal amount to translate. + * @param {number} y The vertical amount to translate. + * @return {Polygon} This for chaining. + */ + Polygon.prototype['translate'] = Polygon.prototype.translate = function (x, y) { + var i; + var points = this['points']; + var len = points.length; + for (i = 0; i < len; i++) { + points[i].x += x; + points[i].y += y; + } + return this; + }; + + // ## Box + // + // Represents an axis-aligned box, with a width and height. + + + // Create a new box, with the specified position, width, and height. If no position + // is given, the position will be `(0,0)`. If no width or height are given, they will + // be set to `0`. + /** + * @param {Vector=} pos A vector representing the top-left of the box. + * @param {?number=} w The width of the box. + * @param {?number=} h The height of the box. + * @constructor + */ + function Box(pos, w, h) { + this['pos'] = pos || new Vector(); + this['w'] = w || 0; + this['h'] = h || 0; + } + SAT['Box'] = Box; + + // Returns a polygon whose edges are the same as this box. + /** + * @return {Polygon} A new Polygon that represents this box. + */ + Box.prototype['toPolygon'] = Box.prototype.toPolygon = function() { + var pos = this['pos']; + var w = this['w']; + var h = this['h']; + return new Polygon(new Vector(pos['x'], pos['y']), [ + new Vector(), new Vector(w, 0), + new Vector(w,h), new Vector(0,h) + ]); + }; + + // ## Response + // + // An object representing the result of an intersection. Contains: + // - The two objects participating in the intersection + // - The vector representing the minimum change necessary to extract the first object + // from the second one (as well as a unit vector in that direction and the magnitude + // of the overlap) + // - Whether the first object is entirely inside the second, and vice versa. + /** + * @constructor + */ + function Response() { + this['a'] = null; + this['b'] = null; + this['overlapN'] = new Vector(); + this['overlapV'] = new Vector(); + this.clear(); + } + SAT['Response'] = Response; + + // Set some values of the response back to their defaults. Call this between tests if + // you are going to reuse a single Response object for multiple intersection tests (recommented + // as it will avoid allcating extra memory) + /** + * @return {Response} This for chaining + */ + Response.prototype['clear'] = Response.prototype.clear = function() { + this['aInB'] = true; + this['bInA'] = true; + this['overlap'] = Number.MAX_VALUE; + return this; + }; + + // ## Object Pools + + // A pool of `Vector` objects that are used in calculations to avoid + // allocating memory. + /** + * @type {Array.} + */ + var T_VECTORS = []; + for (var i = 0; i < 10; i++) { T_VECTORS.push(new Vector()); } + + // A pool of arrays of numbers used in calculations to avoid allocating + // memory. + /** + * @type {Array.>} + */ + var T_ARRAYS = []; + for (var i = 0; i < 5; i++) { T_ARRAYS.push([]); } + + // ## Helper Functions + + // Flattens the specified array of points onto a unit vector axis, + // resulting in a one dimensional range of the minimum and + // maximum value on that axis. + /** + * @param {Array.} points The points to flatten. + * @param {Vector} normal The unit vector axis to flatten on. + * @param {Array.} result An array. After calling this function, + * result[0] will be the minimum value, + * result[1] will be the maximum value. + */ + function flattenPointsOn(points, normal, result) { + var min = Number.MAX_VALUE; + var max = -Number.MAX_VALUE; + var len = points.length; + for (var i = 0; i < len; i++ ) { + // The magnitude of the projection of the point onto the normal + var dot = points[i].dot(normal); + if (dot < min) { min = dot; } + if (dot > max) { max = dot; } + } + result[0] = min; result[1] = max; + } + + // Check whether two convex polygons are separated by the specified + // axis (must be a unit vector). + /** + * @param {Vector} aPos The position of the first polygon. + * @param {Vector} bPos The position of the second polygon. + * @param {Array.} aPoints The points in the first polygon. + * @param {Array.} bPoints The points in the second polygon. + * @param {Vector} axis The axis (unit sized) to test against. The points of both polygons + * will be projected onto this axis. + * @param {Response=} response A Response object (optional) which will be populated + * if the axis is not a separating axis. + * @return {boolean} true if it is a separating axis, false otherwise. If false, + * and a response is passed in, information about how much overlap and + * the direction of the overlap will be populated. + */ + function isSeparatingAxis(aPos, bPos, aPoints, bPoints, axis, response) { + var rangeA = T_ARRAYS.pop(); + var rangeB = T_ARRAYS.pop(); + // The magnitude of the offset between the two polygons + var offsetV = T_VECTORS.pop().copy(bPos).sub(aPos); + var projectedOffset = offsetV.dot(axis); + // Project the polygons onto the axis. + flattenPointsOn(aPoints, axis, rangeA); + flattenPointsOn(bPoints, axis, rangeB); + // Move B's range to its position relative to A. + rangeB[0] += projectedOffset; + rangeB[1] += projectedOffset; + // Check if there is a gap. If there is, this is a separating axis and we can stop + if (rangeA[0] > rangeB[1] || rangeB[0] > rangeA[1]) { + T_VECTORS.push(offsetV); + T_ARRAYS.push(rangeA); + T_ARRAYS.push(rangeB); + return true; + } + // This is not a separating axis. If we're calculating a response, calculate the overlap. + if (response) { + var overlap = 0; + // A starts further left than B + if (rangeA[0] < rangeB[0]) { + response['aInB'] = false; + // A ends before B does. We have to pull A out of B + if (rangeA[1] < rangeB[1]) { + overlap = rangeA[1] - rangeB[0]; + response['bInA'] = false; + // B is fully inside A. Pick the shortest way out. + } else { + var option1 = rangeA[1] - rangeB[0]; + var option2 = rangeB[1] - rangeA[0]; + overlap = option1 < option2 ? option1 : -option2; + } + // B starts further left than A + } else { + response['bInA'] = false; + // B ends before A ends. We have to push A out of B + if (rangeA[1] > rangeB[1]) { + overlap = rangeA[0] - rangeB[1]; + response['aInB'] = false; + // A is fully inside B. Pick the shortest way out. + } else { + var option1 = rangeA[1] - rangeB[0]; + var option2 = rangeB[1] - rangeA[0]; + overlap = option1 < option2 ? option1 : -option2; + } + } + // If this is the smallest amount of overlap we've seen so far, set it as the minimum overlap. + var absOverlap = Math.abs(overlap); + if (absOverlap < response['overlap']) { + response['overlap'] = absOverlap; + response['overlapN'].copy(axis); + if (overlap < 0) { + response['overlapN'].reverse(); + } + } + } + T_VECTORS.push(offsetV); + T_ARRAYS.push(rangeA); + T_ARRAYS.push(rangeB); + return false; + } + + // Calculates which Vornoi region a point is on a line segment. + // It is assumed that both the line and the point are relative to `(0,0)` + // + // | (0) | + // (-1) [S]--------------[E] (1) + // | (0) | + /** + * @param {Vector} line The line segment. + * @param {Vector} point The point. + * @return {number} LEFT_VORNOI_REGION (-1) if it is the left region, + * MIDDLE_VORNOI_REGION (0) if it is the middle region, + * RIGHT_VORNOI_REGION (1) if it is the right region. + */ + function vornoiRegion(line, point) { + var len2 = line.len2(); + var dp = point.dot(line); + // If the point is beyond the start of the line, it is in the + // left vornoi region. + if (dp < 0) { return LEFT_VORNOI_REGION; } + // If the point is beyond the end of the line, it is in the + // right vornoi region. + else if (dp > len2) { return RIGHT_VORNOI_REGION; } + // Otherwise, it's in the middle one. + else { return MIDDLE_VORNOI_REGION; } + } + // Constants for Vornoi regions + /** + * @const + */ + var LEFT_VORNOI_REGION = -1; + /** + * @const + */ + var MIDDLE_VORNOI_REGION = 0; + /** + * @const + */ + var RIGHT_VORNOI_REGION = 1; + + // ## Collision Tests + + // Check if two circles collide. + /** + * @param {Circle} a The first circle. + * @param {Circle} b The second circle. + * @param {Response=} response Response object (optional) that will be populated if + * the circles intersect. + * @return {boolean} true if the circles intersect, false if they don't. + */ + function testCircleCircle(a, b, response) { + // Check if the distance between the centers of the two + // circles is greater than their combined radius. + var differenceV = T_VECTORS.pop().copy(b['pos']).sub(a['pos']); + var totalRadius = a['r'] + b['r']; + var totalRadiusSq = totalRadius * totalRadius; + var distanceSq = differenceV.len2(); + // If the distance is bigger than the combined radius, they don't intersect. + if (distanceSq > totalRadiusSq) { + T_VECTORS.push(differenceV); + return false; + } + // They intersect. If we're calculating a response, calculate the overlap. + if (response) { + var dist = Math.sqrt(distanceSq); + response['a'] = a; + response['b'] = b; + response['overlap'] = totalRadius - dist; + response['overlapN'].copy(differenceV.normalize()); + response['overlapV'].copy(differenceV).scale(response['overlap']); + response['aInB']= a['r'] <= b['r'] && dist <= b['r'] - a['r']; + response['bInA'] = b['r'] <= a['r'] && dist <= a['r'] - b['r']; + } + T_VECTORS.push(differenceV); + return true; + } + SAT['testCircleCircle'] = testCircleCircle; + + // Check if a polygon and a circle collide. + /** + * @param {Polygon} polygon The polygon. + * @param {Circle} circle The circle. + * @param {Response=} response Response object (optional) that will be populated if + * they interset. + * @return {boolean} true if they intersect, false if they don't. + */ + function testPolygonCircle(polygon, circle, response) { + // Get the position of the circle relative to the polygon. + var circlePos = T_VECTORS.pop().copy(circle['pos']).sub(polygon['pos']); + var radius = circle['r']; + var radius2 = radius * radius; + var points = polygon['points']; + var len = points.length; + var edge = T_VECTORS.pop(); + var point = T_VECTORS.pop(); + + // For each edge in the polygon: + for (var i = 0; i < len; i++) { + var next = i === len - 1 ? 0 : i + 1; + var prev = i === 0 ? len - 1 : i - 1; + var overlap = 0; + var overlapN = null; + + // Get the edge. + edge.copy(polygon['edges'][i]); + // Calculate the center of the circle relative to the starting point of the edge. + point.copy(circlePos).sub(points[i]); + + // If the distance between the center of the circle and the point + // is bigger than the radius, the polygon is definitely not fully in + // the circle. + if (response && point.len2() > radius2) { + response['aInB'] = false; + } + + // Calculate which Vornoi region the center of the circle is in. + var region = vornoiRegion(edge, point); + // If it's the left region: + if (region === LEFT_VORNOI_REGION) { + // We need to make sure we're in the RIGHT_VORNOI_REGION of the previous edge. + edge.copy(polygon['edges'][prev]); + // Calculate the center of the circle relative the starting point of the previous edge + var point2 = T_VECTORS.pop().copy(circlePos).sub(points[prev]); + region = vornoiRegion(edge, point2); + if (region === RIGHT_VORNOI_REGION) { + // It's in the region we want. Check if the circle intersects the point. + var dist = point.len(); + if (dist > radius) { + // No intersection + T_VECTORS.push(circlePos); + T_VECTORS.push(edge); + T_VECTORS.push(point); + T_VECTORS.push(point2); + return false; + } else if (response) { + // It intersects, calculate the overlap. + response['bInA'] = false; + overlapN = point.normalize(); + overlap = radius - dist; + } + } + T_VECTORS.push(point2); + // If it's the right region: + } else if (region === RIGHT_VORNOI_REGION) { + // We need to make sure we're in the left region on the next edge + edge.copy(polygon['edges'][next]); + // Calculate the center of the circle relative to the starting point of the next edge. + point.copy(circlePos).sub(points[next]); + region = vornoiRegion(edge, point); + if (region === LEFT_VORNOI_REGION) { + // It's in the region we want. Check if the circle intersects the point. + var dist = point.len(); + if (dist > radius) { + // No intersection + T_VECTORS.push(circlePos); + T_VECTORS.push(edge); + T_VECTORS.push(point); + return false; + } else if (response) { + // It intersects, calculate the overlap. + response['bInA'] = false; + overlapN = point.normalize(); + overlap = radius - dist; + } + } + // Otherwise, it's the middle region: + } else { + // Need to check if the circle is intersecting the edge, + // Change the edge into its "edge normal". + var normal = edge.perp().normalize(); + // Find the perpendicular distance between the center of the + // circle and the edge. + var dist = point.dot(normal); + var distAbs = Math.abs(dist); + // If the circle is on the outside of the edge, there is no intersection. + if (dist > 0 && distAbs > radius) { + // No intersection + T_VECTORS.push(circlePos); + T_VECTORS.push(normal); + T_VECTORS.push(point); + return false; + } else if (response) { + // It intersects, calculate the overlap. + overlapN = normal; + overlap = radius - dist; + // If the center of the circle is on the outside of the edge, or part of the + // circle is on the outside, the circle is not fully inside the polygon. + if (dist >= 0 || overlap < 2 * radius) { + response['bInA'] = false; + } + } + } + + // If this is the smallest overlap we've seen, keep it. + // (overlapN may be null if the circle was in the wrong Vornoi region). + if (overlapN && response && Math.abs(overlap) < Math.abs(response['overlap'])) { + response['overlap'] = overlap; + response['overlapN'].copy(overlapN); + } + } + + // Calculate the final overlap vector - based on the smallest overlap. + if (response) { + response['a'] = polygon; + response['b'] = circle; + response['overlapV'].copy(response['overlapN']).scale(response['overlap']); + } + T_VECTORS.push(circlePos); + T_VECTORS.push(edge); + T_VECTORS.push(point); + return true; + } + SAT['testPolygonCircle'] = testPolygonCircle; + + // Check if a circle and a polygon collide. + // + // **NOTE:** This is slightly less efficient than polygonCircle as it just + // runs polygonCircle and reverses everything at the end. + /** + * @param {Circle} circle The circle. + * @param {Polygon} polygon The polygon. + * @param {Response=} response Response object (optional) that will be populated if + * they interset. + * @return {boolean} true if they intersect, false if they don't. + */ + function testCirclePolygon(circle, polygon, response) { + // Test the polygon against the circle. + var result = testPolygonCircle(polygon, circle, response); + if (result && response) { + // Swap A and B in the response. + var a = response['a']; + var aInB = response['aInB']; + response['overlapN'].reverse(); + response['overlapV'].reverse(); + response['a'] = response['b']; + response['b'] = a; + response['aInB'] = response['bInA']; + response['bInA'] = aInB; + } + return result; + } + SAT['testCirclePolygon'] = testCirclePolygon; + + // Checks whether polygons collide. + /** + * @param {Polygon} a The first polygon. + * @param {Polygon} b The second polygon. + * @param {Response=} response Response object (optional) that will be populated if + * they interset. + * @return {boolean} true if they intersect, false if they don't. + */ + function testPolygonPolygon(a, b, response) { + var aPoints = a['points']; + var aLen = aPoints.length; + var bPoints = b['points']; + var bLen = bPoints.length; + // If any of the edge normals of A is a separating axis, no intersection. + for (var i = 0; i < aLen; i++) { + if (isSeparatingAxis(a['pos'], b['pos'], aPoints, bPoints, a['normals'][i], response)) { + return false; + } + } + // If any of the edge normals of B is a separating axis, no intersection. + for (var i = 0;i < bLen; i++) { + if (isSeparatingAxis(a['pos'], b['pos'], aPoints, bPoints, b['normals'][i], response)) { + return false; + } + } + // Since none of the edge normals of A or B are a separating axis, there is an intersection + // and we've already calculated the smallest overlap (in isSeparatingAxis). Calculate the + // final overlap vector. + if (response) { + response['a'] = a; + response['b'] = b; + response['overlapV'].copy(response['overlapN']).scale(response['overlap']); + } + return true; + } + SAT['testPolygonPolygon'] = testPolygonPolygon; + + return SAT; +})); \ No newline at end of file diff --git a/examples/wip/acceleration.js b/examples/wip/acceleration.js new file mode 100644 index 00000000..5188e556 --- /dev/null +++ b/examples/wip/acceleration.js @@ -0,0 +1,100 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('car', 'assets/sprites/car90.png'); + game.load.image('baddie', 'assets/sprites/space-baddie.png'); + +} + +var car; +var aliens; + +function create() { + + // aliens = game.add.group(); + + // for (var i = 0; i < 50; i++) + // { + // var s = aliens.create(game.world.randomX, game.world.randomY, 'baddie'); + // s.name = 'alien' + s; + // s.body.collideWorldBounds = true; + // s.body.bounce.setTo(0.8, 0.8); + // s.body.velocity.setTo(10 + Math.random() * 40, 10 + Math.random() * 40); + // } + + car = game.add.sprite(0, 300, 'car'); + car.anchor.setTo(0.5, 0.5); + car.body.collideWorldBounds = true; + car.body.bounce.setTo(0.8, 0.8); + car.body.allowRotation = true; + car.body.linearDamping = 0.4; + + // car.body.acceleration.x = 10; + game.input.onDown.add(start, this); + +} + +var s = 0; + +function start() { + + // car.body.velocity.x = 200; + car.body.acceleration.x = 100; + s = game.time.now; + +} + +function update() { + + // if (car.x >= 400 && car.body.velocity.x > 0) + // { + // car.body.velocity.x = 0; + // car.body.acceleration.x = 0; + // var total = game.time.now - s; + // console.log(game.time.physicsElapsed); + // console.log('total ms', total, 'px/sec', car.x/(total/1000)); + // } + + // car.body.velocity.x = 0; + // car.body.velocity.y = 0; + car.body.angularVelocity = 0; + + car.body.acceleration.x = 0; + car.body.acceleration.y = 0; + + if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + { + car.body.angularVelocity = -200; + // car.body.acceleration.x = -100; + } + else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + { + car.body.angularVelocity = 200; + // car.body.acceleration.x = 100; + } + + if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + { + game.physics.accelerationFromRotation(car.rotation, 400, car.body.acceleration); + + // car.body.acceleration.x = 10; + // car.body.acceleration.copyFrom(game.physics.velocityFromAngle(car.angle, 30)); + // car.body.velocity.copyFrom(game.physics.velocityFromAngle(car.angle, 300)); + } + else + { + // game.physics.accelerationFromRotation(car.rotation, 10, car.body.acceleration); + } + + // game.physics.collide(car, aliens); + +} + +function render() { + + // game.debug.renderSpriteInfo(car, 32, 32); + game.debug.renderBodyInfo(car, 16, 24); + +} diff --git a/examples/wip/audio loop.js b/examples/wip/audio loop.js new file mode 100644 index 00000000..858eb092 --- /dev/null +++ b/examples/wip/audio loop.js @@ -0,0 +1,46 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.audio('music', 'assets/audio/CatAstroPhi_shmup_normal.wav'); + +} + +var music; + +function create() { + + music = game.add.audio('music'); + + // play: function (marker, position, volume, loop, forceRestart) { + + music.play('', 0, 1, true); + + game.input.onDown.add(toggleAudio, this); + +} + +function toggleAudio() { + + if (music.isPlaying) + { + music.pause(); + } + else + { + music.resume(); + } + +} + +function update() { + + +} + +function render() { + + game.debug.renderSoundInfo(music, 32, 32); + +} diff --git a/examples/wip/blocked.js b/examples/wip/blocked.js new file mode 100644 index 00000000..22107b80 --- /dev/null +++ b/examples/wip/blocked.js @@ -0,0 +1,281 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('chunk', 'assets/sprites/chunk.png'); + game.load.image('arrow', 'assets/sprites/asteroids_ship.png'); + game.load.image('p', 'assets/sprites/mushroom2.png'); + game.load.image('ball', 'assets/sprites/shinyball.png'); + +} + +var sprite; +var sprite2; + +var track; +var bmd; + +function create() { + + game.stage.backgroundColor = '#124184'; + + bmd = game.add.bitmapData(800, 600); + bmd.fillStyle('#ffffff'); + var bg = game.add.sprite(0, 0, bmd); + bg.body.moves = false; + + test9(); + +} + +// stacked +function test9() { + + game.physics.gravity.y = 500; + + sprite = game.add.sprite(400, 100, 'ball'); + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(0.8, 0.8); + sprite.body.minBounceVelocity = 0.8; + + sprite2 = game.add.sprite(400, 300, 'ball'); + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.5, 0.5); + sprite2.body.minBounceVelocity = 0.8; + + // game.input.onDown.add(launch8, this); + +} + +// gravity into floor jiggle +function test8() { + + game.physics.gravity.y = 1000; + + sprite = game.add.sprite(400, 100, 'ball'); + sprite.body.collideWorldBounds = true; + // it's all about tweaking these values + sprite.body.bounce.setTo(0.8, 0.8); + sprite.body.minBounceVelocity = 1.2; + sprite.body.velocity.x = -400; + sprite.body.linearDamping = 1.2; + + sprite2 = game.add.sprite(500, 100, 'ball'); + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.5, 0.5); + sprite2.body.minBounceVelocity = 0.8; + sprite2.body.linearDamping = 0.5; + + game.input.onDown.add(launch8, this); + +} + +function launch8() { + + // sprite.body.velocity.x = -200; + sprite2.body.velocity.x = 200; + +} + +// both sprites are shot into each other vertically +function test7() { + + // game.physics.gravity.y = 50; + + sprite = game.add.sprite(400, 600, 'ball'); + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(0.8, 0.8); + + sprite2 = game.add.sprite(400, 100, 'ball'); + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.8, 0.8); + + track = sprite2; + + game.input.onDown.add(launch7, this); + +} + +function launch7() { + + sprite.body.velocity.y = -200; + // sprite2.body.velocity.y = 200; + +} + + +// sprite is on the bottom, blocked by the world bounds, sprite2 falls onto it via gravity only +function test6() { + + game.physics.gravity.y = 100; + + sprite = game.add.sprite(380, 600, 'p'); + sprite.body.collideWorldBounds = true; + + sprite2 = game.add.sprite(400, 100, 'ball'); + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.8, 0.8); + + track = sprite2; + +} + +// sprite is on the bottom, blocked by the world bounds, sprite2 falls onto it +function test5() { + + game.physics.gravity.y = 50; + + sprite = game.add.sprite(400, 600, 'ball'); + sprite.body.collideWorldBounds = true; + + sprite2 = game.add.sprite(400, 100, 'ball'); + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.8, 0.8); + + track = sprite2; + + game.input.onDown.add(launch5, this); + +} + +function launch5() { + + sprite2.body.velocity.y = 200; + +} + + +// bounce both sprites into each other, one with lots less velocity - checking newtons craddle approach +function test4() { + + game.physics.gravity.y = 100; + + sprite = game.add.sprite(780, 400, 'ball'); + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(0.8, 0.8); + + sprite2 = game.add.sprite(0, 400, 'ball'); + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.8, 0.8); + + track = sprite2; + + game.input.onDown.add(launch4, this); + +} + +function launch4() { + + sprite.body.velocity.x = 70; + sprite2.body.velocity.x = -250; + +} + +// bounce both sprites into each other, identical bounce + velocity +function test3() { + + game.physics.gravity.y = 100; + + sprite = game.add.sprite(780, 400, 'p'); + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(0.8, 0.8); + + sprite2 = game.add.sprite(0, 400, 'p'); + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.8, 0.8); + + track = sprite2; + + game.input.onDown.add(launch3, this); + +} + +function launch3() { + + sprite.body.velocity.x = 225; + sprite2.body.velocity.x = -225; + +} + +// sprite is on the right, blocked by the world bounds, sprite2 bounces into it +function test2() { + + game.physics.gravity.y = 100; + + sprite = game.add.sprite(780, 400, 'p'); + sprite.body.collideWorldBounds = true; + + sprite2 = game.add.sprite(0, 400, 'p'); + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.8, 0.8); + + track = sprite2; + + game.input.onDown.add(launch2, this); + +} + +function launch2() { + + sprite2.body.velocity.x = -225; + +} + +// sprite is on the left, blocked by the world bounds, sprite2 bounces into it +function test1() { + + game.physics.gravity.y = 100; + + sprite = game.add.sprite(0, 400, 'p'); + sprite.body.collideWorldBounds = true; + + sprite2 = game.add.sprite(700, 400, 'p'); + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.8, 0.8); + + track = sprite2; + + game.input.onDown.add(launch1, this); + +} + +function launch1() { + + sprite2.body.velocity.x = -225; + +} + +function update() { + + game.physics.collide(sprite, sprite2); + + // sprite.rotation = sprite.body.angle; + + if (sprite) + { + bmd.fillStyle('#ffff00'); + bmd.fillRect(sprite.body.center.x, sprite.body.center.y, 2, 2); + } + + if (sprite2) + { + bmd.fillStyle('#ff00ff'); + bmd.fillRect(sprite2.body.center.x, sprite2.body.center.y, 2, 2); + } + +} + +function render() { + + if (sprite) + { + game.debug.renderBodyInfo(sprite, 16, 24); + } + + if (sprite2) + { + game.debug.renderBodyInfo(sprite2, 16, 190); + } + +} diff --git a/examples/wip/bmd.js b/examples/wip/bmd.js index dda21b51..36d4e42a 100644 --- a/examples/wip/bmd.js +++ b/examples/wip/bmd.js @@ -14,7 +14,7 @@ var bmd; function create() { - bmd = game.add.bitmapData('ball', 32, 64); + bmd = game.add.bitmapData(32, 64); console.log(bmd); diff --git a/examples/wip/body angle.js b/examples/wip/body angle.js new file mode 100644 index 00000000..3a955d2d --- /dev/null +++ b/examples/wip/body angle.js @@ -0,0 +1,50 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('arrow', 'assets/sprites/longarrow.png'); + +} + +var sprite; +var cursors; + + +function create() { + + game.stage.backgroundColor = '#124184'; + + sprite = game.add.sprite(400, 300, 'arrow'); + + cursors = game.input.keyboard.createCursorKeys(); + +} + +function update() { + + sprite.body.velocity.x = 0; + sprite.body.velocity.y = 0; + sprite.body.angularVelocity = 0; + + if (cursors.left.isDown) + { + sprite.body.angularVelocity = -100; + } + else if (cursors.right.isDown) + { + sprite.body.angularVelocity = 100; + } + + if (cursors.up.isDown) + { + game.physics.velocityFromAngle(sprite.angle, 300, sprite.body.velocity); + } + +} + +function render() { + + game.debug.renderBodyInfo(sprite, 16, 24); + +} diff --git a/examples/wip/body group.js b/examples/wip/body group.js new file mode 100644 index 00000000..946b21b2 --- /dev/null +++ b/examples/wip/body group.js @@ -0,0 +1,336 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('bullet', 'assets/games/invaders/bullet.png'); + game.load.image('enemyBullet', 'assets/games/invaders/enemy-bullet.png'); + game.load.spritesheet('invader', 'assets/games/invaders/invader32x32x4.png', 32, 32); + game.load.image('ship', 'assets/games/invaders/player.png'); + game.load.spritesheet('kaboom', 'assets/games/invaders/explode.png', 128, 128); + game.load.image('starfield', 'assets/games/invaders/starfield.png'); + game.load.image('background', 'assets/games/starstruck/background2.png'); + +} + +var player; +var aliens; +var bullets; +var bulletTime = 0; +var cursors; +var fireButton; +var explosions; +var starfield; +var score = 0; +var scoreString = ''; +var scoreText; +var lives; +var enemyBullet; +var firingTimer = 0; +var stateText; +var livingEnemies = []; + +var bob; + +function create() { + + $('#step').click(function(){ + console.log('---- STEP', game.stepCount, '-------------------------------'); + game.step(); + }); + + game.enableStep(); + + + // The scrolling starfield background + // starfield = game.add.tileSprite(0, 0, 800, 600, 'starfield'); + + // Our bullet group + // bullets = game.add.group(); + // bullets.createMultiple(30, 'bullet'); + // bullets.setAll('anchor.x', 0.5); + // bullets.setAll('anchor.y', 1); + // bullets.setAll('outOfBoundsKill', true); + + // The enemy's bullets + // enemyBullets = game.add.group(); + // enemyBullets.createMultiple(30, 'enemyBullet'); + // enemyBullets.setAll('anchor.x', 0.5); + // enemyBullets.setAll('anchor.y', 1); + // enemyBullets.setAll('outOfBoundsKill', true); + + // The hero! + // player = game.add.sprite(400, 500, 'ship'); + // player.anchor.setTo(0.5, 0.5); + + // The baddies! + aliens = game.add.group(); + + createAliens(); + + // The score + // scoreString = 'Score : '; + // scoreText = game.add.text(10, 10, scoreString + score, { fontSize: '34px', fill: '#fff' }); + + // Lives + // lives = game.add.group(); + // game.add.text(game.world.width - 100, 10, 'Lives : ', { fontSize: '34px', fill: '#fff' }); + + // Text + // stateText = game.add.text(game.world.centerX,game.world.centerY,'', { fontSize: '84px', fill: '#fff' }); + // stateText.anchor.setTo(0.5, 0.5); + // stateText.visible = false; + + // for (var i = 0; i < 3; i++) + // { + // var ship = lives.create(game.world.width - 100 + (30 * i), 60, 'ship'); + // ship.anchor.setTo(0.5, 0.5); + // ship.angle = 90; + // ship.alpha = 0.4; + // } + + // An explosion pool + // explosions = game.add.group(); + // explosions.createMultiple(30, 'kaboom'); + // explosions.forEach(setupInvader, this); + + // And some controls to play the game with + cursors = game.input.keyboard.createCursorKeys(); + // fireButton = game.input.keyboard.addKey(Phaser.Keyboard.SPACEBAR); +} + +function createAliens () { + +/* + for (var y = 0; y < 4; y++) + { + for (var x = 0; x < 10; x++) + { + var alien = aliens.create(x * 48, y * 50, 'invader'); + alien.anchor.setTo(0.5, 0.5); + alien.animations.add('fly', [ 0, 1, 2, 3 ], 20, true); + alien.play('fly'); + } + } +*/ + +bob = game.add.sprite(32, 32, 'invader'); + + // bob = aliens.create(48, 50, 'invader'); + + bob.debug = true; + + aliens.x = 100; + aliens.y = 50; + + // All this does is basically start the invaders moving. Notice we're moving the Group they belong to, rather than the invaders directly. + // var tween = game.add.tween(aliens).to( { x: 200 }, 2000, Phaser.Easing.Linear.None, true, 0, 1000, true); + + // When the tween completes it calls descend, before looping again + // tween.onComplete.add(descend, this); +} + +function setupInvader (invader) { + + invader.anchor.x = 0.5; + invader.anchor.y = 0.5; + invader.animations.add('kaboom'); + +} + +function descend() { + +console.log('descend'); + aliens.y += 10; + +} + +function update() { + + // aliens.x += 1; + bob.body.velocity.x = 100; + // bob.body.velocity.y = 100; + + // Scroll the background + // starfield.tilePosition.y += 2; + + // Reset the player, then check for movement keys + +/* + player.body.velocity.setTo(0, 0); + + if (cursors.left.isDown) + { + player.body.velocity.x = -200; + } + else if (cursors.right.isDown) + { + player.body.velocity.x = 200; + } + + // Firing? + if (fireButton.isDown) + { + fireBullet(); + } + + if (game.time.now > firingTimer) + { + enemyFires(); + } + + // Run collision + game.physics.collide(bullets, aliens, collisionHandler, null, this); + game.physics.collide(enemyBullets, player, enemyHitsPlayer, null, this); +*/ + +} + +/* + +function collisionHandler (bullet, alien) { + + // When a bullet hits an alien we kill them both + bullet.kill(); + alien.kill(); + + // Increase the score + score += 20; + scoreText.content = scoreString + score; + + // And create an explosion :) + var explosion = explosions.getFirstDead(); + explosion.reset(alien.body.x, alien.body.y); + explosion.play('kaboom', 30, false, true); + + if (aliens.countLiving() == 0) + { + score += 1000; + scoreText.content = scoreString + score; + + enemyBullets.callAll('kill',this); + stateText.content = " You Won, \n Click to restart"; + stateText.visible = true; + + //the "click to restart" handler + game.input.onTap.addOnce(restart,this); + } + +} + +function enemyHitsPlayer (player,bullet) { + + bullet.kill(); + + live = lives.getFirstAlive(); + + if (live) + { + live.kill(); + } + + // And create an explosion :) + var explosion = explosions.getFirstDead(); + explosion.reset(player.body.x, player.body.y); + explosion.play('kaboom', 30, false, true); + + // When the player dies + if (lives.countLiving() < 1) + { + player.kill(); + enemyBullets.callAll('kill'); + + stateText.content=" GAME OVER \n Click to restart"; + stateText.visible = true; + + //the "click to restart" handler + game.input.onTap.addOnce(restart,this); + } + +} + +function enemyFires () { + + // Grab the first bullet we can from the pool + enemyBullet = enemyBullets.getFirstExists(false); + + livingEnemies.length=0; + + aliens.forEachAlive(function(alien){ + + // put every living enemy in an array + livingEnemies.push(alien); + }); + + + if (enemyBullet && livingEnemies.length > 0) + { + + var random=game.rnd.integerInRange(0,livingEnemies.length); + + // randomly select one of them + var shooter=livingEnemies[random]; + // And fire the bullet from this enemy + enemyBullet.reset(shooter.body.x, shooter.body.y); + + game.physics.moveToObject(enemyBullet,player,120); + firingTimer = game.time.now + 2000; + } + +} + +function fireBullet () { + + // To avoid them being allowed to fire too fast we set a time limit + if (game.time.now > bulletTime) + { + // Grab the first bullet we can from the pool + bullet = bullets.getFirstExists(false); + + if (bullet) + { + // And fire it + bullet.reset(player.x, player.y + 8); + bullet.body.velocity.y = -400; + bulletTime = game.time.now + 200; + } + } + +} + +function resetBullet (bullet) { + + // Called if the bullet goes out of the screen + bullet.kill(); + +} + +function restart () { + + // A new level starts + + //resets the life count + lives.callAll('revive'); + // And brings the aliens back from the dead :) + aliens.removeAll(); + createAliens(); + + //revives the player + player.revive(); + //hides the text + stateText.visible = false; + +} + +*/ + +function render() { + + for (var i = 0; i < aliens._container.children.length; i++) + { + // game.debug.renderPhysicsBody(aliens._container.children[i].body); + } + + game.debug.renderPhysicsBody(bob.body); + +} \ No newline at end of file diff --git a/examples/wip/body scale.js b/examples/wip/body scale.js new file mode 100644 index 00000000..c40a8c56 --- /dev/null +++ b/examples/wip/body scale.js @@ -0,0 +1,48 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.spritesheet('gameboy', 'assets/sprites/gameboy_seize_color_40x60.png', 40, 60); + +} + +var sprite; +var sprite2; + +function create() { + + game.stage.backgroundColor = '#124184'; + + // Here we're tweening the scale of the sprite, which translates to the scale of the Body as well + // The collision will carry on working even against the scaled body. + + sprite = game.add.sprite(200, 300, 'gameboy', 2); + sprite.name = 'green'; + // sprite.anchor.setTo(0.5, 0.5); + sprite.body.immovable = true; + + sprite2 = game.add.sprite(600, 300, 'gameboy', 3); + sprite2.name = 'yellow'; + sprite2.body.rebound = false; + + // sprite2.body.velocity.x = -200; + + game.add.tween(sprite2).to( { x: 0 }, 3000, Phaser.Easing.Linear.None, true); + + // game.add.tween(sprite.scale).to( { x: 3, y: 3 }, 2000, Phaser.Easing.Linear.None, true, 0, 1000, true); + +} + +function update() { + + game.physics.collide(sprite, sprite2); + +} + +function render() { + + game.debug.renderPolygon(sprite.body.polygons, 'rgb(255,0,0)'); + game.debug.renderPolygon(sprite2.body.polygons, 'rgb(255,0,0)'); + +} diff --git a/examples/wip/bunny.js b/examples/wip/bunny.js index a86a6a8e..518e52a7 100644 --- a/examples/wip/bunny.js +++ b/examples/wip/bunny.js @@ -40,9 +40,9 @@ this.bunny.body.velocity.x = -500; } - // var melon = this.melonGroup.getFirstExists(true); - // melon.x = this.bunny.x; - // melon.y = this.bunny.y - 40; + var melon = this.melonGroup.getFirstExists(true); + melon.x = this.bunny.x; + melon.y = this.bunny.y - 40; this.carrot.x = this.bunny.x; this.carrot.y = this.bunny.y - 20; diff --git a/examples/wip/circlebox.js b/examples/wip/circlebox.js new file mode 100644 index 00000000..7291d406 --- /dev/null +++ b/examples/wip/circlebox.js @@ -0,0 +1,70 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('wizball', 'assets/sprites/wizball.png'); + game.load.image('platform', 'assets/sprites/interference_tunnel.png'); + +} + +var ball; +var circle; +var platform; + +function create() { + + // Our ball sprite + ball = game.add.sprite(440, 100, 'wizball'); + ball.anchor.setTo(0.5, 0.5); + + ball.body.customSeparateX = true; + ball.body.customSeparateY = true; + + ball.body.velocity.y = 150; + ball.body.bounce.y = 0.9; + + // Our collision circle + circle = new Phaser.Circle(200, 100, 188); + + // Our platform + platform = game.add.sprite(200, 450, 'platform'); + platform.body.immovable = true; + +} + +function update() { + + // ball.x = game.input.x; + // ball.y = game.input.y; + + circle.x = ball.x; + circle.y = ball.y; + + // This is a rect vs. rect collision. The callback will check the circle. + game.physics.overlap(ball, platform, collisionCallback, processCallback, this); + +} + +function collisionCallback(a, b) { + + ball.body.y -= 10; + ball.body.velocity.y *= -1 * ball.body.bounce.y; + +} + +function processCallback(a, b) { + + return (Phaser.Circle.intersectsRectangle(circle, platform.body)); + +} + +function render() { + + game.debug.renderText(Phaser.Circle.intersectsRectangle(circle, platform.body), 32, 32); + game.debug.renderText(ball.body.velocity.y, 32, 64); + // game.debug.renderText(ball.body.overlapY, 64, 64); + game.debug.renderCircle(circle); + game.debug.renderRectangle(platform.body); + +} diff --git a/examples/wip/commando.js b/examples/wip/commando.js new file mode 100644 index 00000000..2a3f40e1 --- /dev/null +++ b/examples/wip/commando.js @@ -0,0 +1,137 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.tilemap('map', 'assets/maps/commando.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('tiles', 'assets/maps/commando.png'); + game.load.image('phaser', 'assets/sprites/arrow.png'); + +} + +var cursors; +var map; +var layer; +var sprite; + +function create() { + + map = game.add.tilemap('map'); + + map.addTilesetImage('CommandoMap1-1BG_bank.png', 'tiles'); + + layer = map.createLayer('ShoeBox Tile Grab'); + // layer.debug = true; + layer.resizeWorld(); + + sprite = game.add.sprite(260, 100, 'phaser'); + sprite.anchor.setTo(0.5, 0.5); + + sprite.body.setSize(16, 16, 8, 8); + + // We'll set a lower max angular velocity here to keep it from going totally nuts + sprite.body.maxAngular = 500; + + // Apply a drag otherwise the sprite will just spin and never slow down + sprite.body.angularDrag = 50; + + game.camera.follow(sprite); + + cursors = game.input.keyboard.createCursorKeys(); + +} + +function update() { + +/* + if (cursors.left.isDown) + { + game.camera.x -= 1; + } + else if (cursors.right.isDown) + { + game.camera.x += 1; + } + + if (cursors.up.isDown) + { + layer.scrollY -= 4; + } + else if (cursors.down.isDown) + { + layer.scrollY += 4; + } +*/ + game.physics.collide(sprite, layer); + + sprite.body.velocity.x = 0; + sprite.body.velocity.y = 0; + sprite.body.angularVelocity = 0; + + // sprite.body.acceleration.x = 0; + // sprite.body.angularAcceleration = 0; + + if (cursors.left.isDown) + { + // sprite.body.acceleration.x = -200; + sprite.body.angularVelocity = -300; + // sprite.body.angularAcceleration -= 200; + } + else if (cursors.right.isDown) + { + // sprite.body.acceleration.x = 200; + sprite.body.angularVelocity = 300; + // sprite.body.angularAcceleration += 200; + } + + if (cursors.up.isDown) + { + game.physics.velocityFromAngle(sprite.angle, 300, sprite.body.velocity); + } + else + { + // game.physics.velocityFromAngle(sprite.angle, sprite.body.velocity, sprite.body.velocity); + } + + /* + sprite.body.velocity.x = 0; + sprite.body.velocity.y = 0; + + sprite.angle = sprite.angle + 1; + + if (cursors.up.isDown) + { + sprite.body.velocity.y = -900; + } + else if (cursors.down.isDown) + { + sprite.body.velocity.y = 900; + } + + if (cursors.left.isDown) + { + sprite.body.velocity.x = -900; + // sprite.scale.x = -1; + } + else if (cursors.right.isDown) + { + sprite.body.velocity.x = 900; + // sprite.scale.x = 1; + } + */ + + +} + +function render() { + + // game.debug.renderSpriteBody(sprite); + // game.debug.renderSpriteBounds(sprite); + + // game.debug.renderText(sprite.x, 32, 32); + // game.debug.renderText(sprite.y, 32, 48); + + // game.debug.renderText(layer.scrollX, 32, 32); + // game.debug.renderText(layer.scrollY, 32, 48); + +} \ No newline at end of file diff --git a/examples/wip/create map polygon.js b/examples/wip/create map polygon.js new file mode 100644 index 00000000..c461bf3a --- /dev/null +++ b/examples/wip/create map polygon.js @@ -0,0 +1,234 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + // game.load.tilemap('map', 'assets/tilemaps/maps/platform.json', null, Phaser.Tilemap.TILED_JSON); + // game.load.image('platformer_tiles', 'assets/tilemaps/tiles/platformer_tiles.png'); + + game.load.tilemap('map', 'assets/tilemaps/maps/features_test.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png'); + game.load.image('walls_1x2', 'assets/tilemaps/tiles/walls_1x2.png'); + game.load.image('tiles2', 'assets/tilemaps/tiles/tiles2.png'); + + +} + +var map; +var layer; +var mapLayer; + +var polys = []; +var tiles = []; +var idx = 0; +var group = []; + +function create() { + + game.stage.backgroundColor = '#124184'; + + // map = game.add.tilemap('map'); + // map.addTilesetImage('platformer_tiles'); + // map.setCollisionBetween(21, 53); + // layer = map.createLayer('Tile Layer 1'); + // layer.debug = true; + + map = game.add.tilemap('map'); + map.addTilesetImage('ground_1x1'); + map.addTilesetImage('walls_1x2'); + map.addTilesetImage('tiles2'); + map.setCollisionBetween(1, 12); + layer = map.createLayer('Tile Layer 1'); + + mapLayer = map.layers[0]; + + tiles = getInterestingTiles(); + + console.log('found',tiles.length,'interesting tiles'); + + + // group = []; + + // var tile = getFirstUnscanned(); + + // console.log('starting from', tile); + + // floodFill(tile); + + // console.log('group collected, size', group.length); + + // now scan the group + // scanEdges(); + + + + // works great :) + while (getScannedLeft() > 0) { + + // group = []; + + var tile = getFirstUnscanned(); + + console.log('starting from', tile); + + floodFill(tile); + + console.log('group collected, size', group.length); + + console.log('remaining: ', getScannedLeft()); + + } + +} + +function getFirstUnscanned() { + + for (var i = 0; i < tiles.length; i++) + { + if (!tiles[i].scanned) + { + return tiles[i]; + } + } + +} + +function getScannedLeft() { + + var total = tiles.length; + + for (var i = 0; i < tiles.length; i++) + { + if (tiles[i].scanned) + { + total--; + } + } + + return total; + +} + +var current; + +function scanEdges() { + + var points = []; + + var start = group[0]; + + // special case for when group.length = 1 should go here + + + +} + +function scanTop(origin) { + +} + +function floodFill(origin) { + + if (origin.scanned === true) + { + return; + } + + origin.scanned = true; + + group.push(origin); + + // console.log('ff origin', origin.x, origin.y); + + var west = map.getTileLeft(0, origin.x, origin.y); + + if (west && (west.faceTop || west.faceBottom || west.faceLeft || west.faceRight)) + { + // console.log('west found', west); + floodFill(west); + } + + var east = map.getTileRight(0, origin.x, origin.y); + + if (east && (east.faceTop || east.faceBottom || east.faceLeft || east.faceRight)) + { + // console.log('east found', east); + floodFill(east); + } + + var north = map.getTileAbove(0, origin.x, origin.y); + + if (north && (north.faceTop || north.faceBottom || north.faceLeft || north.faceRight)) + { + // console.log('north found', north); + floodFill(north); + } + + var south = map.getTileBelow(0, origin.x, origin.y); + + if (south && (south.faceTop || south.faceBottom || south.faceLeft || south.faceRight)) + { + // console.log('south found', south); + floodFill(south); + } + +} + +function getInterestingTiles() { + + var tiles = []; + + for (var y = 0, h = mapLayer.height; y < h; y++) + { + for (var x = 0, w = mapLayer.width; x < w; x++) + { + var tile = mapLayer.data[y][x]; + + if (tile && (tile.faceTop || tile.faceBottom || tile.faceLeft || tile.faceRight)) + { + // reset the scanned status + tile.scanned = false; + tiles.push(tile); + } + } + } + + return tiles; + +} + +function getTile() { + + for (var y = 0, h = mapLayer.height; y < h; y++) + { + for (var x = 0, w = mapLayer.width; x < w; x++) + { + var tile = mapLayer.data[y][x]; + + if (tile && (tile.faceTop || tile.faceBottom || tile.faceLeft || tile.faceRight)) + { + return tile; + } + } + } + +} + +function update() { + + +} + +function render() { + + if (group) + { + game.context.fillStyle = 'rgba(255,0,0,0.7)'; + + for (var i = 0; i < group.length; i++) + { + game.context.fillRect(group[i].x * group[i].width, group[i].y * group[i].height, group[i].width, group[i].height); + } + } + +} \ No newline at end of file diff --git a/examples/wip/demo worm.js b/examples/wip/demo worm.js new file mode 100644 index 00000000..8c764ee1 --- /dev/null +++ b/examples/wip/demo worm.js @@ -0,0 +1,79 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('ball', 'assets/sprites/shinyball.png'); + +} + +var sprite; +var particles = []; +var bmd; + +var u = 0; +var n = 0; +var oldn = 0; +var ad = 0; + +function create() { + + bmd = game.add.bitmapData(800, 600); + + for (var i = 0; i < 60; i++) + { + particles.push(new Phaser.Point(0, 0)); + } + + sprite = game.add.sprite(0, 0, bmd); + +} + +function mycircle(context, x, y, R, color) { + + //R = 64; + + context.fillStyle = color; + context.beginPath(); + context.arc(x, y, R, 0, Math.PI * 2, true); + context.closePath(); + context.fill(); + +} + +function update() { + + bmd.clear(); + + oldn = n; + + for (var t = 0; t < particles.length; t++) + { + var p = particles[t]; + + // p.x = Math.sin(n) * 50 + Math.cos(n * 1.5) * 300; + // p.y = Math.sin(n / 2) * 20 + Math.sin(n * 2) * 250; + + p.x = Math.cos(n) * 50 + Math.sin(n * 1.5) * 300; + p.y = Math.cos(n / 2) * 20 + Math.cos(n * 2) * 250; + + var tx = p.x; + var ty = p.y; + + bmd.context.globalCompositeOperation = 'xor'; + + //mycircle(bmd.context, p.x + 400, p.y + 300, Math.sin(t * 360 / particles.length / 2 * Math.PI / 180) * 50, 'rgba(255, 255, 0, 1)'); + mycircle(bmd.context, p.x + 400, p.y + 300, Math.sin(t * 360 / particles.length / 2 * Math.PI / 180) * 50, 'rgba(255, 255, 0, 1)'); + + n += 0.05; + + //bmd.context.globalCompositeOperation = 'source-over'; + } + + n = oldn + 0.02; + +} + +function render() { + +} diff --git a/examples/wip/dragonfire.js b/examples/wip/dragonfire.js new file mode 100644 index 00000000..3525bac3 --- /dev/null +++ b/examples/wip/dragonfire.js @@ -0,0 +1,53 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +var background; +var filter; + +function preload() { + + game.load.spritesheet('dragon', 'assets/sprites/stormlord-dragon96x64.png', 96, 64); + game.load.image('sky', 'assets/skies/sky2.png'); + game.load.image('land', 'assets/wip/karamoon.png'); + game.load.script('fire', '../filters/Fire.js'); + +} + +var sky; +var background; +var fire; +var dragon; + +function create() { + + sky = game.add.sprite(0, 600, 'sky'); + sky.scale.y = -1; + sky.alpha = 0.5; + + fire = game.add.sprite(0, 200); + fire.width = 800; + fire.height = 400; + + background = game.add.sprite(0, 0, 'land'); + + dragon = game.add.sprite(100, 300, 'dragon'); + dragon.animations.add('flyright', [0,1,2,3,4,5], 10, true); + dragon.play('flyright'); + + filter = game.add.filter('Fire', 800, 400); + filter.alpha = 0.0; + fire.filters = [filter]; + +} + +function update() { + + filter.update(); + +} + +function render() { + + // filter.update(); + +} diff --git a/examples/wip/TRSIPlasmaFilter.js b/examples/wip/filters/TRSIPlasmaFilter.js similarity index 100% rename from examples/wip/TRSIPlasmaFilter.js rename to examples/wip/filters/TRSIPlasmaFilter.js diff --git a/examples/wip/binarySerpentsFilter.js b/examples/wip/filters/binarySerpentsFilter.js similarity index 100% rename from examples/wip/binarySerpentsFilter.js rename to examples/wip/filters/binarySerpentsFilter.js diff --git a/examples/wip/c64PlasmaFilter.js b/examples/wip/filters/c64PlasmaFilter.js similarity index 100% rename from examples/wip/c64PlasmaFilter.js rename to examples/wip/filters/c64PlasmaFilter.js diff --git a/examples/wip/caustic lights.js b/examples/wip/filters/caustic lights.js similarity index 100% rename from examples/wip/caustic lights.js rename to examples/wip/filters/caustic lights.js diff --git a/examples/wip/checkerWaveFilter.js b/examples/wip/filters/checkerWaveFilter.js similarity index 100% rename from examples/wip/checkerWaveFilter.js rename to examples/wip/filters/checkerWaveFilter.js diff --git a/examples/wip/classicTunnelFilter.js b/examples/wip/filters/classicTunnelFilter.js similarity index 100% rename from examples/wip/classicTunnelFilter.js rename to examples/wip/filters/classicTunnelFilter.js diff --git a/examples/wip/colorBoxFilter.js b/examples/wip/filters/colorBoxFilter.js similarity index 100% rename from examples/wip/colorBoxFilter.js rename to examples/wip/filters/colorBoxFilter.js diff --git a/examples/wip/colorWaveFilter.js b/examples/wip/filters/colorWaveFilter.js similarity index 100% rename from examples/wip/colorWaveFilter.js rename to examples/wip/filters/colorWaveFilter.js diff --git a/examples/wip/colorbars_demo.js b/examples/wip/filters/colorbars_demo.js similarity index 100% rename from examples/wip/colorbars_demo.js rename to examples/wip/filters/colorbars_demo.js diff --git a/examples/wip/deformStarFilter.js b/examples/wip/filters/deformStarFilter.js similarity index 100% rename from examples/wip/deformStarFilter.js rename to examples/wip/filters/deformStarFilter.js diff --git a/examples/wip/fakeLenseFilter.js b/examples/wip/filters/fakeLenseFilter.js similarity index 100% rename from examples/wip/fakeLenseFilter.js rename to examples/wip/filters/fakeLenseFilter.js diff --git a/examples/wip/filter.js b/examples/wip/filters/filter.js similarity index 100% rename from examples/wip/filter.js rename to examples/wip/filters/filter.js diff --git a/examples/wip/fireFilter.js b/examples/wip/filters/fireFilter.js similarity index 100% rename from examples/wip/fireFilter.js rename to examples/wip/filters/fireFilter.js diff --git a/examples/wip/fire_demo.js b/examples/wip/filters/fire_demo.js similarity index 100% rename from examples/wip/fire_demo.js rename to examples/wip/filters/fire_demo.js diff --git a/examples/wip/flameFilter.js b/examples/wip/filters/flameFilter.js similarity index 100% rename from examples/wip/flameFilter.js rename to examples/wip/filters/flameFilter.js diff --git a/examples/wip/flowerFilter.js b/examples/wip/filters/flowerFilter.js similarity index 100% rename from examples/wip/flowerFilter.js rename to examples/wip/filters/flowerFilter.js diff --git a/examples/wip/fractalRayMarchFilter.js b/examples/wip/filters/fractalRayMarchFilter.js similarity index 100% rename from examples/wip/fractalRayMarchFilter.js rename to examples/wip/filters/fractalRayMarchFilter.js diff --git a/examples/wip/heroku.js b/examples/wip/filters/heroku.js similarity index 100% rename from examples/wip/heroku.js rename to examples/wip/filters/heroku.js diff --git a/examples/wip/hueRotationFilter.js b/examples/wip/filters/hueRotationFilter.js similarity index 100% rename from examples/wip/hueRotationFilter.js rename to examples/wip/filters/hueRotationFilter.js diff --git a/examples/wip/hypnoticRipplesFilter.js b/examples/wip/filters/hypnoticRipplesFilter.js similarity index 100% rename from examples/wip/hypnoticRipplesFilter.js rename to examples/wip/filters/hypnoticRipplesFilter.js diff --git a/examples/wip/icosohedronFilter.js b/examples/wip/filters/icosohedronFilter.js similarity index 100% rename from examples/wip/icosohedronFilter.js rename to examples/wip/filters/icosohedronFilter.js diff --git a/examples/wip/filters/index.php b/examples/wip/filters/index.php new file mode 100644 index 00000000..7938ad82 --- /dev/null +++ b/examples/wip/filters/index.php @@ -0,0 +1,109 @@ + $value) + { + if (is_array($value) && count($value) > 0) + { + $total += count($value); + } + } + + function getFile() { + + global $files, $dir, $filename, $title, $code; + + if (isset($_GET['d']) && isset($_GET['f'])) + { + $dir = urldecode($_GET['d']); + $filename = urldecode($_GET['d']) . '/' . urldecode($_GET['f']); + $title = urldecode($_GET['t']); + + if (file_exists($filename)) + { + $code = file_get_contents($filename); + $files = dirToArray($dir); + } + } + + } + + function dirToArray($dir) { + + $ignore = array('.', '..', '_site', 'assets', 'states', 'book'); + $result = array(); + $root = scandir($dir); + $dirs = array_diff($root, $ignore); + + foreach ($dirs as $key => $value) + { + if (is_dir($dir . DIRECTORY_SEPARATOR . $value)) + { + $result[$value] = dirToArray($dir . DIRECTORY_SEPARATOR . $value); + } + else + { + if (substr($value, -3) == '.js') + { + $result[] = $value; + } + } + } + + return $result; + } + + function printJSLinks($dir, $files) { + + $output = ""; + + foreach ($files as $key => $value) + { + $value2 = substr($value, 0, -3); + $file = urlencode($value); + + $output .= "$value2
    "; + } + + return $output; + + } +?> + + + + + phaser + + + + + + + + +
    + +

    work in progress filters

    + + + + + \ No newline at end of file diff --git a/examples/wip/lightbeam_demo.js b/examples/wip/filters/lightbeam_demo.js similarity index 100% rename from examples/wip/lightbeam_demo.js rename to examples/wip/filters/lightbeam_demo.js diff --git a/examples/wip/mengerTunnelFilter.js b/examples/wip/filters/mengerTunnelFilter.js similarity index 100% rename from examples/wip/mengerTunnelFilter.js rename to examples/wip/filters/mengerTunnelFilter.js diff --git a/examples/wip/metaBallsFilter.js b/examples/wip/filters/metaBallsFilter.js similarity index 100% rename from examples/wip/metaBallsFilter.js rename to examples/wip/filters/metaBallsFilter.js diff --git a/examples/wip/mouseStarFilter.js b/examples/wip/filters/mouseStarFilter.js similarity index 100% rename from examples/wip/mouseStarFilter.js rename to examples/wip/filters/mouseStarFilter.js diff --git a/examples/wip/mysteryVortexFilter.js b/examples/wip/filters/mysteryVortexFilter.js similarity index 100% rename from examples/wip/mysteryVortexFilter.js rename to examples/wip/filters/mysteryVortexFilter.js diff --git a/examples/wip/planeDeformationFilter.js b/examples/wip/filters/planeDeformationFilter.js similarity index 100% rename from examples/wip/planeDeformationFilter.js rename to examples/wip/filters/planeDeformationFilter.js diff --git a/examples/wip/plasma3DFilter.js b/examples/wip/filters/plasma3DFilter.js similarity index 100% rename from examples/wip/plasma3DFilter.js rename to examples/wip/filters/plasma3DFilter.js diff --git a/examples/wip/plasmaBeamFilter.js b/examples/wip/filters/plasmaBeamFilter.js similarity index 100% rename from examples/wip/plasmaBeamFilter.js rename to examples/wip/filters/plasmaBeamFilter.js diff --git a/examples/wip/plasmaFilter.js b/examples/wip/filters/plasmaFilter.js similarity index 100% rename from examples/wip/plasmaFilter.js rename to examples/wip/filters/plasmaFilter.js diff --git a/examples/wip/plasmaFlowerFilter.js b/examples/wip/filters/plasmaFlowerFilter.js similarity index 100% rename from examples/wip/plasmaFlowerFilter.js rename to examples/wip/filters/plasmaFlowerFilter.js diff --git a/examples/wip/plasma_demo.js b/examples/wip/filters/plasma_demo.js similarity index 100% rename from examples/wip/plasma_demo.js rename to examples/wip/filters/plasma_demo.js diff --git a/examples/wip/pulsingInterferenceFilter.js b/examples/wip/filters/pulsingInterferenceFilter.js similarity index 100% rename from examples/wip/pulsingInterferenceFilter.js rename to examples/wip/filters/pulsingInterferenceFilter.js diff --git a/examples/wip/rayTracedBallsFilter.js b/examples/wip/filters/rayTracedBallsFilter.js similarity index 100% rename from examples/wip/rayTracedBallsFilter.js rename to examples/wip/filters/rayTracedBallsFilter.js diff --git a/examples/wip/retroPlasmaFilter.js b/examples/wip/filters/retroPlasmaFilter.js similarity index 100% rename from examples/wip/retroPlasmaFilter.js rename to examples/wip/filters/retroPlasmaFilter.js diff --git a/examples/wip/rotationalFractalsFilter.js b/examples/wip/filters/rotationalFractalsFilter.js similarity index 100% rename from examples/wip/rotationalFractalsFilter.js rename to examples/wip/filters/rotationalFractalsFilter.js diff --git a/examples/wip/rotoZoomerFilter.js b/examples/wip/filters/rotoZoomerFilter.js similarity index 100% rename from examples/wip/rotoZoomerFilter.js rename to examples/wip/filters/rotoZoomerFilter.js diff --git a/examples/wip/shadertoy-effect.js b/examples/wip/filters/shadertoy-effect.js similarity index 100% rename from examples/wip/shadertoy-effect.js rename to examples/wip/filters/shadertoy-effect.js diff --git a/examples/wip/shinyTaffyFilter.js b/examples/wip/filters/shinyTaffyFilter.js similarity index 100% rename from examples/wip/shinyTaffyFilter.js rename to examples/wip/filters/shinyTaffyFilter.js diff --git a/examples/wip/sineWaveFilter.js b/examples/wip/filters/sineWaveFilter.js similarity index 100% rename from examples/wip/sineWaveFilter.js rename to examples/wip/filters/sineWaveFilter.js diff --git a/examples/wip/sineWaveFixedBaseFilter.js b/examples/wip/filters/sineWaveFixedBaseFilter.js similarity index 100% rename from examples/wip/sineWaveFixedBaseFilter.js rename to examples/wip/filters/sineWaveFixedBaseFilter.js diff --git a/examples/wip/softTunnelFilter.js b/examples/wip/filters/softTunnelFilter.js similarity index 100% rename from examples/wip/softTunnelFilter.js rename to examples/wip/filters/softTunnelFilter.js diff --git a/examples/wip/spaceRacingLiteFilter.js b/examples/wip/filters/spaceRacingLiteFilter.js similarity index 100% rename from examples/wip/spaceRacingLiteFilter.js rename to examples/wip/filters/spaceRacingLiteFilter.js diff --git a/examples/wip/starNestFilter.js b/examples/wip/filters/starNestFilter.js similarity index 100% rename from examples/wip/starNestFilter.js rename to examples/wip/filters/starNestFilter.js diff --git a/examples/wip/starNurseryFilter.js b/examples/wip/filters/starNurseryFilter.js similarity index 100% rename from examples/wip/starNurseryFilter.js rename to examples/wip/filters/starNurseryFilter.js diff --git a/examples/wip/starfieldFilter.js b/examples/wip/filters/starfieldFilter.js similarity index 100% rename from examples/wip/starfieldFilter.js rename to examples/wip/filters/starfieldFilter.js diff --git a/examples/wip/starsBackgroundFilter.js b/examples/wip/filters/starsBackgroundFilter.js similarity index 100% rename from examples/wip/starsBackgroundFilter.js rename to examples/wip/filters/starsBackgroundFilter.js diff --git a/examples/wip/tex00.jpg b/examples/wip/filters/tex00.jpg similarity index 100% rename from examples/wip/tex00.jpg rename to examples/wip/filters/tex00.jpg diff --git a/examples/wip/tex01.jpg b/examples/wip/filters/tex01.jpg similarity index 100% rename from examples/wip/tex01.jpg rename to examples/wip/filters/tex01.jpg diff --git a/examples/wip/tex02.jpg b/examples/wip/filters/tex02.jpg similarity index 100% rename from examples/wip/tex02.jpg rename to examples/wip/filters/tex02.jpg diff --git a/examples/wip/tex03.jpg b/examples/wip/filters/tex03.jpg similarity index 100% rename from examples/wip/tex03.jpg rename to examples/wip/filters/tex03.jpg diff --git a/examples/wip/tex04.jpg b/examples/wip/filters/tex04.jpg similarity index 100% rename from examples/wip/tex04.jpg rename to examples/wip/filters/tex04.jpg diff --git a/examples/wip/tex05.jpg b/examples/wip/filters/tex05.jpg similarity index 100% rename from examples/wip/tex05.jpg rename to examples/wip/filters/tex05.jpg diff --git a/examples/wip/tex06.jpg b/examples/wip/filters/tex06.jpg similarity index 100% rename from examples/wip/tex06.jpg rename to examples/wip/filters/tex06.jpg diff --git a/examples/wip/tex07.jpg b/examples/wip/filters/tex07.jpg similarity index 100% rename from examples/wip/tex07.jpg rename to examples/wip/filters/tex07.jpg diff --git a/examples/wip/tex08.jpg b/examples/wip/filters/tex08.jpg similarity index 100% rename from examples/wip/tex08.jpg rename to examples/wip/filters/tex08.jpg diff --git a/examples/wip/tex09.jpg b/examples/wip/filters/tex09.jpg similarity index 100% rename from examples/wip/tex09.jpg rename to examples/wip/filters/tex09.jpg diff --git a/examples/wip/tex10.png b/examples/wip/filters/tex10.png similarity index 100% rename from examples/wip/tex10.png rename to examples/wip/filters/tex10.png diff --git a/examples/wip/tex11.png b/examples/wip/filters/tex11.png similarity index 100% rename from examples/wip/tex11.png rename to examples/wip/filters/tex11.png diff --git a/examples/wip/tex12.png b/examples/wip/filters/tex12.png similarity index 100% rename from examples/wip/tex12.png rename to examples/wip/filters/tex12.png diff --git a/examples/wip/tex14.png b/examples/wip/filters/tex14.png similarity index 100% rename from examples/wip/tex14.png rename to examples/wip/filters/tex14.png diff --git a/examples/wip/tex15.png b/examples/wip/filters/tex15.png similarity index 100% rename from examples/wip/tex15.png rename to examples/wip/filters/tex15.png diff --git a/examples/wip/tex16.png b/examples/wip/filters/tex16.png similarity index 100% rename from examples/wip/tex16.png rename to examples/wip/filters/tex16.png diff --git a/examples/wip/trippyLinesFilter.js b/examples/wip/filters/trippyLinesFilter.js similarity index 100% rename from examples/wip/trippyLinesFilter.js rename to examples/wip/filters/trippyLinesFilter.js diff --git a/examples/wip/tunnelFilter.js b/examples/wip/filters/tunnelFilter.js similarity index 100% rename from examples/wip/tunnelFilter.js rename to examples/wip/filters/tunnelFilter.js diff --git a/examples/wip/tunnel_demo.js b/examples/wip/filters/tunnel_demo.js similarity index 100% rename from examples/wip/tunnel_demo.js rename to examples/wip/filters/tunnel_demo.js diff --git a/examples/wip/vortexFilter.js b/examples/wip/filters/vortexFilter.js similarity index 100% rename from examples/wip/vortexFilter.js rename to examples/wip/filters/vortexFilter.js diff --git a/examples/wip/wobbleFilter.js b/examples/wip/filters/wobbleFilter.js similarity index 100% rename from examples/wip/wobbleFilter.js rename to examples/wip/filters/wobbleFilter.js diff --git a/examples/wip/fixdrag.js b/examples/wip/fixdrag.js new file mode 100644 index 00000000..4ec838a7 --- /dev/null +++ b/examples/wip/fixdrag.js @@ -0,0 +1,72 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.stage.backgroundColor = '#007236'; + + game.load.image('ball', 'assets/sprites/shinyball.png'); + game.load.image('mushroom', 'assets/sprites/mushroom2.png'); + game.load.image('phaser', 'assets/sprites/sonic_havok_sanity.png'); + +} + +var sprite; +var cursors; + +function create() { + + game.world.setBounds(0, 0, 1000, 1000); + + for (var i = 0; i < 100; i++) + { + game.add.sprite(game.world.randomX, game.world.randomY, 'mushroom'); + } + + sprite = game.add.sprite(200, 200, 'ball'); + + sprite.fixedToCamera = true; + // sprite.cameraOffset.setTo(200, 200); + + + sprite.inputEnabled = true; + sprite.input.enableDrag(); + sprite.events.onInputOver.add(wibble, this); + + cursors = game.input.keyboard.createCursorKeys(); + +} + +function wibble() { + console.log('over'); +} + +function update() { + + if (cursors.up.isDown) + { + game.camera.y -= 4; + } + else if (cursors.down.isDown) + { + game.camera.y += 4; + } + + if (cursors.left.isDown) + { + game.camera.x -= 4; + } + else if (cursors.right.isDown) + { + game.camera.x += 4; + } + +} + +function render() { + + game.debug.renderText(sprite.cameraOffset.x, 32, 32); + game.debug.renderText(sprite.cameraOffset.y, 32, 64); + game.debug.renderPointer(game.input.activePointer); + +} diff --git a/examples/wip/gravity.js b/examples/wip/gravity.js new file mode 100644 index 00000000..7906e98f --- /dev/null +++ b/examples/wip/gravity.js @@ -0,0 +1,39 @@ +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + game.load.image('arrow', 'assets/sprites/arrow.png'); + +} + +var sprite; + +var setGravityToPointXY = function(game,sprite,power, radiusLow,radiusHigh,pointX,pointY){ + var pointXY = new Phaser.Point(pointX,pointY); + var tempDistance = Phaser.Point.distance(sprite,pointXY); + if(tempDistance>radiusLow&&tempDistance phaser + + + +

    work in progress examples

    -1){ + + C.x = pa[n].x; + C.y = pa[n].y; + + if(n > 0){ + + cx+=C.x; + cy+=C.y; + + D=Point(pa[n-1])||Point(pa[0]); + + i=lineIntersectLine(A,B,C,D); + + if(i != null){ + result.intersections.push(i); + } + if(lineIntersectLine(A,new Point(C.x+D.x,A.y),C,D) != null){ + An++; + } + if(lineIntersectLine(B,new Point(C.x+D.x,B.y),C,D) != null){ + Bn++; + } + } + n--; + } + if(An % 2 == 0){ + result.start_inside=true; + } + if(Bn % 2 == 0){ + result.end_inside=true; + } + result.centroid=new Point(cx/(pa.length-1),cy/(pa.length-1)); + result.intersects = result.intersections.length > 0; + return result; +} +*/ + +var c = 'rgb(255,255,255)'; +var p = new Phaser.Point(); + +function update() { + + line1.fromSprite(handle1, handle2, true); + line2.fromSprite(handle3, handle4, true); + + p = line1.intersects(line2, true); + + if (p) + { + c = 'rgb(0,255,0)'; + } + else + { + c = 'rgb(255,255,255)'; + } + +} + +function render() { + + game.debug.renderLine(line1, c); + game.debug.renderLine(line2, c); + + game.debug.renderLineInfo(line1, 32, 32); + game.debug.renderLineInfo(line2, 32, 100); + + if (p) + { + game.context.fillStyle = 'rgb(255,0,255)'; + game.context.fillRect(p.x - 2, p.y - 2, 5, 5); + } + +} \ No newline at end of file diff --git a/examples/wip/line polygon.js b/examples/wip/line polygon.js new file mode 100644 index 00000000..6941b7ff --- /dev/null +++ b/examples/wip/line polygon.js @@ -0,0 +1,163 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.spritesheet('balls', 'assets/sprites/balls.png', 17, 17); + +} + +var handle1; +var handle2; + +var line; +var polygon; + +function create() { + + game.stage.backgroundColor = '#124184'; + + handle1 = game.add.sprite(100, 150, 'balls', 0); + handle1.inputEnabled = true; + handle1.input.enableDrag(true); + + handle2 = game.add.sprite(400, 200, 'balls', 0); + handle2.inputEnabled = true; + handle2.input.enableDrag(true); + + line = new Phaser.Line(handle1.x, handle1.y, handle2.x, handle2.y); + + polygon = new SAT.Polygon(new SAT.Vector(300, 300), [new SAT.Vector(0, 50), new SAT.Vector(100, 50), new SAT.Vector(100, 0), new SAT.Vector(150, 0), new SAT.Vector(150, 150), new SAT.Vector(100, 150), new SAT.Vector(100, 100), new SAT.Vector(0, 100), new SAT.Vector(0, 50)]); + +} + +/*--------------------------------------------------------------------------- +Returns an Object with the following properties: +intersects -Boolean indicating if an intersection exists. +start_inside -Boolean indicating if Point A is inside of the polygon. +end_inside -Boolean indicating if Point B is inside of the polygon. +intersections -Array of intersection Points along the polygon. +centroid -A Point indicating "center of mass" of the polygon. + +"pArry" is an Array of Points. +----------------------------------------------------------------------------*/ + +function lineIntersectPoly(A, B, polygon) { + + var An =1; + var Bn =1; + var C = {x: 0, y: 0}; + var D = {x: 0, y: 0}; + var i = {x: 0, y: 0}; + var cx=0; + var cy=0; + var result = {}; + + var pa = []; + + for (var pi = 0; pi < polygon.points.length; pi++) + { + pa.push({ x: polygon.points[pi].x + polygon.pos.x, y: polygon.points[pi].y + polygon.pos.y }) + } + + pa.push(pa[0]); //Create line from last Point to beginning Point + + result.intersects = false; + result.intersections=[]; + result.start_inside=false; + result.end_inside=false; + + var n = pa.length-1; + + while(n > -1){ + + C.x = pa[n].x; + C.y = pa[n].y; + + if(n > 0){ + + cx+=C.x; + cy+=C.y; + + D.x = pa[n-1].x || pa[0].x; + D.y = pa[n-1].y || pa[0].y; + + i=Phaser.Line.intersectsPoints(A,B,C,D); + + if(i != null){ + result.intersections.push(i); + } + if(Phaser.Line.intersectsPoints(A,new Phaser.Point(C.x+D.x,A.y),C,D) != null){ + An++; + } + if(Phaser.Line.intersectsPoints(B,new Phaser.Point(C.x+D.x,B.y),C,D) != null){ + Bn++; + } + } + n--; + } + if(An % 2 == 0){ + result.start_inside=true; + } + if(Bn % 2 == 0){ + result.end_inside=true; + } + result.centroid=new Phaser.Point(cx/(pa.length-1),cy/(pa.length-1)); + result.intersects = result.intersections.length > 0; + return result; +} + +var c = 'rgb(255,255,255)'; +var p = new Phaser.Point(); +var result = {}; + +function update() { + + line.fromSprite(handle1, handle2, true); + + result = lineIntersectPoly(line.start, line.end, polygon); + + handle1.frame = 0; + handle2.frame = 0; + + if (result.intersects) + { + c = 'rgb(0,255,0)'; + + if (result.start_inside) + { + handle1.frame = 1; + } + + if (result.end_inside) + { + handle2.frame = 1; + } + } + else + { + c = 'rgb(255,255,255)'; + } + +} + +function render() { + + game.debug.renderLine(line, c); + game.debug.renderLineInfo(line, 32, 32); + + game.debug.renderPolygon(polygon); + + if (result.intersects) + { + game.debug.renderText(result.intersects, 32, 100); + + game.context.fillStyle = 'rgb(255,0,255)'; + + for (var i = 0; i < result.intersections.length; i++) + { + game.context.fillRect(result.intersections[i].x - 2, result.intersections[i].y - 2, 5, 5); + } + } + +} \ No newline at end of file diff --git a/examples/wip/mod.js b/examples/wip/mod.js new file mode 100644 index 00000000..0fc25ae0 --- /dev/null +++ b/examples/wip/mod.js @@ -0,0 +1,174 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.script('pt', 'wip/pt.js'); + game.load.binary('impulse', 'assets/audio/protracker/act_of_impulse.mod', modLoaded, this); + game.load.binary('macrocosm', 'assets/audio/protracker/macrocosm.mod', modLoaded, this); + game.load.binary('enigma', 'assets/audio/protracker/enigma.mod', modLoaded, this); + game.load.binary('elysium', 'assets/audio/protracker/elysium.mod', modLoaded, this); + game.load.binary('stardust', 'assets/audio/protracker/sd-ingame1.mod', modLoaded, this); + game.load.binary('globaltrash', 'assets/audio/protracker/global_trash_3_v2.mod', modLoaded, this); + game.load.image('vu1', 'assets/sprites/flectrum.png'); + game.load.image('vu2', 'assets/sprites/flectrum2.png'); + game.load.image('vu3', 'assets/sprites/healthbar.png'); + +} + +function modLoaded(key, data) { + + console.log('module loaded:', key); + + var buffer = new Uint8Array(data); + + return buffer; + +} + +var vu1; +var vu2; +var vu3; +var vu4; + +var modsample = new Array(); +var module; + +var sample1; +var sample2; +var sample3; +var sample4; +var sampleName1; +var sampleName2; +var sampleName3; +var sampleName4; + +var r1; +var r2; +var r3; +var r4; + +function create() { + + // vu1 = game.add.sprite(400, 100, 'vu3'); + // vu2 = game.add.sprite(400, 150, 'vu3'); + // vu3 = game.add.sprite(400, 200, 'vu3'); + // vu4 = game.add.sprite(400, 250, 'vu3'); + + module = new Protracker(); +// module.buffer = game.cache.getBinary('globaltrash'); + module.buffer = game.cache.getBinary('macrocosm'); + module.parse(); + module.play(); + + r1 = new Phaser.Rectangle(400, 100, 100, 32); + r2 = new Phaser.Rectangle(400, 150, 100, 32); + r3 = new Phaser.Rectangle(400, 200, 100, 32); + r4 = new Phaser.Rectangle(400, 250, 100, 32); + + // console.log(module.sample); + +} + +function update() { + + sampleName1 = ''; + sampleName2 = ''; + sampleName3 = ''; + sampleName4 = ''; + + sample1 = module.channel[0].sample; + sample2 = module.channel[1].sample; + sample3 = module.channel[2].sample; + sample4 = module.channel[3].sample; + + /* + module.sample = array of Objects containing: + + data (Float32Array) + finetime + length (ms? bytes?) + looplength + loopstart + name + volume + +arpeggio: 0 +command: 0 +data: 0 +flags: 0 +note: 22 +noteon: 1 +period: 240 +sample: 11 +samplepos: 314.3411880952386 +samplespeed: 0.335118537414966 +semitone: 14 +slidespeed: 0 +slideto: 214 +slidetospeed: 0 +vibratodepth: 0 +vibratopos: 0 +vibratospeed: 0 +vibratowave: 0 +voiceperiod: 240 +volume: 64 + */ + + if (module.sample[sample1]) + { + sampleName1 = module.sample[sample1].name; + } + + if (module.sample[sample2]) + { + sampleName2 = module.sample[sample2].name; + } + + if (module.sample[sample3]) + { + sampleName3 = module.sample[sample3].name; + } + + if (module.sample[sample4]) + { + sampleName4 = module.sample[sample4].name; + } + + // vu1.width = Math.round(module.vu[0] * 400); + // vu2.width = Math.round(module.vu[1] * 400); + // vu3.width = Math.round(module.vu[2] * 400); + // vu4.width = Math.round(module.vu[3] * 400); + + r1.width = Math.round(module.vu[0] * 500); + r2.width = Math.round(module.vu[1] * 500); + r3.width = Math.round(module.vu[2] * 500); + r4.width = Math.round(module.vu[3] * 500); + +} + +function render() { + + game.debug.renderText('Sample ' + sample1 + ' : ' + sampleName1, 16, 32); + game.debug.renderText('Sample ' + sample2 + ' : ' + sampleName2, 16, 64); + game.debug.renderText('Sample ' + sample3 + ' : ' + sampleName3, 16, 96); + game.debug.renderText('Sample ' + sample4 + ' : ' + sampleName4, 16, 128); + + game.debug.renderText('Position: ' + module.position, 16, 160); + game.debug.renderText('Pattern: ' + module.row, 16, 192); + game.debug.renderText('BPM: ' + module.bpm, 16, 224); + game.debug.renderText('Speed: ' + module.speed, 16, 256); + game.debug.renderText('Name: ' + module.title, 16, 288); + game.debug.renderText('Author: ' + module.signature, 16, 320); + + game.debug.renderText('vu1: ' + module.vu[0], 16, 352); + game.debug.renderText('vu2: ' + module.vu[1], 16, 384); + game.debug.renderText('vu3: ' + module.vu[2], 16, 416); + game.debug.renderText('vu4: ' + module.vu[3], 16, 448); + + game.debug.renderRectangle(r1); + game.debug.renderRectangle(r2); + game.debug.renderRectangle(r3); + game.debug.renderRectangle(r4); + +} diff --git a/examples/wip/moveToPointer.js b/examples/wip/moveToPointer.js new file mode 100644 index 00000000..865825c9 --- /dev/null +++ b/examples/wip/moveToPointer.js @@ -0,0 +1,38 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create }); + +function preload() { + + game.load.image('arrow', 'assets/sprites/arrow.png'); + +} + +var sprite; +var tween; + +function create() { + + sprite = game.add.sprite(32, 32, 'arrow'); + + sprite.anchor.setTo(0.5, 0.5); + + game.input.onDown.add(moveSprite, this); + +} + +function moveSprite (pointer) { + + if (tween && tween.isRunning) + { + tween.stop(); + } + + sprite.rotation = game.physics.angleToPointer(sprite, pointer); + + // 300 = 300 pixels per second = the speed the sprite will move at, regardless of the distance it has to travel + var duration = (game.physics.distanceToPointer(sprite, pointer) / 300) * 1000; + + tween = game.add.tween(sprite).to({ x: pointer.x, y: pointer.y }, duration, Phaser.Easing.Linear.None, true); + +} + diff --git a/examples/wip/multiball.js b/examples/wip/multiball.js new file mode 100644 index 00000000..08bea551 --- /dev/null +++ b/examples/wip/multiball.js @@ -0,0 +1,40 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); + +function preload() { + + game.load.spritesheet('spinner', 'assets/sprites/bluemetal_32x32x4.png', 32, 32); + +} + +var sprites; + +function create() { + + // Here we create a group, populate it with sprites, give them all a random velocity + // and then check the group against itself for collision + + sprites = game.add.group(); + + for (var i = 0; i < 30; i++) + { + var s = sprites.create(game.rnd.integerInRange(100, 700), game.rnd.integerInRange(32, 200), 'spinner'); + s.animations.add('spin', [0,1,2,3]); + s.play('spin', 20, true); + s.body.velocity.x = game.rnd.integerInRange(-200, 200); + s.body.velocity.y = game.rnd.integerInRange(-200, 200); + } + + sprites.setAll('body.collideWorldBounds', true); + sprites.setAll('body.bounce.x', 1); + sprites.setAll('body.bounce.y', 1); + sprites.setAll('body.linearDamping', 0); + sprites.setAll('body.minBounceVelocity', 0); + +} + +function update() { + + game.physics.collide(sprites); + +} diff --git a/examples/wip/nested groups.js b/examples/wip/nested groups.js new file mode 100644 index 00000000..cf5902df --- /dev/null +++ b/examples/wip/nested groups.js @@ -0,0 +1,41 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); + +function preload() { + + game.load.image('ball', 'assets/sprites/pangball.png'); + game.load.image('arrow', 'assets/sprites/asteroids_ship.png'); + +} + +var ballsGroup; +var shipsGroup; + +function create() { + + ballsGroup = game.add.group(); + shipsGroup = game.add.group(); + + for (var i = 0; i < 20; i++) + { + // Create some randomly placed sprites in both Groups + ballsGroup.create(game.rnd.integerInRange(0, 128), game.world.randomY, 'ball'); + shipsGroup.create(game.rnd.integerInRange(0, 128), game.world.randomY, 'arrow'); + } + + // Now make the ships group a child of the balls group - so anything that happens to the balls group + // will happen to the ships group too + ballsGroup.add(shipsGroup); + +} + +function update() { + + ballsGroup.x += 0.1; + + // Because shipsGroup is a child of ballsGroup it has already been moved 0.1px by the line above + // So the following line of code will make it appear to move twice as fast as ballsGroup + shipsGroup.x += 0.1; + +} + diff --git a/examples/wip/one way collision.js b/examples/wip/one way collision.js new file mode 100644 index 00000000..61a4cc6d --- /dev/null +++ b/examples/wip/one way collision.js @@ -0,0 +1,325 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.spritesheet('gameboy', 'assets/sprites/gameboy_seize_color_40x60.png', 40, 60); + game.load.image('atari', 'assets/sprites/atari130xe.png'); + +} + +var sprite; +var sprite2; +var sprite3; +var reverse = false; + +function onBeginContact(a, b) { + console.log('Begin Contact between', a.name, 'and', b.name); +} + +function onEndContact(a, b) { + console.log('End Contact between', a.name, 'and', b.name); +} + +function create() { + + game.stage.backgroundColor = '#124184'; + + test8(); + +} + +function test8() { + + // A up into B + + sprite = game.add.sprite(300, 200, 'atari'); + sprite.name = 'atari'; + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(1, 1); + sprite.body.checkCollision.up = false; + sprite.body.checkCollision.down = false; + + sprite2 = game.add.sprite(350, 400, 'gameboy', 2); + sprite2.name = 'gameboy'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(1, 1); + + sprite2.events.onBeginContact.add(onBeginContact, this); + sprite2.events.onEndContact.add(onEndContact, this); + + reverse = true; + + game.input.onDown.add(launch8, this); + +} + +function launch8() { + + sprite2.body.velocity.x = -100; + sprite2.body.velocity.y = -200; + +} + +function test7() { + + // A down into B + + sprite = game.add.sprite(300, 400, 'atari'); + sprite.name = 'atari'; + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(1, 1); + sprite.body.checkCollision.up = false; + + sprite2 = game.add.sprite(350, 100, 'gameboy', 2); + sprite2.name = 'gameboy'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(1, 1); + + // reverse = true; + + game.input.onDown.add(launch7, this); + +} + +function launch7() { + + sprite2.body.velocity.y = 100; + +} + +function test6() { + + // Offset Down Collision false + + sprite = game.add.sprite(100, 300, 'atari'); + sprite.name = 'atari'; + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(1, 1); + sprite.body.checkCollision.left = false; + sprite.body.checkCollision.right = false; + + sprite2 = game.add.sprite(500, 330, 'gameboy', 2); + // sprite2 = game.add.sprite(500, 530, 'gameboy', 2); + sprite2.name = 'gameboy'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(1, 1); + + sprite3 = game.add.sprite(400, 100, 'gameboy', 0); + sprite3.name = 'gameboy2'; + sprite3.body.collideWorldBounds = true; + sprite3.body.bounce.setTo(1, 1); + + game.input.onDown.add(launch6, this); + +} + +function launch6() { + + sprite.body.velocity.x = 100; + sprite2.body.velocity.x = -100; + sprite3.body.velocity.y = 100; + +} + +function test5() { + + // Offset Down Collision false + + sprite = game.add.sprite(360, 400, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + // sprite.body.bounce.setTo(0.9, 0.9); + sprite.body.checkCollision.up = false; + + sprite2 = game.add.sprite(400, 200, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + // sprite2.body.checkCollision.down = false; + // sprite2.body.mass = 1; + sprite2.body.bounce.setTo(1, 1); + // sprite2.body.linearDamping = 0; + + game.input.onDown.add(launch5, this); + +} + +function launch5() { + + // sprite.body.velocity.x = 200; + // sprite.body.velocity.y = -300; + // sprite2.body.velocity.x = -200; + sprite2.body.velocity.y = 200; + +} + +function test4() { + + // Down Collision false + + sprite = game.add.sprite(400, 400, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(0.9, 0.9); + + sprite2 = game.add.sprite(400, 200, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + sprite2.body.checkCollision.down = false; + // sprite2.body.mass = 1; + // sprite2.body.bounce.setTo(1, 1); + // sprite2.body.linearDamping = 0; + + game.input.onDown.add(launch4, this); + +} + +function launch4() { + + // sprite.body.velocity.x = 200; + sprite.body.velocity.y = -300; + // sprite2.body.velocity.x = -200; + // sprite2.body.velocity.y = -200; + +} + +function test3() { + + // Top Collision false + + sprite = game.add.sprite(400, 400, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.checkCollision.up = false; + + sprite2 = game.add.sprite(400, 200, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + // sprite2.body.checkCollision.left = false; + sprite2.body.bounce.setTo(0.9, 0.9); + // sprite2.body.mass = 1; + // sprite2.body.bounce.setTo(1, 1); + // sprite2.body.linearDamping = 0; + + game.input.onDown.add(launch3, this); + +} + +function launch3() { + + // sprite.body.velocity.x = 200; + // sprite.body.velocity.y = -300; + // sprite2.body.velocity.x = -200; + sprite2.body.velocity.y = 200; + +} + +function test2() { + + // Left Collision false + + sprite = game.add.sprite(200, 300, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + // sprite.body.checkCollision.right = false; + sprite.body.bounce.setTo(0.9, 0.9); + // sprite.body.linearDamping = 0; + // sprite.scale.setTo(2, 2); + // sprite.body.mass = 2; + + sprite2 = game.add.sprite(500, 300, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + sprite2.body.checkCollision.left = false; + // sprite2.body.bounce.setTo(0.9, 0.9); + // sprite2.body.mass = 1; + // sprite2.body.bounce.setTo(1, 1); + // sprite2.body.linearDamping = 0; + + game.input.onDown.add(launch2, this); + +} + +function launch2() { + + sprite.body.velocity.x = 200; + // sprite.body.velocity.y = -300; + // sprite2.body.velocity.x = -200; + // sprite2.body.velocity.y = -200; + +} + + +function test1() { + + // Right Collision false + + sprite = game.add.sprite(200, 300, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.checkCollision.right = false; + // sprite.body.bounce.setTo(0.9, 0.9); + // sprite.body.bounce.setTo(1, 1); + // sprite.body.linearDamping = 0; + // sprite.scale.setTo(2, 2); + // sprite.body.mass = 2; + + sprite2 = game.add.sprite(500, 300, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + sprite2.body.bounce.setTo(0.9, 0.9); + // sprite2.body.mass = 1; + // sprite2.body.bounce.setTo(1, 1); + // sprite2.body.linearDamping = 0; + + game.input.onDown.add(launch1, this); + +} + +function launch1() { + + sprite2.body.velocity.x = -200; + +} + +function update() { + + if (reverse) + { + game.physics.collide(sprite2, sprite); + } + else + { + game.physics.collide(sprite, sprite2); + } + + if (sprite3) + { + game.physics.collide(sprite, sprite3); + } + +} + +function render() { + + if (sprite) + { + game.debug.renderBodyInfo(sprite, 16, 24); + } + + if (sprite) + { + game.debug.renderPhysicsBody(sprite.body); + } + + if (sprite2) + { + game.debug.renderPhysicsBody(sprite2.body); + } + + if (sprite3) + { + game.debug.renderPhysicsBody(sprite3.body); + } + +} diff --git a/examples/wip/pausetime.js b/examples/wip/pausetime.js new file mode 100644 index 00000000..117447a2 --- /dev/null +++ b/examples/wip/pausetime.js @@ -0,0 +1,29 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { create: create, render: render }); + +function create() { + + game.onPause.add(onGamePause, this); + game.onResume.add(onGameResume, this); + +} + +function onGamePause() { + + console.log('game paused at ' + this.time.now); + +} + +function onGameResume() { + + console.log('game un-paused at ' + this.time.now); + console.log('was paused for ' + game.time.pauseDuration); + +} + +function render() { + + game.debug.renderText('now: ' + game.time.now, 32, 32); + game.debug.renderText('paused: ' + game.paused, 32, 64); + +} diff --git a/examples/wip/physics-motion.js b/examples/wip/physics-motion.js new file mode 100644 index 00000000..d12d79b5 --- /dev/null +++ b/examples/wip/physics-motion.js @@ -0,0 +1,63 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('chunk', 'assets/sprites/chunk.png'); + game.load.image('arrow', 'assets/sprites/asteroids_ship.png'); + +} + +var sprite; +var bmd; + +function create() { + + game.stage.backgroundColor = '#124184'; + + bmd = game.add.bitmapData(800, 600); + bmd.fillStyle('#ffffff'); + var bg = game.add.sprite(0, 0, bmd); + bg.body.moves = false; + + game.physics.gravity.y = 100; + + sprite = game.add.sprite(32, 450, 'arrow'); + sprite.anchor.setTo(0.5, 0.5); + + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(0.8, 0.8); + + sprite.body.linearDamping = 0.1; + + game.input.onDown.add(launch, this); + +} + +function launch() { + + if (game.input.x < 400) + { + sprite.body.velocity.setTo(-200, -200); + } + else + { + sprite.body.velocity.setTo(200, -200); + } + +} + +function update() { + + sprite.rotation = sprite.body.angle; + + bmd.fillStyle('#ffff00'); + bmd.fillRect(sprite.x, sprite.y, 2, 2); + +} + +function render() { + + game.debug.renderBodyInfo(sprite, 16, 24); + +} diff --git a/examples/wip/pivot.js b/examples/wip/pivot.js index 3bc4b2ed..d0e27548 100644 --- a/examples/wip/pivot.js +++ b/examples/wip/pivot.js @@ -4,25 +4,22 @@ function preload() { game.load.image('atari', 'assets/sprites/atari130xe.png'); game.load.image('mushroom', 'assets/sprites/mushroom2.png'); + game.load.image('ball', 'assets/sprites/pangball.png'); } var sprite1; -var sprite2; +// var sprite2; function create() { game.stage.backgroundColor = '#2d2d2d'; - // This will check Sprite vs. Sprite collision + sprite1 = game.add.sprite(300, 300, 'ball'); - sprite1 = game.add.sprite(300, 300, 'atari'); - sprite1.name = 'atari'; - sprite1.body.immovable = true; - - sprite1.anchor.setTo(0.5, 0.5); - sprite1.pivot.x = 250; - sprite1.pivot.y = 300; + sprite1.anchor.setTo(0, 1); + sprite1.pivot.x = 100; + sprite1.pivot.y = 100; // sprite2 = game.add.sprite(0, 0, 'mushroom'); // sprite2.name = 'mushroom'; @@ -32,8 +29,8 @@ function create() { function update() { sprite1.angle += 1; - sprite1.pivot.x = game.input.x; - sprite1.pivot.y = game.input.y; + // sprite1.pivot.x = game.input.x; + // sprite1.pivot.y = game.input.y; } @@ -42,7 +39,7 @@ function render() { game.debug.renderPixel(sprite1.pivot.x, sprite1.pivot.y); // game.debug.renderSpriteInfo(sprite1, 100, 400); - game.debug.renderSpriteBounds(sprite1); + // game.debug.renderSpriteBounds(sprite1); // game.debug.renderSpriteInfo(sprite2, 100, 100); // game.debug.renderSpriteBounds(sprite2); } diff --git a/examples/wip/platform.js b/examples/wip/platform.js new file mode 100644 index 00000000..f58a672f --- /dev/null +++ b/examples/wip/platform.js @@ -0,0 +1,121 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.tilemap('map', 'assets/tilemaps/maps/platform.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('platformer_tiles', 'assets/tilemaps/tiles/platformer_tiles.png'); + game.load.spritesheet('gameboy', 'assets/sprites/gameboy_seize_color_40x60.png', 40, 60); + game.load.spritesheet('balls', 'assets/sprites/balls.png', 17, 17); + +} + +var map; +var layer; +var sprite; +var sprite2; +var balls; +var cursors; + +function create() { + + game.stage.backgroundColor = '#124184'; + + map = game.add.tilemap('map'); + + map.addTilesetImage('platformer_tiles'); + + map.setCollisionBetween(21, 53); + + layer = map.createLayer('Tile Layer 1'); + + layer.debug = true; + + // game.physics.gravity.y = 150; + +/* + balls = game.add.group(); + + for (var i = 0; i < 30; i++) + { + var s = balls.create(game.rnd.integerInRange(100, 700), game.rnd.integerInRange(100, 200), 'balls', game.rnd.integerInRange(0, 6)); + s.body.velocity.x = game.rnd.integerInRange(-400, 400); + s.body.velocity.y = game.rnd.integerInRange(-100, -200); + s.name = 'ball' + i; + } + + balls.setAll('body.collideWorldBounds', true); + balls.setAll('body.bounce.x', 0.8); + balls.setAll('body.bounce.y', 0.9); + balls.setAll('body.minBounceVelocity', 0.9); + balls.setAll('body.linearDamping', 0.5); +*/ + + sprite2 = game.add.sprite(340, 250, 'gameboy', 2); + sprite2.name = 'green'; + sprite2.body.collideWorldBounds = true; + // sprite2.body.bounce.setTo(0.5, 0.5); + + sprite = game.add.sprite(270, 100, 'gameboy', 0); + sprite.name = 'red'; + sprite.body.collideWorldBounds = true; + sprite.body.minBounceVelocity = 0.9; + sprite.body.bounce.setTo(0.5, 0.9); + sprite.body.linearDamping = 0.5; + + + game.input.onDown.add(launch, this); + +} + +function launch() { + + // sprite.body.velocity.x = -200; + // sprite.body.velocity.y = -200; + + sprite2.body.velocity.x = -200; + sprite2.body.velocity.y = -200; + +} + +function hit(face, body1, body2) { + + console.log('hit', face); + +} + +var flag = false; + +function update() { + + // game.physics.collide(balls, layer); + game.physics.collide(sprite, layer); + game.physics.collide(sprite2, layer); + game.physics.collide(sprite, sprite2); + +} + +function render() { + + game.debug.renderBodyInfo(sprite2, 32, 32); + game.debug.renderPhysicsBody(sprite2.body); + + + // game.debug.renderText(sprite2.body.left, 32, 30); + // game.debug.renderText(sprite2.body.right, 32, 50); + // game.debug.renderText(sprite2.body.top, 32, 70); + // game.debug.renderText(sprite2.body.bottom, 32, 90); + + + // for (var i = 0; i < balls._container.length; i++) + // { + + // } + + // if (sprite) + // { + // // game.debug.renderBodyInfo(sprite, 20, 30); + // game.debug.renderBodyInfo(sprite2, 20, 230); + // } + +} \ No newline at end of file diff --git a/examples/wip/pt.js b/examples/wip/pt.js new file mode 100644 index 00000000..007fa11f --- /dev/null +++ b/examples/wip/pt.js @@ -0,0 +1,913 @@ +/* + amiga protracker module player for web audio api + (c) 2012-2013 firehawk/tda (firehawk@haxor.fi) + + originally hacked together in a weekend, so please excuse + me for the spaghetti code. :) + + AMIGAAAAAAAAH!! + + kinda sorta changelog: + (apr 2013) + - changed the logic for pattern break/jump. mod.pattern_skank now + plays correctly. + (feb 2013) + - fixed NaN samples with mod.fractured and mod.multicolour (thanks Aegis!) + (jan 2013) + - fixed vibrato amplitude (was half of what it should be, apparently) + - fixed to work on safari again (thanks Matt Diamond @ stackoverflow.com) + (dec 2012) + - replaced effect switch-statement with jumptables + - fixed clicks (bad loops, empty samples) + - fixed playback bug with sample-only rows + - added amiga 500 lowpass filters (not 100% authentic, though) + - added compressor to output + - latest safari has broken web audio so chrome-only for now + (aug 2012) + - first version written from scratch + + todo: + - safari on ipad is broken again, it seems + - fix more playback bugs + * mod.black_queen (pattern loop has glitches) + - properly test EEx delay pattern + - implement the rest of the effects + - optimize for more speed!! SPEEEED!! + * switch to fixed point sample pointers, Math.floor() is _slow_ on iOS +*/ + +// constructor for protracker player object +function Protracker() +{ + var i, t; + + this.initialize(); + this.clearsong(); + + this.url=""; + this.loading=false; + this.ready=false; + this.playing=false; + this.buffer=0; + this.mixerNode=0; + this.paused=false; + this.repeat=false; + this.separation=true; + + this.palclock=true; + + this.autostart=false; + + this.onReady=function(){}; + this.onPlay=function(){}; + this.onStop=function(){}; + + // paula period values + this.baseperiodtable=new Array( + 856,808,762,720,678,640,604,570,538,508,480,453, + 428,404,381,360,339,320,302,285,269,254,240,226, + 214,202,190,180,170,160,151,143,135,127,120,113); + + // finetune multipliers + this.finetunetable=new Array(); + for(t=0;t<16;t++) this.finetunetable[t]=Math.pow(2, (t-8)/12/8); + + // calc tables for vibrato waveforms + this.vibratotable=new Array(); + for(t=0;t<4;t++) { + this.vibratotable[t]=new Array(); + for(i=0;i<64;i++) { + switch(t) { + case 0: + this.vibratotable[t][i]=127*Math.sin(Math.PI*2*(i/64)); + break; + case 1: + this.vibratotable[t][i]=127-4*i; + break; + case 2: + this.vibratotable[t][i]=(i<32)?127:-127; + break; + case 3: + this.vibratotable[t][i]=(1-2*Math.random())*127; + break; + } + } + } + + // effect jumptables + this.effects_t0 = new Array( + this.effect_t0_0, this.effect_t0_1, this.effect_t0_2, this.effect_t0_3, this.effect_t0_4, this.effect_t0_5, this.effect_t0_6, this.effect_t0_7, + this.effect_t0_8, this.effect_t0_9, this.effect_t0_a, this.effect_t0_b, this.effect_t0_c, this.effect_t0_d, this.effect_t0_e, this.effect_t0_f); + this.effects_t0_e = new Array( + this.effect_t0_e0, this.effect_t0_e1, this.effect_t0_e2, this.effect_t0_e3, this.effect_t0_e4, this.effect_t0_e5, this.effect_t0_e6, this.effect_t0_e7, + this.effect_t0_e8, this.effect_t0_e9, this.effect_t0_ea, this.effect_t0_eb, this.effect_t0_ec, this.effect_t0_ed, this.effect_t0_ee, this.effect_t0_ef); + this.effects_t1 = new Array( + this.effect_t1_0, this.effect_t1_1, this.effect_t1_2, this.effect_t1_3, this.effect_t1_4, this.effect_t1_5, this.effect_t1_6, this.effect_t1_7, + this.effect_t1_8, this.effect_t1_9, this.effect_t1_a, this.effect_t1_b, this.effect_t1_c, this.effect_t1_d, this.effect_t1_e, this.effect_t1_f); + this.effects_t1_e = new Array( + this.effect_t1_e0, this.effect_t1_e1, this.effect_t1_e2, this.effect_t1_e3, this.effect_t1_e4, this.effect_t1_e5, this.effect_t1_e6, this.effect_t1_e7, + this.effect_t1_e8, this.effect_t1_e9, this.effect_t1_ea, this.effect_t1_eb, this.effect_t1_ec, this.effect_t1_ed, this.effect_t1_ee, this.effect_t1_ef); + + this.context = null; + this.samplerate=44100; + this.bufferlen=2048; +} + + + +// create the web audio context +Protracker.prototype.createContext = function() +{ + this.context = new webkitAudioContext(); + this.samplerate=this.context.sampleRate; + this.bufferlen=(this.samplerate > 44100) ? 4096 : 2048; + + // fixed filter at 6kHz + this.filterNode=this.context.createBiquadFilter(); + this.filterNode.frequency.value=6000 + + // "LED filter" at 3.5kHz - off by default + this.lowpassNode=this.context.createBiquadFilter(); + this.lowpassNode.frequency.value=28867; + + // mixer + this.mixerNode=this.context.createJavaScriptNode(this.bufferlen, 1, 2); + this.mixerNode.module=this; + this.mixerNode.onaudioprocess=Protracker.prototype.mix; + + // compressor for a bit of volume boost + this.compressorNode=this.context.createDynamicsCompressor(); + + // patch up some cables :) + this.mixerNode.connect(this.filterNode); + this.filterNode.connect(this.lowpassNode); + this.lowpassNode.connect(this.compressorNode); + this.compressorNode.connect(this.context.destination); +} + + + +// play loaded and parsed module with webaudio context +Protracker.prototype.play = function() +{ + if (this.context==null) this.createContext(); + + if (!this.ready) return false; + if (this.paused) { + this.paused=false; + return true; + } + this.paused=false; + this.initialize(); + this.flags=1+2; + this.playing=true; + this.onPlay(); + return true; +} + + + +// pause playback +Protracker.prototype.pause = function() +{ + if (!this.paused) { + this.paused=true; + } else { + this.paused=false; + } +} + + + +// stop playback and release webaudio node +Protracker.prototype.stop = function() +{ + this.playing=false; + this.onStop(); +} + + + +// jump positions forward/back +Protracker.prototype.jump = function(step) +{ + this.tick=0; + this.row=0; + this.position+=step; + this.flags=1+2; + if (this.position<0) this.position=0; + if (this.position >= this.songlen) this.stop(); +} + + + +// set whether module repeats after songlen +Protracker.prototype.setrepeat = function(rep) +{ + this.repeat=rep; +} + + + +// set stereo separation mode (false=paula, true=betterpaula) +Protracker.prototype.setseparation = function(sep) +{ + this.separation=sep; +} + + + +// set amiga video standard (false=NTSC, true=PAL) +Protracker.prototype.setamigatype = function(clock) +{ + this.palclock=clock; +} + + + +// set autostart to play immediately after loading +Protracker.prototype.setautostart = function(st) +{ + this.autostart=st; +} + + + +// clear song data +Protracker.prototype.clearsong = function() +{ + this.title=""; + this.signature=""; + this.songlen=1; + this.repeatpos=0; + this.patterntable=new ArrayBuffer(128); + for(i=0;i<128;i++) this.patterntable[i]=0; + + this.channels=4; + + this.sample=new Array(); + this.samples=31; + for(i=0;i<31;i++) { + this.sample[i]=new Object(); + this.sample[i].name=""; + this.sample[i].length=0; + this.sample[i].finetune=0; + this.sample[i].volume=64; + this.sample[i].loopstart=0; + this.sample[i].looplength=0; + this.sample[i].data=0; + } + + this.patterns=0; + this.pattern=new Array(); + this.note=new Array(); + + this.looprow=0; + this.loopstart=0; + this.loopcount=0; + + this.patterndelay=0; + this.patternwait=0; +} + + +// initialize all player variables +Protracker.prototype.initialize = function() +{ + this.tick=0; + this.position=0; + this.row=0; + this.offset=0; + this.flags=0; + + this.speed=6; + this.bpm=125; + this.breakrow=0; + this.patternjump=0; + this.patterndelay=0; + this.patternwait=0; + + this.channel=new Array(); + for(i=0;i0x1f) && (this.buffer[st+j]<0x7f)) ? + (String.fromCharCode(this.buffer[st+j])) : + (" "); + j++; + } + this.sample[i].length=2*(this.buffer[st+22]*256 + this.buffer[st+23]); + this.sample[i].finetune=this.buffer[st+24]; + if (this.sample[i].finetune > 7) this.sample[i].finetune=this.sample[i].finetune-16; + this.sample[i].volume=this.buffer[st+25]; + this.sample[i].loopstart=2*(this.buffer[st+26]*256 + this.buffer[st+27]); + this.sample[i].looplength=2*(this.buffer[st+28]*256 + this.buffer[st+29]); + if (this.sample[i].looplength==2) this.sample[i].looplength=0; + if (this.sample[i].loopstart>this.sample[i].length) { + this.sample[i].loopstart=0; + this.sample[i].looplength=0; + } + } + + this.songlen=this.buffer[950]; + if (this.buffer[951] != 127) this.repeatpos=this.buffer[951]; + for(i=0;i<128;i++) { + this.patterntable[i]=this.buffer[952+i]; + if (this.patterntable[i] > this.patterns) this.patterns=this.patterntable[i]; + } + this.patterns+=1; + var patlen=4*64*this.channels; + + this.pattern=new Array(); + this.note=new Array(); + for(i=0;ispd) { mod.tick++; mod.offset=0; mod.flags|=1; } + if (mod.tick>=mod.speed) { + + if (mod.patterndelay) { // delay pattern + if (mod.tick < ((mod.patternwait+1)*mod.speed)) { + mod.patternwait++; + } else { + mod.row++; mod.tick=0; mod.flags|=2; mod.patterndelay=0; + + } + } + else { + + if (mod.flags&(16+32+64)) { + if (mod.flags&64) { // loop pattern? + mod.row=mod.looprow; + mod.flags&=0xa1; + mod.flags|=2; + } + else { + if (mod.flags&16) { // pattern jump/break? + //console.log("break to pattern " + mod.patternjump + " row "+mod.breakrow); + mod.position=mod.patternjump; + mod.row=mod.breakrow; + mod.patternjump=0; + mod.breakrow=0; + mod.flags&=0xe1; + mod.flags|=2; + } + } + mod.tick=0; + } else { + mod.row++; mod.tick=0; mod.flags|=2; + } + } + } + + if (mod.row>=64) { mod.position++; mod.row=0; mod.flags|=4; } + if (mod.position>=mod.songlen) { + if (mod.repeat) { + mod.position=0; + } else { + mod.stop(); + } + return; + } +} + + + +// mix an audio buffer with data +Protracker.prototype.mix = function(ape) { + var f; + var p, pp, n, nn; + var mod=ape.srcElement.module; + outp=new Array(); + + var bufs=new Array(ape.outputBuffer.getChannelData(0), ape.outputBuffer.getChannelData(1)); + var buflen=ape.outputBuffer.length; + for(var s=0;s3) mod.channel[ch].vibratopos=0; + mod.channel[ch].flags|=3; // recalc speed + mod.channel[ch].noteon=1; + } else { + mod.channel[ch].slideto=n; + + } + } + nn=mod.pattern[p][pp+0]&0xf0 | mod.pattern[p][pp+2]>>4; + if (nn) { + mod.channel[ch].sample=nn-1; + + mod.channel[ch].volume=mod.sample[nn-1].volume; + if (!n && (mod.channel[ch].samplepos > mod.sample[nn-1].length)) mod.channel[ch].samplepos=0; + } + } + } + mod.channel[ch].voiceperiod=mod.channel[ch].period; + if (mod.channel[ch].samplepos==0) modsample[ch]=mod.channel[ch].sample; + + + // kill empty samples + if (!mod.sample[mod.channel[ch].sample].length) mod.channel[ch].noteon=0; + + // effects + if (mod.flags&1) { + if (!mod.tick) { + // process only on tick 0 + mod.effects_t0[mod.channel[ch].command](mod, ch); + } else { + mod.effects_t1[mod.channel[ch].command](mod, ch); + } + } + + // recalc note number from period + if (mod.channel[ch].flags&2) { + for(var np=0; np=mod.channel[ch].period) mod.channel[ch].note=np; + mod.channel[ch].semitone=7; + if (mod.channel[ch].period>=120) + mod.channel[ch].semitone=mod.baseperiodtable[mod.channel[ch].note]-mod.baseperiodtable[mod.channel[ch].note+1]; + } + + // recalc sample speed and apply finetune + if ((mod.channel[ch].flags&1 || mod.flags&2) && mod.channel[ch].voiceperiod) + mod.channel[ch].samplespeed= + (mod.palclock ? 7093789.2 : 7159090.5)/(mod.channel[ch].voiceperiod*2) * mod.finetunetable[mod.sample[mod.channel[ch].sample].finetune+8] / mod.samplerate; + + // advance vibrato on each new tick + if (mod.flags&1) { + mod.channel[ch].vibratopos+=mod.channel[ch].vibratospeed; + mod.channel[ch].vibratopos&=0x3f; + } + + // mix channel to output + och=och^(ch&1); + f=0.0; + if (mod.channel[ch].noteon) { + if (mod.sample[mod.channel[ch].sample].length > mod.channel[ch].samplepos) + f=(1.0/mod.channels) * + (mod.sample[mod.channel[ch].sample].data[Math.floor(mod.channel[ch].samplepos)]*mod.channel[ch].volume)/64.0; + outp[och]+=f; + mod.channel[ch].samplepos+=mod.channel[ch].samplespeed; + } + if (s==0) mod.vu[ch]=Math.abs(f); + + // loop or end samples + if (mod.channel[ch].noteon) { + if (mod.sample[mod.channel[ch].sample].loopstart || mod.sample[mod.channel[ch].sample].looplength) { + if (mod.channel[ch].samplepos >= (mod.sample[mod.channel[ch].sample].loopstart+mod.sample[mod.channel[ch].sample].looplength)) { + mod.channel[ch].samplepos=mod.sample[mod.channel[ch].sample].loopstart; + } + } else { + if (mod.channel[ch].samplepos >= mod.sample[mod.channel[ch].sample].length) { + mod.channel[ch].noteon=0; + } + } + } + + // clear channel flags + mod.channel[ch].flags=0; + } + mod.offset++; + mod.flags&=0x70; + } + + // a more headphone-friendly stereo separation (aka. betterpaula) + if (mod.separation) { + t=outp[0]; + outp[0]=outp[0]*0.6 + outp[1]*0.4; + outp[1]=outp[1]*0.6 + t*0.4; + } + bufs[0][s]=outp[0]; + bufs[1][s]=outp[1]; + } +} + + + +// +// tick 0 effect functions +// +Protracker.prototype.effect_t0_0=function(mod, ch) { // 0 arpeggio + mod.channel[ch].arpeggio=mod.channel[ch].data; +} +Protracker.prototype.effect_t0_1=function(mod, ch) { // 1 slide up + if (mod.channel[ch].data) mod.channel[ch].slidespeed=mod.channel[ch].data; +} +Protracker.prototype.effect_t0_2=function(mod, ch) { // 2 slide down + if (mod.channel[ch].data) mod.channel[ch].slidespeed=mod.channel[ch].data; +} +Protracker.prototype.effect_t0_3=function(mod, ch) { // 3 slide to note + if (mod.channel[ch].data) mod.channel[ch].slidetospeed=mod.channel[ch].data; +} +Protracker.prototype.effect_t0_4=function(mod, ch) { // 4 vibrato + if (mod.channel[ch].data&0x0f && mod.channel[ch].data&0xf0) { + mod.channel[ch].vibratodepth=(mod.channel[ch].data&0x0f); + mod.channel[ch].vibratospeed=(mod.channel[ch].data&0xf0)>>4; + } + mod.channel[ch].voiceperiod+= + (mod.channel[ch].vibratodepth/32)*mod.channel[ch].semitone*(mod.vibratotable[mod.channel[ch].vibratowave&3][mod.channel[ch].vibratopos]/127); + mod.channel[ch].flags|=1; +} +Protracker.prototype.effect_t0_5=function(mod, ch) { // 5 +} +Protracker.prototype.effect_t0_6=function(mod, ch) { // 6 +} +Protracker.prototype.effect_t0_7=function(mod, ch) { // 7 +} +Protracker.prototype.effect_t0_8=function(mod, ch) { // 8 +} +Protracker.prototype.effect_t0_9=function(mod, ch) { // 9 set sample offset + mod.channel[ch].samplepos=mod.channel[ch].data*256; +} +Protracker.prototype.effect_t0_a=function(mod, ch) { // a +} +Protracker.prototype.effect_t0_b=function(mod, ch) { // b pattern jump + mod.breakrow=0; + mod.patternjump=mod.channel[ch].data; + mod.flags|=16; +} +Protracker.prototype.effect_t0_c=function(mod, ch) { // c set volume + mod.channel[ch].volume=mod.channel[ch].data; +} +Protracker.prototype.effect_t0_d=function(mod, ch) { // d pattern break + mod.breakrow=((mod.channel[ch].data&0xf0)>>4)*10 + (mod.channel[ch].data&0x0f); + if (!(mod.flags&16)) mod.patternjump=mod.position+1; + mod.flags|=16; +} +Protracker.prototype.effect_t0_e=function(mod, ch) { // e + var i=(mod.channel[ch].data&0xf0)>>4; + mod.effects_t0_e[i](mod, ch); +} +Protracker.prototype.effect_t0_f=function(mod, ch) { // f set speed + if (mod.channel[ch].data > 32) { + mod.bpm=mod.channel[ch].data; + } else { + if (mod.channel[ch].data) mod.speed=mod.channel[ch].data; + } +} + + + +// +// tick 0 effect e functions +// +Protracker.prototype.effect_t0_e0=function(mod, ch) { // e0 filter on/off + if (mod.channel[ch].data&0x0f) { + mod.lowpassNode.frequency.value=4280; //3500; + } else { + mod.lowpassNode.frequency.value=28867; + } +} +Protracker.prototype.effect_t0_e1=function(mod, ch) { // e1 fine slide up + mod.channel[ch].period-=mod.channel[ch].data&0x0f; + if (mod.channel[ch].period < 113) mod.channel[ch].period=113; +} +Protracker.prototype.effect_t0_e2=function(mod, ch) { // e2 fine slide down + mod.channel[ch].period+=mod.channel[ch].data&0x0f; + if (mod.channel[ch].period > 856) mod.channel[ch].period=856; + mod.channel[ch].flags|=1; +} +Protracker.prototype.effect_t0_e3=function(mod, ch) { // e3 set glissando +} +Protracker.prototype.effect_t0_e4=function(mod, ch) { // e4 set vibrato waveform + mod.channel[ch].vibratowave=mod.channel[ch].data&0x07; +} +Protracker.prototype.effect_t0_e5=function(mod, ch) { // e5 set finetune +} +Protracker.prototype.effect_t0_e6=function(mod, ch) { // e6 loop pattern + if (mod.channel[ch].data&0x0f) { + if (mod.loopcount) { + mod.loopcount--; + } else { + mod.loopcount=mod.channel[ch].data&0x0f; + } + if (mod.loopcount) mod.flags|=64; + } else { + mod.looprow=mod.row; + } +} +Protracker.prototype.effect_t0_e7=function(mod, ch) { // e7 +} +Protracker.prototype.effect_t0_e8=function(mod, ch) { // e8 +} +Protracker.prototype.effect_t0_e9=function(mod, ch) { // e9 +} +Protracker.prototype.effect_t0_ea=function(mod, ch) { // ea fine volslide up + mod.channel[ch].volume+=mod.channel[ch].data&0x0f; + if (mod.channel[ch].volume > 64) mod.channel[ch].volume=64; +} +Protracker.prototype.effect_t0_eb=function(mod, ch) { // eb fine volslide down + mod.channel[ch].volume-=mod.channel[ch].data&0x0f; + if (mod.channel[ch].volume < 0) mod.channel[ch].volume=0; +} +Protracker.prototype.effect_t0_ec=function(mod, ch) { // ec +} +Protracker.prototype.effect_t0_ed=function(mod, ch) { // ed delay sample + if (mod.tick==(mod.channel[ch].data&0x0f)) { + // start note + var p=mod.patterntable[mod.position]; + var pp=mod.row*4*mod.channels + ch*4; + n=(mod.pattern[p][pp]&0x0f)<<8 | mod.pattern[p][pp+1]; + if (n) { + mod.channel[ch].period=n; + mod.channel[ch].voiceperiod=mod.channel[ch].period; + mod.channel[ch].samplepos=0; + if (mod.channel[ch].vibratowave>3) mod.channel[ch].vibratopos=0; + mod.channel[ch].flags|=3; // recalc speed + mod.channel[ch].noteon=1; + } + n=mod.pattern[p][pp+0]&0xf0 | mod.pattern[p][pp+2]>>4; + if (n) { + mod.channel[ch].sample=n-1; + mod.channel[ch].volume=mod.sample[n-1].volume; + } + } +} +Protracker.prototype.effect_t0_ee=function(mod, ch) { // ee delay pattern + mod.patterndelay=mod.channel[ch].data&0x0f; + mod.patternwait=0; +} +Protracker.prototype.effect_t0_ef=function(mod, ch) { // ef +} + + + +// +// tick 1+ effect functions +// +Protracker.prototype.effect_t1_0=function(mod, ch) { // 0 arpeggio + if (mod.channel[ch].data) { + var apn=mod.channel[ch].note; + if ((mod.tick%3)==1) apn+=mod.channel[ch].arpeggio>>4; + if ((mod.tick%3)==2) apn+=mod.channel[ch].arpeggio&0x0f; + if (apn>=0 && apn <= mod.baseperiodtable.length) + mod.channel[ch].voiceperiod = mod.baseperiodtable[apn]; + mod.channel[ch].flags|=1; + } +} +Protracker.prototype.effect_t1_1=function(mod, ch) { // 1 slide up + mod.channel[ch].period-=mod.channel[ch].slidespeed; + if (mod.channel[ch].period<113) mod.channel[ch].period=113; + mod.channel[ch].flags|=3; // recalc speed +} +Protracker.prototype.effect_t1_2=function(mod, ch) { // 2 slide down + mod.channel[ch].period+=mod.channel[ch].slidespeed; + if (mod.channel[ch].period>856) mod.channel[ch].period=856; + mod.channel[ch].flags|=3; // recalc speed +} +Protracker.prototype.effect_t1_3=function(mod, ch) { // 3 slide to note + if (mod.channel[ch].period < mod.channel[ch].slideto) { + mod.channel[ch].period+=mod.channel[ch].slidetospeed; + if (mod.channel[ch].period > mod.channel[ch].slideto) + mod.channel[ch].period=mod.channel[ch].slideto; + } + if (mod.channel[ch].period > mod.channel[ch].slideto) { + mod.channel[ch].period-=mod.channel[ch].slidetospeed; + if (mod.channel[ch].period>4); + if (mod.channel[ch].volume>64) mod.channel[ch].volume=64; + } + if (!(mod.channel[ch].data&0xf0)) { + // x is zero, slide down + mod.channel[ch].volume-=(mod.channel[ch].data&0x0f); + if (mod.channel[ch].volume<0) mod.channel[ch].volume=0; + } +} +Protracker.prototype.effect_t1_b=function(mod, ch) { // b pattern jump +} +Protracker.prototype.effect_t1_c=function(mod, ch) { // c set volume +} +Protracker.prototype.effect_t1_d=function(mod, ch) { // d pattern break +} +Protracker.prototype.effect_t1_e=function(mod, ch) { // e + var i=(mod.channel[ch].data&0xf0)>>4; + mod.effects_t1_e[i](mod, ch); +} +Protracker.prototype.effect_t1_f=function(mod, ch) { // f +} + + + +// +// tick 1+ effect e functions +// +Protracker.prototype.effect_t1_e0=function(mod, ch) { // e0 +} +Protracker.prototype.effect_t1_e1=function(mod, ch) { // e1 +} +Protracker.prototype.effect_t1_e2=function(mod, ch) { // e2 +} +Protracker.prototype.effect_t1_e3=function(mod, ch) { // e3 +} +Protracker.prototype.effect_t1_e4=function(mod, ch) { // e4 +} +Protracker.prototype.effect_t1_e5=function(mod, ch) { // e5 +} +Protracker.prototype.effect_t1_e6=function(mod, ch) { // e6 +} +Protracker.prototype.effect_t1_e7=function(mod, ch) { // e7 +} +Protracker.prototype.effect_t1_e8=function(mod, ch) { // e8 +} +Protracker.prototype.effect_t1_e9=function(mod, ch) { // e9 retrig sample + if (mod.tick%(mod.channel[ch].data&0x0f)==0) + mod.channel[ch].samplepos=0; +} +Protracker.prototype.effect_t1_ea=function(mod, ch) { // ea +} +Protracker.prototype.effect_t1_eb=function(mod, ch) { // eb +} +Protracker.prototype.effect_t1_ec=function(mod, ch) { // ec cut sample + if (mod.tick==(mod.channel[ch].data&0x0f)) + mod.channel[ch].volume=0; +} +Protracker.prototype.effect_t1_ed=function(mod, ch) { // ed delay sample + mod.effect_t0_ed(mod, ch); +} +Protracker.prototype.effect_t1_ee=function(mod, ch) { // ee +} +Protracker.prototype.effect_t1_ef=function(mod, ch) { // ef +} diff --git a/examples/wip/rabbit map.js b/examples/wip/rabbit map.js new file mode 100644 index 00000000..0c73507e --- /dev/null +++ b/examples/wip/rabbit map.js @@ -0,0 +1,251 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.tilemap('map', 'assets/tilemaps/maps/features_test.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png'); + game.load.image('walls_1x2', 'assets/tilemaps/tiles/walls_1x2.png'); + game.load.image('tiles2', 'assets/tilemaps/tiles/tiles2.png'); + + game.load.image('ball', 'assets/sprites/shinyball.png'); + game.load.image('phaser', 'assets/sprites/firstaid.png'); + // game.load.image('phaser', 'assets/sprites/atari130xe.png'); + // game.load.image('phaser', 'assets/sprites/mushroom2.png'); + +} + +var cursors; +var map; +var coins; + +var layer; +var layer2; +var layer3; + +var sprite; +var ball; +var marker; + +function create() { + +console.log(' --- state create start ---'); + + $('#step').click(function(){ + game.step(); + }); + + game.stage.backgroundColor = '#124184'; + + + marker = new Phaser.Line(256, 0, 256, 600); + + map = game.add.tilemap('map'); + + map.addTilesetImage('ground_1x1'); + map.addTilesetImage('walls_1x2'); + map.addTilesetImage('tiles2'); + + map.setCollisionBetween(1, 12); + + layer = map.createLayer('Tile Layer 1'); + + // layer.debug = true; + + layer.resizeWorld(); + + game.physics.gravity.y = 200; + + + sprite = game.add.sprite(100, 240, 'phaser'); + // sprite.anchor.setTo(0.5, 0.5); + // sprite.body.setCircle(20); + + // sprite.body.moves = false; + + ball = game.add.sprite(200, 180, 'ball'); + + // game.add.tween(sprite).to({x: 500},5000,Phaser.Easing.Linear.None,true); + + // game.add.tween(sprite).to({angle: 360},5000,Phaser.Easing.Linear.None,true); + + // sprite = game.add.sprite(200, 240, 'phaser'); // 3-block corner test + + // sprite.debug = true; + // game.stepping = true; + + // sprite.body.velocity.y = -300; + + // sprite.body.velocity.y = 200; + + + + + + + // We'll set a lower max angular velocity here to keep it from going totally nuts + // sprite.body.maxAngular = 500; + + // Apply a drag otherwise the sprite will just spin and never slow down + // sprite.body.angularDrag = 50; + + // sprite.body.bounce.x = 0.8; + sprite.body.bounce.y = 0.8; + + // sprite.angle = 35; + + game.camera.follow(sprite); + + // game.input.onDown.add(getIt, this); + + cursors = game.input.keyboard.createCursorKeys(); + +} + +function update() { + +// console.log(' --- state update start ---'); + +/* + if (cursors.left.isDown) + { + game.camera.x -= 1; + } + else if (cursors.right.isDown) + { + game.camera.x += 1; + } + + if (cursors.up.isDown) + { + layer.scrollY -= 4; + } + else if (cursors.down.isDown) + { + layer.scrollY += 4; + } +*/ + + game.physics.collide(sprite, layer); + game.physics.collide(sprite, ball); + + // sprite.body.velocity.y = -300; + + // sprite.body.angularVelocity = -100; + // sprite.body.angularAcceleration = 200; + + + // sprite.body.velocity.x = 0; + // sprite.body.velocity.y = 0; + sprite.body.angularVelocity = 0; + + // sprite.body.acceleration.x = 0; + // sprite.body.angularAcceleration = 0; + + if (cursors.left.isDown) + { + // sprite.body.acceleration.x = -200; + sprite.body.angularVelocity = -300; + // sprite.body.angularAcceleration -= 200; + } + else if (cursors.right.isDown) + { + // sprite.body.acceleration.x = 200; + sprite.body.angularVelocity = 300; + // sprite.body.angularAcceleration += 200; + } + + if (cursors.up.isDown) + { + game.physics.velocityFromAngle(sprite.angle, 300, sprite.body.velocity); + } + + + + + /* + sprite.body.velocity.x = 0; + sprite.body.velocity.y = 0; + + sprite.angle = sprite.angle + 1; + */ + + // if (cursors.up.isDown) + // { + // sprite.body.velocity.y = -200; + // } + // else if (cursors.down.isDown) + // { + // sprite.body.velocity.y = 100; + // } + + // if (cursors.left.isDown) + // { + // sprite.body.velocity.x = -200; + // } + // else if (cursors.right.isDown) + // { + // sprite.body.velocity.x = 200; + // } + + // if (cursors.up.isDown) + // { + // sprite.y -= 2; + // } + // else if (cursors.down.isDown) + // { + // sprite.y += 2; + // } + + // if (cursors.left.isDown) + // { + // sprite.x -= 2; + // } + // else if (cursors.right.isDown) + // { + // sprite.x += 2; + // } + + // if (cursors.up.isDown) + // { + // sprite.body.y -= 2; + // } + // else if (cursors.down.isDown) + // { + // sprite.body.y += 2; + // } + + // if (cursors.left.isDown) + // { + // sprite.body.x -= 2; + // } + // else if (cursors.right.isDown) + // { + // sprite.body.x += 2; + // } + + + +} + +function render() { + + // game.debug.renderSpriteBody(sprite); + // game.debug.renderSpriteBounds(sprite); + + game.debug.renderPhysicsBody(sprite.body); + game.debug.renderBodyInfo(sprite, 32, 32); + + // game.debug.renderLine(marker, 'rgba(255,255,255,0.5)'); + + // game.debug.renderText(sprite.deltaX, 32, 32); + // game.debug.renderText(sprite.deltaY, 32, 48); + // game.debug.renderText(sprite.body.deltaX(), 232, 32); + // game.debug.renderText(sprite.body.deltaY(), 232, 48); + + // game.debug.renderText(sprite.body.left, 32, 32); + // game.debug.renderText(sprite.body.top, 32, 48); + + // game.debug.renderSpriteCoords(sprite, 32, 320); + +} \ No newline at end of file diff --git a/examples/wip/rect test.js b/examples/wip/rect test.js new file mode 100644 index 00000000..23888889 --- /dev/null +++ b/examples/wip/rect test.js @@ -0,0 +1,83 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + +} + +var body; +var tile; + +function create() { + + body = { left: 386, top: 89, right: 412, bottom: 127 }; + tile = { x: 416, y: 96, right: 448, bottom: 128 }; + + game.input.keyboard.addKeyCapture([Phaser.Keyboard.LEFT, Phaser.Keyboard.RIGHT, Phaser.Keyboard.UP, Phaser.Keyboard.DOWN]); + +} + +function tileIntersects (body, tile) { + + if (body.width <= 0 || body.height <= 0 || tile.width <= 0 || tile.height <= 0) + { + // return false; + } + + var test1 = body.right < tile.x; + var test2 = body.bottom < tile.y; + var test3 = body.left > tile.right; + var test4 = body.top > tile.bottom; + + result = !(body.right < tile.x || body.bottom < tile.y || body.left > tile.right || body.top > tile.bottom); + + // game.debug.renderText('intersects: ' + result, 32, 32); + // game.debug.renderText('test 1: ' + test1, 320, 60); + // game.debug.renderText('test 2: ' + test2, 320, 80); + // game.debug.renderText('test 3: ' + test3, 320, 100); + // game.debug.renderText('test 4: ' + test4, 320, 120); + + return result; + +} + +function update() { + + if (game.input.keyboard.isDown(Phaser.Keyboard.LEFT)) + { + body.left -= 1; + body.right -= 1; + } + + if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)) + { + body.left += 1; + body.right += 1; + } + + if (game.input.keyboard.isDown(Phaser.Keyboard.UP)) + { + body.top -= 1; + body.bottom -= 1; + } + + if (game.input.keyboard.isDown(Phaser.Keyboard.DOWN)) + { + body.top += 1; + body.bottom += 1; + } + +} + +function render() { + + var r = tileIntersects(body, tile); + + game.context.fillStyle = 'rgb(255,0,0)'; + game.context.fillRect(body.left, body.top, body.right-body.left,body.bottom-body.top); + + game.context.fillStyle = 'rgb(0,255,0)'; + game.context.fillRect(tile.x, tile.y, tile.right-tile.x,tile.bottom-tile.y); + +} diff --git a/examples/wip/removeFilter.js b/examples/wip/removeFilter.js new file mode 100644 index 00000000..cf67aba4 --- /dev/null +++ b/examples/wip/removeFilter.js @@ -0,0 +1,51 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); + +var logo; +var background; +var filter; + +function preload() { + + game.load.image('phaser', 'assets/sprites/phaser2.png'); + game.load.script('fire', '../filters/Fire.js'); + +} + +function create() { + + + logo = game.add.sprite(game.world.centerX, game.world.centerY, 'phaser'); + logo.anchor.setTo(0.5, 0.5); + + background = game.add.sprite(0, 0); + background.width = 800; + background.height = 600; + + filter = game.add.filter('Fire', 800, 600); + filter.alpha = 0.0; + + background.filters = [filter]; + + + game.input.onDown.add(removeBackground, this); + +} + +function update() { + + filter.update(); + +} + +function removeBackground() { + + console.log('removeBackground'); + + + // background.filters = null; + background.destroy(); + + // console.log(background.filters); + +} diff --git a/examples/wip/rendertexture1.js b/examples/wip/rendertexture1.js index 7ddf2305..02f14549 100644 --- a/examples/wip/rendertexture1.js +++ b/examples/wip/rendertexture1.js @@ -1,38 +1,87 @@ -var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); +var config = { + + width: "100%", + height: "100%", + renderer: Phaser.WEBGL, + parent: 'phaser-example', + state: { preload: preload, create: create, update: update }, + backgroundColor: '#ff0000' + +}; + +var game = new Phaser.Game(config); function preload() { - game.load.spritesheet('veggies', 'assets/sprites/fruitnveg32wh37.png', 32, 32); + game.load.image('spin1', 'assets/sprites/spinObj_01.png'); + game.load.image('spin2', 'assets/sprites/spinObj_02.png'); + game.load.image('spin3', 'assets/sprites/spinObj_03.png'); + game.load.image('spin4', 'assets/sprites/spinObj_04.png'); + game.load.image('spin5', 'assets/sprites/spinObj_05.png'); + game.load.image('spin6', 'assets/sprites/spinObj_06.png'); + game.load.image('spin7', 'assets/sprites/spinObj_07.png'); + game.load.image('spin8', 'assets/sprites/spinObj_08.png'); } -var group; -var texture; +var renderTexture; +var renderTexture2; +var currentTexture; +var outputSprite; +var stuffContainer; +var count = 0; function create() { - group = game.add.group(); - group.create(0, 0, 'veggies', 0); - group.create(32, 0, 'veggies', 1); - group.create(0, 32, 'veggies', 2); - group.create(32, 32, 'veggies', 3); - group.visible = false; + // create two render textures.. these dynamic textures will be used to draw the scene into itself + renderTexture = game.add.renderTexture('texture1', game.width, game.height); + renderTexture2 = game.add.renderTexture('textur2e', game.width, game.height); + currentTexture = renderTexture; - texture = game.add.renderTexture('texture', 800, 600); - - game.add.sprite(0, 0, texture); + // create a new sprite that uses the render texture we created above + outputSprite = game.add.sprite(game.width/2, game.height/2, currentTexture); + + // align the sprite + outputSprite.anchor.x = 0.5; + outputSprite.anchor.y = 0.5; + + stuffContainer = game.add.group(); + stuffContainer.x = game.width/2; + stuffContainer.y = game.height/2; + + // now create some items and randomly position them in the stuff container + for (var i = 0; i < 20; i++) + { + var item = stuffContainer.create(Math.random() * 400 - 200, Math.random() * 400 - 200, game.rnd.pick(game.cache.getImageKeys())); + item.anchor.setTo(0.5, 0.5); + } + + // used for spinning! + count = 0; } function update() { - var clear = false; + stuffContainer.addAll('rotation', 0.1); - for (var i = 0; i < 60; i++) - { - clear = (i == 0); - texture.renderXY(group, game.world.randomX, game.world.randomY, clear); - } + count += 0.01; + + // swap the buffers.. + var temp = renderTexture; + renderTexture = renderTexture2; + renderTexture2 = temp; + + // set the new texture + outputSprite.setTexture(renderTexture); + + // twist this up! + stuffContainer.rotation -= 0.01 + outputSprite.scale.x = outputSprite.scale.y = 1 + Math.sin(count) * 0.2; + + // render the stage to the texture + // the true clears the texture before content is rendered + renderTexture2.renderXY(game.stage.display, 0, 0, true); } diff --git a/examples/wip/sat1.js b/examples/wip/sat1.js new file mode 100644 index 00000000..803079d7 --- /dev/null +++ b/examples/wip/sat1.js @@ -0,0 +1,184 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.spritesheet('gameboy', 'assets/sprites/gameboy_seize_color_40x60.png', 40, 60); + +} + +var sprite; +var sprite2; +var sprite3; + +var bmd; + +var b1; +var b2; +var b3; + +var r; + +function create() { + + game.stage.backgroundColor = '#124184'; + + test1(); + + bmd = game.add.bitmapData(800, 600); + var bg = game.add.sprite(0, 0, bmd); + bg.body.moves = false; + + bmd.clear(); + bmd.context.lineWidth = 1; + +} + +function test1() { + + sprite = game.add.sprite(500, 400, 'gameboy', 0); + // sprite = game.add.sprite(0, 0, 'gameboy', 0); + sprite.name = 'red'; + // sprite.pivot.x = 20; + // sprite.pivot.y = 30; + // sprite.anchor.setTo(0.5, 0.5); + + // sprite.body.polygon.translate(20, 20); + + // sprite.body.polygon.rotate(game.math.degToRad(45)); + // sprite.angle = 45; + + // sprite.scale.setTo(2, 2); + // sprite.body.polygon.scale(2, 2); + + sprite.body.bounce.x = 0.8; + + sprite2 = game.add.sprite(0, 400, 'gameboy', 2); + sprite2.name = 'green'; + // sprite2.body = null; + + sprite3 = game.add.sprite(700, 400, 'gameboy', 3); + sprite3.name = 'yellow'; + // sprite3.body = null; + + // b1 = new SAT.Box(new SAT.Vector(sprite.x, sprite.y), sprite.width, sprite.height); + // b2 = new SAT.Box(new SAT.Vector(sprite2.x, sprite2.y), sprite2.width, sprite2.height); + // b3 = new SAT.Box(new SAT.Vector(sprite3.x, sprite3.y), sprite3.width, sprite3.height); + + // r = new SAT.Response(); + + // console.log(b2); + + game.input.onDown.add(launch1, this); + +} + +function launch1() { + + + // console.log(b1); + + sprite.body.velocity.x = -100; + // sprite2.body.velocity.x = -225; + +} + + +function update() { + + // sprite.angle += 0.5; + // sprite.body.polygon.rotate(game.math.degToRad(0.5)); + + /* + b1.pos.x = sprite.x; + b1.pos.y = sprite.y; + + b2.pos.x = sprite2.x; + b2.pos.y = sprite2.y; + + b3.pos.x = sprite3.x; + b3.pos.y = sprite3.y; + + r.clear(); + + if (SAT.testPolygonPolygon(b1.toPolygon(), b2.toPolygon(), r)) + { + console.log(r, b1.pos, b2.pos); + + // b1.pos.sub(r.overlapV); + // sprite.body.velocity.x *= -sprite.body.bounce.x; + + sprite.body.velocity.x = 0; + + sprite.x += Math.abs(r.overlapV.x) + 1; + console.log('sprite moved to', sprite.x); + // sprite.x = b1.pos.x; + // sprite.y = b1.pos.y; + + } + */ + + sprite.body.collide(sprite2.body); + + bmd.clear(); + + if (sprite) + { + renderPolygon(sprite.body.polygon); + // bmd.fillStyle('rgba(255,0,0,0.8'); + // bmd.fillRect(sprite.body.polygon.pos.x, sprite.body.polygon.pos.y, sprite.body.shape.w, sprite.body.shape.h); + } + + if (sprite2) + { + renderPolygon(sprite2.body.polygon); + // bmd.fillStyle('rgba(0,255,0,0.8'); + // bmd.fillRect(sprite2.body.polygon.pos.x, sprite2.body.polygon.pos.y, sprite2.body.shape.w, sprite2.body.shape.h); + } + + if (sprite3) + { + renderPolygon(sprite3.body.polygon); + // bmd.fillStyle('rgba(0,0,255,0.8'); + // bmd.fillRect(sprite3.body.polygon.pos.x, sprite3.body.polygon.pos.y, sprite3.body.shape.w, sprite3.body.shape.h); + } + +} + +function renderPolygon (polygon, color) { + +// console.log(polygon); + // this.start(0, 0, color); + + bmd.context.beginPath(); + bmd.context.moveTo(polygon.pos.x + polygon.points[0].x, polygon.pos.y + polygon.points[0].y); + + for (var i = 1; i < polygon.points.length; i++) + { + bmd.context.lineTo(polygon.pos.x + polygon.points[i].x, polygon.pos.y + polygon.points[i].y); + } + + bmd.context.closePath(); + bmd.context.strokeStyle = 'rgba(255, 255, 255, 1)'; + // bmd.context.strokeStyle = color; + bmd.context.stroke(); + +} + + +function render() { + + if (sprite) + { + // game.debug.renderBodyInfo(sprite, 16, 24); + game.debug.renderText(sprite.name + ' x: ' + sprite.x, 16, 500); + game.debug.renderText(sprite.name + ' world x: ' + sprite.world.x, 16, 520); + } + + if (sprite2) + { + // game.debug.renderBodyInfo(sprite2, 16, 190); + game.debug.renderText(sprite2.name + ' x: ' + sprite2.x, 400, 500); + } + +} diff --git a/examples/wip/sci-fly2.js b/examples/wip/sci-fly2.js new file mode 100644 index 00000000..2e2d502d --- /dev/null +++ b/examples/wip/sci-fly2.js @@ -0,0 +1,93 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update }); + +function preload() { + + game.load.tilemap('level3', 'assets/tilemaps/maps/cybernoid.json', null, Phaser.Tilemap.TILED_JSON); + game.load.image('tiles', 'assets/tilemaps/tiles/cybernoid.png', 16, 16); + game.load.image('phaser', 'assets/sprites/phaser-ship.png'); + game.load.image('chunk', 'assets/sprites/chunk.png'); + +} + +var map; +var layer; +var cursors; +var sprite; +var emitter; + +function create() { + + // A Tilemap object just holds the data needed to describe the map (i.e. the json exported from Tiled, or the CSV exported from elsewhere). + // You can add your own data or manipulate the data (swap tiles around, etc) but in order to display it you need to create a TilemapLayer. + map = game.add.tilemap('level3'); + + map.addTilesetImage('CybernoidMap3BG_bank.png', 'tiles'); + + layer = map.createLayer(0); + + // Basically this sets EVERY SINGLE tile to fully collide on all faces + map.setCollisionByExclusion([7, 32, 35, 36, 47]); + + // layer.debug = true; + + layer.resizeWorld(); + + cursors = game.input.keyboard.createCursorKeys(); + + emitter = game.add.emitter(0, 0, 200); + + emitter.makeParticles('chunk'); + emitter.minRotation = 0; + emitter.maxRotation = 0; + emitter.gravity = 150; + emitter.bounce.setTo(0.5, 0.5); + + sprite = game.add.sprite(200, 70, 'phaser'); + sprite.anchor.setTo(0.5, 0.5); + + game.camera.follow(sprite); + +} + +function particleBurst() { + + emitter.x = sprite.x; + emitter.y = sprite.y; + emitter.start(true, 2000, null, 1); + +} + +function update() { + + game.physics.collide(sprite, layer); + game.physics.collide(emitter, layer); + + sprite.body.velocity.x = 0; + sprite.body.velocity.y = 0; + + if (cursors.up.isDown) + { + sprite.body.velocity.y = -150; + particleBurst(); + } + else if (cursors.down.isDown) + { + sprite.body.velocity.y = 150; + particleBurst(); + } + + if (cursors.left.isDown) + { + sprite.body.velocity.x = -150; + sprite.scale.x = -1; + particleBurst(); + } + else if (cursors.right.isDown) + { + sprite.body.velocity.x = 150; + sprite.scale.x = 1; + particleBurst(); + } + +} diff --git a/examples/wip/snake.js b/examples/wip/snake.js new file mode 100644 index 00000000..65840205 --- /dev/null +++ b/examples/wip/snake.js @@ -0,0 +1,32 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + +} + +var snake; +var bmd; +var cursors; + +function create() { + + bmd = game.add.bitmapData(32, 32); + bmd.context.fillStyle = 'rgb(0, 255, 0)'; + bmd.context.fillRect(0, 0, 32, 32); + + snake = game.add.group(); + + sprite = game.add.sprite(game.world.randomX - 32, game.world.randomY - 64, bmd); + +} + +function update() { + + +} + +function render() { + +} diff --git a/examples/wip/snake2.js b/examples/wip/snake2.js new file mode 100644 index 00000000..c67cd7c3 --- /dev/null +++ b/examples/wip/snake2.js @@ -0,0 +1,169 @@ +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.spritesheet('snake','assets/games/snake/sprites.png', 32, 32); + game.load.image('ball', 'assets/sprites/pangball.png'); + +} + +var snake; + +var snakeHead; //head of snake sprite +var snakePath = []; //arrary of positions(points) that have to be stored for the path the sections follow +var numSnakeSections = 10; //number of snake body sections +var snakeSpacer = 6; //parameter that sets the spacing between sections +var snakeSpeed = 250; +var snakeLength = 10; + +var fruit; + +var snakeCircles = []; +var node; +var ball; + +function create() { + + game.world.setBounds(0, 0, 800, 600); + + game.stage.backgroundColor = '#0f4e93'; + + cursors = game.input.keyboard.createCursorKeys(); + + snake = game.add.group(); + + snakeHead = snake.create(400, 300, 'snake', 5); + snakeHead.anchor.setTo(0.5, 0.5); + snakeHead.animations.add('chomp', [5, 6], 10, true); + snakeHead.play('chomp'); + snakeHead.body.collideWorldBounds = true; + snakeCircles.push(new Phaser.Circle(snakeHead.x, snakeHead.y, 16)); + + // Init snakeSection array + for (var i = 1; i <= numSnakeSections-1; i++) + { + var snakeSection = snake.create(400, 300, 'snake', 7); + snakeSection.anchor.setTo(0.5, 0.5); + snakeSection.animations.add('walk', [7, 8, 9, 10], 10, true); + snakeSection.play('walk'); + snakeCircles.push(new Phaser.Circle(400, 300, 16)); + + if (i > snakeLength) + { + snakeSection.visible = false; + } + } + + node = new Phaser.Circle(300, 300, 170); + ball = game.add.sprite(node.x, node.y, 'ball'); + ball.anchor.setTo(0.5, 0.5); + + // fruit = game.add.group(); + + // for (var i = 0; i < 20; i++) + // { + // fruit.create(game.world.randomX, game.world.randomY, 'snake', 2); + // } + + // Init snakePath array + for (var i = 0; i <= numSnakeSections * snakeSpacer; i++) + { + snakePath[i] = new Phaser.Point(400, 300); + } + +} + +function newNode() { + + node.x = game.rnd.integerInRange(100, 700); + node.y = game.rnd.integerInRange(100, 500); + ball.x = node.x; + ball.y = node.y; + ball.alpha = 1; + +} + +function update() { + + // game.physics.collide(snakeHead, fruit, eatFruit); + + var enclosed = true; + + for (var i = 0; i <= numSnakeSections - 1; i++) + { + if (Phaser.Circle.intersects(snakeCircles[i], node) === false) + { + enclosed = false; + break; + } + } + + if (enclosed) + { + ball.alpha -= 0.02; + + if (ball.alpha <= 0) + { + newNode(); + } + } + + snakeHead.body.angularVelocity = 0; + + // if (cursors.up.isDown) + // { + snakeHead.body.velocity.copyFrom(game.physics.velocityFromAngle(snakeHead.angle, snakeSpeed)); + + snakeCircles[0].x = snakeHead.x; + snakeCircles[0].y = snakeHead.y; + + var part = snakePath.pop(); + + part.setTo(snakeHead.x, snakeHead.y); + + snakePath.unshift(part); + + for (var i = 1; i <= numSnakeSections - 1; i++) + { + var x = (snakePath[i * snakeSpacer]).x; + var y = (snakePath[i * snakeSpacer]).y; + snake.getAt(i).x = x; + snake.getAt(i).y = y; + snakeCircles[i].x = x; + snakeCircles[i].y = y; + } + // } + + if (cursors.left.isDown) + { + snakeHead.body.angularVelocity = -220; + } + else if (cursors.right.isDown) + { + snakeHead.body.angularVelocity = 220; + } + +} + +function eatFruit(snakeHead, fruit) { + + fruit.kill(); + + snakeLength++; + + snake.getAt(snakeLength).visible = true; + snakeSpeed += 10; + +} + +function render() { + + //game.debug.renderCircle(node); + + for (var i = 0; i <= numSnakeSections - 1; i++) + { + //game.debug.renderCircle(snakeCircles[i], 'rgb(255,0,0)'); + } + + +} \ No newline at end of file diff --git a/examples/wip/sprite vs sprite.js b/examples/wip/sprite vs sprite.js index 37f0ee32..6ecd9ed3 100644 --- a/examples/wip/sprite vs sprite.js +++ b/examples/wip/sprite vs sprite.js @@ -1,60 +1,95 @@ -var game = new Phaser.Game(800, 600, Phaser.CANVAS, '', { preload: preload, create: create, update: update, render: render }); +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); function preload() { game.load.image('atari', 'assets/sprites/atari130xe.png'); game.load.image('mushroom', 'assets/sprites/mushroom2.png'); + game.load.image('backdrop', 'assets/pics/remember-me.jpg'); } var sprite1; var sprite2; +var cursors; + function create() { + game.world.setBounds(0, 0, 1920, 1200); + + game.add.sprite(0, 0, 'backdrop'); + game.stage.backgroundColor = '#2d2d2d'; // This will check Sprite vs. Sprite collision + + sprite1 = game.add.sprite(50, 250, 'atari'); sprite1.name = 'atari'; - sprite1.body.immovable = true; + sprite1.body.immovable = true; - sprite2 = game.add.sprite(0, 0, 'mushroom'); + sprite2 = game.add.sprite(32, 32, 'mushroom'); sprite2.name = 'mushroom'; + sprite2.body.setCircle(32); + + game.camera.follow(sprite1); + + cursors = game.input.keyboard.createCursorKeys(); } function update() { - sprite1.body.x = game.input.x; //uncoment for tests - - if (sprite2.y > 400) + game.physics.collide(sprite1, sprite2); + + if (cursors.left.isDown) { - sprite2.x = 0; - sprite2.y = 0; + sprite1.body.x -= 4; + } + else if (cursors.right.isDown) + { + sprite1.body.x += 4; + } + + if (cursors.up.isDown) + { + sprite1.body.y -= 4; + } + else if (cursors.down.isDown) + { + sprite1.body.y += 4; + } + + + /* + sprite1.x = game.input.x; + + if (game.input.y > 300) + { + sprite1.y = game.input.y; + } + else + { + sprite1.y = 300; + } + + if (sprite2.y > 600) + { + sprite2.body.x = 0; + sprite2.body.y = 0; } + */ - sprite2.body.velocity.x = 100; - sprite2.body.velocity.y = 50; - - // object1, object2, collideCallback, processCallback, callbackContext - game.physics.collide(sprite1, sprite2, collisionHandler, null, this); - -} - -function collisionHandler (obj1, obj2) { - - game.stage.backgroundColor = '#992d2d'; - - console.log(obj1.name + ' collided with ' + obj2.name); + sprite2.body.velocity.x = 50; + sprite2.body.velocity.y = 100; } function render() { - game.debug.renderSpriteInfo(sprite1, 100, 400); - game.debug.renderSpriteBounds(sprite1); - game.debug.renderSpriteInfo(sprite2, 100, 100); - game.debug.renderSpriteBounds(sprite2); + + game.debug.renderPhysicsBody(sprite1.body); + game.debug.renderPhysicsBody(sprite2.body); + } diff --git a/examples/wip/template.js b/examples/wip/template.js new file mode 100644 index 00000000..544dd8f3 --- /dev/null +++ b/examples/wip/template.js @@ -0,0 +1,22 @@ + +var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + +} + +var sprite; + +function create() { + +} + +function update() { + + +} + +function render() { + +} diff --git a/examples/wip/text on top.js b/examples/wip/text on top.js new file mode 100644 index 00000000..8acd3b7b --- /dev/null +++ b/examples/wip/text on top.js @@ -0,0 +1,61 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render : render }); + +function preload() { + + game.load.image('mushroom', 'assets/sprites/mushroom2.png'); + +} + +var cursors; +var group; +var text; +var timer; + +function create() { + + game.stage.backgroundColor = '#007236'; + + for (var i = 0; i < 200; i++) + { + game.add.sprite(game.world.randomX, game.world.randomY, 'mushroom'); + } + + text = game.add.text(0, 0, "Text Above Sprites", { font: "64px Arial", fill: "#00bff3", align: "center" }); + + timer = new Phaser.Timer(game); + timer.add(1000); + + cursors = game.input.keyboard.createCursorKeys(); + +} + +function update() { + + timer.update(); + + if (cursors.up.isDown) + { + text.y -= 4; + } + else if (cursors.down.isDown) + { + text.y += 4; + } + + if (cursors.left.isDown) + { + text.x -= 4; + } + else if (cursors.right.isDown) + { + text.x += 4; + } + +} + +function render() { + + // game.debug.renderCameraInfo(game.camera, 32, 32); + +} diff --git a/examples/wip/tilemap poly.js b/examples/wip/tilemap poly.js new file mode 100644 index 00000000..99f4a442 --- /dev/null +++ b/examples/wip/tilemap poly.js @@ -0,0 +1,105 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, render: render }); + +function preload() { + + game.load.image('phaser', 'assets/sprites/phaser1.png'); + game.load.spritesheet('arrows', 'assets/sprites/arrows.png', 23, 31); + +} + +var arrowStart; +var arrowEnd; +var sprite; + +function create() { + + game.stage.backgroundColor = '#2384e7'; + + // game.physics.setBoundsToWorld(true, true, false, false); + + // arrowStart = game.add.sprite(100, 100, 'arrows', 0); + // arrowEnd = game.add.sprite(400, 100, 'arrows', 1); + + // sprite = game.add.sprite(100, 164, 'phaser'); + sprite = game.add.sprite(300, 364, 'phaser'); + // sprite.anchor.setTo(0.5, 0.5); + sprite.inputEnabled = true; + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(1, 1); + sprite.alpha = 0.2; + + // sprite.body.allowRotation = true; + // sprite.body.polygon.translate(100, 0); + + + // sprite.body.setPolygon([new SAT.Vector(0,0), new SAT.Vector(60, 0), new SAT.Vector(100, 40), new SAT.Vector(60, 80), new SAT.Vector(0, 80)], -50, -40); + + sprite.body.setPolygon([new SAT.Vector(0,50), new SAT.Vector(100, 50), new SAT.Vector(100, 0), new SAT.Vector(150, 0), new SAT.Vector(150, 150), new SAT.Vector(100, 150), new SAT.Vector(100, 100), new SAT.Vector(0, 100), new SAT.Vector(0, 50)], -100, -100); + + + // sprite.body.setCircle(50); + // sprite.body.offset.setTo(50, 50); + + // console.log(sprite.body.x, sprite.body.y, sprite.body.shape.radius); + + sprite.events.onInputDown.add(move, this); + + // sprite.body.polygons.rotate(0.4); + // sprite.rotation = 0.4; + + // console.log(sprite.body.polygons); + +} + +function move() { + + console.log('move'); + + sprite.body.velocity.x = 200; + sprite.body.velocity.y = -200; + // sprite.body.angularVelocity = 2; + + // sprite.rotation = 0.4; + + // console.log(sprite.body.polygon.points); + + // to: function (properties, duration, ease, autoStart, delay, repeat, yoyo) { + + // game.add.tween(sprite).to( { angle: 359 }, 8000, Phaser.Easing.Linear.None, true, 0, 1000, false); + + // sprite.scale.setTo(2, 2); + + if (sprite.x === 100) + { + // Here you'll notice we are using a relative value for the tween. + // You can specify a number as a string with either + or - at the start of it. + // When the tween starts it will take the sprites current X value and add +300 to it. + + // game.add.tween(sprite).to( { x: '+300' }, 2000, Phaser.Easing.Linear.None, true); + } + else if (sprite.x === 400) + { + // game.add.tween(sprite).to( { x: '-300' }, 2000, Phaser.Easing.Linear.None, true); + } + +} + +function render() { + + if (sprite.x === 100 || sprite.x === 400) + { + // game.debug.renderText('Click sprite to tween', 32, 32); + } + + // game.debug.renderText('x: ' + arrowStart.x, arrowStart.x, arrowStart.y - 4); + // game.debug.renderText('x: ' + arrowEnd.x, arrowEnd.x, arrowEnd.y - 4); + + game.debug.renderText('sprite.x: ' + sprite.x + ' deltaX: ' + sprite.deltaX, 32, 32); + game.debug.renderText('sprite.y: ' + sprite.y + ' deltaY: ' + sprite.deltaY, 32, 48); + + game.debug.renderPhysicsBody(sprite.body); + + game.debug.renderPoint(sprite.center); + +} diff --git a/examples/wip/tilemap.js b/examples/wip/tilemap.js new file mode 100644 index 00000000..68f9bd6f --- /dev/null +++ b/examples/wip/tilemap.js @@ -0,0 +1,217 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + // game.load.tilemap('map', 'assets/maps/super_mario.json', null, Phaser.Tilemap.TILED_JSON); + // game.load.tileset('tiles', 'assets/maps/super_mario.png', 16, 16); + + game.load.tilemap('map', 'assets/tilemaps/maps/features_test.json', null, Phaser.Tilemap.TILED_JSON); + + // game.load.image('ground', 'assets/maps/ground_1x1.png'); + + game.load.image('ground_1x1', 'assets/tilemaps/tiles/ground_1x1.png'); + game.load.image('walls_1x2', 'assets/tilemaps/tiles/walls_1x2.png'); + game.load.image('tiles2', 'assets/tilemaps/tiles/tiles2.png'); + + + // game.load.tileset('tiles', 'assets/maps/ground_1x1.png', 32, 32); + // game.load.image('phaser', 'assets/sprites/phaser-ship.png'); + // game.load.image('phaser', 'assets/sprites/mushroom2.png'); + game.load.image('phaser', 'assets/sprites/wabbit.png'); + // game.load.image('phaser', 'assets/sprites/arrow.png'); + game.load.spritesheet('coin', 'assets/sprites/coin.png', 32, 32); + // game.load.image('phaser', 'assets/sprites/darkwing_crazy.png'); + +} + +var cursors; +var map; +var coins; + +var layer; +var layer2; +var layer3; + +var sprite; + +function create() { + + map = game.add.tilemap('map'); + + map.addTilesetImage('ground_1x1'); + map.addTilesetImage('walls_1x2'); + map.addTilesetImage('tiles2'); + + map.setCollisionBetween(1, 12); + + // mario tiles + // map.setCollisionByIndex(15); + // map.setCollisionByIndex(40); + // map.setCollisionByIndexRange(14, 16); + // map.setCollisionByIndexRange(20, 25); + // map.setCollisionByIndexRange(27, 29); + + // layer3 = map.createLayer('Tile Layer 3'); + // layer3.scrollFactorX = 0.5; + + // layer2 = map.createLayer('Tile Layer 2'); + // layer2.alpha = 0.5; + + layer = map.createLayer('Tile Layer 1'); + + layer.debug = true; + + layer.resizeWorld(); + + //coins = + map.createFromObjects('Object Layer 1', 34, 'coin', 0); + + // layer2 = game.add.tilemapLayer(0, 0, 400, 600, null, map, 0); + // layer.cameraOffset.x = 400; + // layer.alpha = 0.5; + + + sprite = game.add.sprite(260, 100, 'phaser'); + // sprite.anchor.setTo(0.5, 0.5); + + // This adjusts the collision body size. + // 100x50 is the new width/height. + // 50, 25 is the X and Y offset of the newly sized box. + // In this case the box is 50px in and 25px down. + // sprite.body.setSize(16, 16, 8, 8); + + // We'll set a lower max angular velocity here to keep it from going totally nuts + sprite.body.maxAngular = 500; + + // Apply a drag otherwise the sprite will just spin and never slow down + sprite.body.angularDrag = 50; + + // sprite.body.drag.x = 50; + // sprite.body.drag.y = 20; + + // sprite.body.velocity.x = 50; + + sprite.body.bounce.x = 0.8; + sprite.body.bounce.y = 0.8; + + // sprite.angle = 35; + + // game.camera.follow(sprite); + + // game.input.onDown.add(getIt, this); + + cursors = game.input.keyboard.createCursorKeys(); + +} + +function getIt() { + + // console.log('cam', game.camera.bounds); + // console.log('w', game.world.bounds); + // console.log(layer.getTiles(sprite.body.x, sprite.body.y, sprite.body.width, sprite.body.height, true, true)); + +} + +function update() { + +/* + if (cursors.left.isDown) + { + game.camera.x -= 1; + } + else if (cursors.right.isDown) + { + game.camera.x += 1; + } + + if (cursors.up.isDown) + { + layer.scrollY -= 4; + } + else if (cursors.down.isDown) + { + layer.scrollY += 4; + } +*/ + game.physics.collide(sprite, layer); + + sprite.body.velocity.x = 0; + sprite.body.velocity.y = 0; + sprite.body.angularVelocity = 0; + + // sprite.body.acceleration.x = 0; + // sprite.body.angularAcceleration = 0; + + /* + if (cursors.left.isDown) + { + // sprite.body.acceleration.x = -200; + sprite.body.angularVelocity = -300; + // sprite.body.angularAcceleration -= 200; + } + else if (cursors.right.isDown) + { + // sprite.body.acceleration.x = 200; + sprite.body.angularVelocity = 300; + // sprite.body.angularAcceleration += 200; + } + + if (cursors.up.isDown) + { + game.physics.velocityFromAngle(sprite.angle, 300, sprite.body.velocity); + } + else + { + // game.physics.velocityFromAngle(sprite.angle, sprite.body.velocity, sprite.body.velocity); + } + */ + + + + + /* + sprite.body.velocity.x = 0; + sprite.body.velocity.y = 0; + + sprite.angle = sprite.angle + 1; + */ + + if (cursors.up.isDown) + { + sprite.body.velocity.y = -100; + } + else if (cursors.down.isDown) + { + sprite.body.velocity.y = 100; + } + + if (cursors.left.isDown) + { + sprite.body.velocity.x = -100; + } + else if (cursors.right.isDown) + { + sprite.body.velocity.x = 100; + } + + +} + +function render() { + + // game.debug.renderSpriteBody(sprite); + // game.debug.renderSpriteBounds(sprite); + game.debug.renderPhysicsBody(sprite.body); + + // game.debug.renderText(sprite.deltaX, 32, 32); + // game.debug.renderText(sprite.deltaY, 32, 48); + // game.debug.renderText(sprite.body.deltaX(), 232, 32); + // game.debug.renderText(sprite.body.deltaY(), 232, 48); + + // game.debug.renderText(sprite.body.left, 32, 32); + // game.debug.renderText(sprite.body.right, 32, 48); + + game.debug.renderSpriteCoords(sprite, 32, 32); + +} \ No newline at end of file diff --git a/examples/wip/timer simple.js b/examples/wip/timer simple.js new file mode 100644 index 00000000..f7b85429 --- /dev/null +++ b/examples/wip/timer simple.js @@ -0,0 +1,45 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('mushroom', 'assets/sprites/mushroom2.png'); + game.load.image('sonic', 'assets/sprites/pangball.png'); + +} + +var timer; + +function create() { + + game.stage.backgroundColor = '#007236'; + + + + // Every second we will call the addSprite function. This will happen 10 times and then stop. + // The final parameter is the one that will be sent to the addSprite function and in this case is the sprite key. + game.time.repeatEvent(Phaser.Timer.SECOND, 10, addSprite, this, 'mushroom'); + + // Every 1.5 seconds we will call the addSprite function. This will happen 5 times and then stop. + game.time.repeatEvent(1500, 10, addSprite, this, 'sonic'); + +} + +function addSprite(key) { + +console.log(arguments); + + game.add.sprite(game.world.randomX, game.world.randomY, key); + +} + +function update() { + +} + +function render() { + + game.debug.renderText(game.time._timer.ms, 32, 32); + // game.debug.renderCameraInfo(game.camera, 32, 32); + +} diff --git a/examples/wip/tween-limit.js b/examples/wip/tween-limit.js new file mode 100644 index 00000000..5a46976f --- /dev/null +++ b/examples/wip/tween-limit.js @@ -0,0 +1,55 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('phaser', 'assets/sprites/phaser1.png'); + game.load.spritesheet('arrows', 'assets/sprites/arrows.png', 23, 31); + +} + +var arrowStart; +var arrowEnd; +var sprite; + +function create() { + + game.stage.backgroundColor = '#2384e7'; + + arrowStart = game.add.sprite(100, 100, 'arrows', 0); + + arrowEnd = game.add.sprite(400, 100, 'arrows', 1); + + sprite = game.add.sprite(100, 164, 'phaser'); + sprite.inputEnabled = true; + + sprite.events.onInputDown.add(move, this); + +} + +function move() { + + var tween = game.add.tween(sprite).to( { x: '+500' }, 3000, Phaser.Easing.Linear.None, true); + + tween.onComplete.add(over, this); + +} + +function over() { + console.log('done'); + sprite.alpha = 0.5; +} + +function update() { + + if (sprite.x > 200) + { + sprite.x = 200; + } + +} + +function render() { + + +} diff --git a/examples/wip/tween-relative.js b/examples/wip/tween-relative.js new file mode 100644 index 00000000..7d0b8f2b --- /dev/null +++ b/examples/wip/tween-relative.js @@ -0,0 +1,102 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, render: render }); + +function preload() { + + game.load.image('phaser', 'assets/sprites/phaser1.png'); + game.load.spritesheet('arrows', 'assets/sprites/arrows.png', 23, 31); + +} + +var arrowStart; +var arrowEnd; +var sprite; + +function create() { + + game.stage.backgroundColor = '#2384e7'; + + // game.physics.setBoundsToWorld(true, true, false, false); + + // arrowStart = game.add.sprite(100, 100, 'arrows', 0); + // arrowEnd = game.add.sprite(400, 100, 'arrows', 1); + + // sprite = game.add.sprite(100, 164, 'phaser'); + sprite = game.add.sprite(300, 364, 'phaser'); + sprite.anchor.setTo(0.5, 0.5); + sprite.inputEnabled = true; + sprite.body.collideWorldBounds = true; + sprite.body.bounce.setTo(1, 1); + + // sprite.body.allowRotation = true; + // sprite.body.polygon.translate(100, 0); + + + sprite.body.setPolygon([new SAT.Vector(0,0), new SAT.Vector(60, 0), new SAT.Vector(100, 40), new SAT.Vector(60, 80), new SAT.Vector(0, 80)], -50, -40); + + + // sprite.body.setCircle(50); + // sprite.body.offset.setTo(50, 50); + + // console.log(sprite.body.x, sprite.body.y, sprite.body.shape.radius); + + sprite.events.onInputDown.add(move, this); + + // sprite.body.polygons.rotate(0.4); + // sprite.rotation = 0.4; + + // console.log(sprite.body.polygons); + +} + +function move() { + + console.log('move'); + + sprite.body.velocity.x = 200; + sprite.body.velocity.y = -200; + // sprite.body.angularVelocity = 2; + + // sprite.rotation = 0.4; + + // console.log(sprite.body.polygon.points); + + // to: function (properties, duration, ease, autoStart, delay, repeat, yoyo) { + + game.add.tween(sprite).to( { angle: 359 }, 4000, Phaser.Easing.Linear.None, true, 0, 1000, false); + + // sprite.scale.setTo(2, 2); + + if (sprite.x === 100) + { + // Here you'll notice we are using a relative value for the tween. + // You can specify a number as a string with either + or - at the start of it. + // When the tween starts it will take the sprites current X value and add +300 to it. + + // game.add.tween(sprite).to( { x: '+300' }, 2000, Phaser.Easing.Linear.None, true); + } + else if (sprite.x === 400) + { + // game.add.tween(sprite).to( { x: '-300' }, 2000, Phaser.Easing.Linear.None, true); + } + +} + +function render() { + + if (sprite.x === 100 || sprite.x === 400) + { + // game.debug.renderText('Click sprite to tween', 32, 32); + } + + // game.debug.renderText('x: ' + arrowStart.x, arrowStart.x, arrowStart.y - 4); + // game.debug.renderText('x: ' + arrowEnd.x, arrowEnd.x, arrowEnd.y - 4); + + game.debug.renderText('sprite.x: ' + sprite.x + ' deltaX: ' + sprite.deltaX, 32, 32); + game.debug.renderText('sprite.y: ' + sprite.y + ' deltaY: ' + sprite.deltaY, 32, 48); + + game.debug.renderPhysicsBody(sprite.body); + + game.debug.renderPoint(sprite.center); + +} diff --git a/examples/wip/wabbits.js b/examples/wip/wabbits.js new file mode 100644 index 00000000..38be965d --- /dev/null +++ b/examples/wip/wabbits.js @@ -0,0 +1,163 @@ +// mods by Patrick OReilly +// twitter: @pato_reilly + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.image('analog', 'assets/tests/fusia.png'); + game.load.image('arrow', 'assets/sprites/longarrow2.png'); + game.load.image('ball', 'assets/sprites/pangball.png'); + game.load.image('hill', 'assets/pics/atari_fujilogo.png'); + game.load.image('block', 'assets/sprites/block.png'); + game.load.image('wabbit', 'assets/sprites/wabbit.png'); + +} + +var arrow; +var ball; +var catchFlag = false; +var wabbits; +var wab; +var launchVelocity = 0; +var shotCount = 0; +var wabbitCount = 0; + +function create() { + + // set global gravity + game.physics.gravity.y = 200; + + game.stage.backgroundColor = '#0072bc'; + + var graphics = game.add.graphics(0, 0); + graphics.beginFill(0x049e0c); + graphics.drawRect(195, 450, 10, 150); + + wabbits = game.add.group(); + + for (var i = 0; i < 5; i++) + { + wab = wabbits.create(game.rnd.integerInRange(575, 650), game.rnd.integerInRange(150, 260), 'wabbit'); + wab.name = 'wab' + i; + wab.body.collideWorldBounds = true; + wab.body.mass = 0.1; + wab.body.linearDamping = 0.2; + } + + hill = game.add.sprite(450, 400, 'hill'); + hill.body.collideWorldBounds = true; + hill.body.mass = 10; + hill.body.immovable = true; + + block = game.add.sprite(575, 300, 'block'); + block.body.collideWorldBounds = true; + block.body.mass = 5; + block.body.linearDamping = 0.4; + + analog = game.add.sprite(200, 450, 'analog'); + analog.body.allowGravity = false; + analog.width = 8; + analog.rotation = 220; + analog.alpha = 0; + analog.anchor.setTo(0.5, 0.0); + + arrow = game.add.sprite(200, 450, 'arrow'); + arrow.anchor.setTo(0.1, 0.5); + arrow.body.allowGravity = false; + arrow.alpha = 0; + + ball = game.add.sprite(100, 400, 'ball'); + ball.anchor.setTo(0.5, 0.5); + ball.inputEnabled = true; + ball.body.collideWorldBounds = true; + ball.body.bounce.setTo(0.9, 0.9); + ball.body.linearDamping = 0.2; + ball.body.immovable = true; + + // Enable input. + ball.input.start(0, true); + ball.events.onInputDown.add(set); + ball.events.onInputUp.add(launch); + +} + +function set(ball, pointer) { + + ball.body.velocity.setTo(0, 0); + ball.body.allowGravity = false; + catchFlag = true; + +} + +function launch() { + + catchFlag = false; + shotCount++; + arrow.alpha = 0; + analog.alpha = 0; + Xvector = (arrow.x - ball.x) * 4.1; + Yvector = (arrow.y - ball.y) * 4.1; + ball.body.allowGravity = true; + ball.body.velocity.setTo(Xvector,Yvector); + +} + +function update() { + + arrow.rotation = game.physics.angleBetween(arrow, ball); + + if (catchFlag == true) + { + // Track the ball sprite to the mouse + ball.x = game.input.activePointer.worldX; + ball.y = game.input.activePointer.worldY; + + arrow.alpha = 1; + analog.alpha = 0.5; + analog.rotation = arrow.rotation - 3.14 / 2; + analog.height = game.physics.distanceToPointer(arrow); + launchVelocity = analog.height; + } + + game.physics.collide(ball, wabbits); + game.physics.collide(wabbits, wabbits); + game.physics.collide(wabbits, hill); + game.physics.collide(ball, hill); + game.physics.collide(block, hill); + game.physics.collide(block, ball); + game.physics.collide(block, wabbits); + + // check wabbits + var wabs = 0; + + for (var i = 0; i < 5; i++) + { + thisWab = wabbits.getAt(i); + + if (thisWab.x > 770 && thisWab.y > 400) + { + thisWab.alive = false; + wabs++; + } + } + + wabbitCount = 5 - wabs; + + // console.log(ball.body.y, ball.body.motionVelocity.y); + +} + +function render() { + + // game.debug.renderSpriteCollision(ball, 32, 32); + + // var graphics = game.add.graphics(0, 0); + // game.context.fillStyle = 'rgba(0,0,255,0.5)'; + // game.context.fillRect(770, 400, 30, 200); + // game.debug.renderText("Drag the ball to launch", 32, 32); + // game.debug.renderText("Try to get all 5 wabbits in the blue area with the least number of shots", 32, 64); + // game.debug.renderText("Shot Count: " + shotCount, 32, 96); + // game.debug.renderText("Wabbits Left: " + wabbitCount, 32, 128); + +} diff --git a/examples/wip/world.js b/examples/wip/world.js new file mode 100644 index 00000000..ae62a499 --- /dev/null +++ b/examples/wip/world.js @@ -0,0 +1,39 @@ + +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); + +function preload() { + + game.load.spritesheet('gameboy', 'assets/sprites/gameboy_seize_color_40x60.png', 40, 60); + +} + +var sprite; + +function create() { + + game.stage.backgroundColor = '#124184'; + + game.physics.gravity.y = 200; + + sprite = game.add.sprite(200, 250, 'gameboy', 4); + sprite.name = 'green'; + sprite.body.collideWorldBounds = true; + // sprite.anchor.setTo(0.5, 0.5); + + sprite.body.bounce.setTo(0.9, 0.9); + sprite.body.velocity.x = 150; + +} + +function update() { + + // sprite.worldTransform[2] += 1; + +} + +function render() { + + game.debug.renderBodyInfo(sprite, 32, 32); + game.debug.renderPhysicsBody(sprite.body); + +} diff --git a/examples/world/fixed to camera.js b/examples/world/fixed to camera.js index 54ee0372..744bdd15 100644 --- a/examples/world/fixed to camera.js +++ b/examples/world/fixed to camera.js @@ -18,20 +18,29 @@ var logo2; function create() { // Modify the world and camera bounds - game.world.setBounds(-1000, -1000, 1000, 1000); + game.world.setBounds(-1000, -1000, 2000, 2000); for (var i = 0; i < 200; i++) { game.add.sprite(game.world.randomX, game.world.randomY, 'mushroom'); } - logo1 = game.add.sprite(100, 100, 'phaser'); + game.add.text(0, 0, "this text scrolls\nwith the background", { font: "32px Arial", fill: "#f26c4f", align: "center" }); + + logo1 = game.add.sprite(0, 0, 'phaser'); logo1.fixedToCamera = true; + logo1.cameraOffset.setTo(100, 100); - logo2 = game.add.sprite(500, 100, 'phaser'); + logo2 = game.add.sprite(0, 0, 'phaser'); logo2.fixedToCamera = true; + logo2.cameraOffset.setTo(500, 100); - game.add.tween(logo2).to( { y: 400 }, 2000, Phaser.Easing.Back.InOut, true, 0, 2000, true); + + var t = game.add.text(0, 0, "this text is fixed to the camera", { font: "32px Arial", fill: "#ffffff", align: "center" }); + t.fixedToCamera = true; + t.cameraOffset.setTo(200, 500); + + game.add.tween(logo2.cameraOffset).to( { y: 400 }, 2000, Phaser.Easing.Back.InOut, true, 0, 2000, true); cursors = game.input.keyboard.createCursorKeys(); diff --git a/examples/world/move around world.js b/examples/world/move around world.js index 10049ad0..53a52026 100644 --- a/examples/world/move around world.js +++ b/examples/world/move around world.js @@ -1,5 +1,5 @@ -var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render : render }); +var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render }); function preload() { @@ -16,7 +16,7 @@ var d; function create() { // Modify the world and camera bounds - game.world.setBounds(-1000, -1000, 1000, 1000); + game.world.setBounds(-2000, -2000, 4000, 4000); for (var i = 0; i < 100; i++) { diff --git a/package.json b/package.json index e8eab2d6..c3c07166 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "Phaser", - "version": "1.1.3", + "version": "1.1.4", "description": "A fast, free and fun HTML5 Game Framework for Desktop and Mobile web browsers.", "author": "Richard Davey", "logo": "https://raw.github.com/photonstorm/phaser/master/phaser-logo-small.png", diff --git a/plugins/ProTracker.js b/plugins/ProTracker.js new file mode 100644 index 00000000..007fa11f --- /dev/null +++ b/plugins/ProTracker.js @@ -0,0 +1,913 @@ +/* + amiga protracker module player for web audio api + (c) 2012-2013 firehawk/tda (firehawk@haxor.fi) + + originally hacked together in a weekend, so please excuse + me for the spaghetti code. :) + + AMIGAAAAAAAAH!! + + kinda sorta changelog: + (apr 2013) + - changed the logic for pattern break/jump. mod.pattern_skank now + plays correctly. + (feb 2013) + - fixed NaN samples with mod.fractured and mod.multicolour (thanks Aegis!) + (jan 2013) + - fixed vibrato amplitude (was half of what it should be, apparently) + - fixed to work on safari again (thanks Matt Diamond @ stackoverflow.com) + (dec 2012) + - replaced effect switch-statement with jumptables + - fixed clicks (bad loops, empty samples) + - fixed playback bug with sample-only rows + - added amiga 500 lowpass filters (not 100% authentic, though) + - added compressor to output + - latest safari has broken web audio so chrome-only for now + (aug 2012) + - first version written from scratch + + todo: + - safari on ipad is broken again, it seems + - fix more playback bugs + * mod.black_queen (pattern loop has glitches) + - properly test EEx delay pattern + - implement the rest of the effects + - optimize for more speed!! SPEEEED!! + * switch to fixed point sample pointers, Math.floor() is _slow_ on iOS +*/ + +// constructor for protracker player object +function Protracker() +{ + var i, t; + + this.initialize(); + this.clearsong(); + + this.url=""; + this.loading=false; + this.ready=false; + this.playing=false; + this.buffer=0; + this.mixerNode=0; + this.paused=false; + this.repeat=false; + this.separation=true; + + this.palclock=true; + + this.autostart=false; + + this.onReady=function(){}; + this.onPlay=function(){}; + this.onStop=function(){}; + + // paula period values + this.baseperiodtable=new Array( + 856,808,762,720,678,640,604,570,538,508,480,453, + 428,404,381,360,339,320,302,285,269,254,240,226, + 214,202,190,180,170,160,151,143,135,127,120,113); + + // finetune multipliers + this.finetunetable=new Array(); + for(t=0;t<16;t++) this.finetunetable[t]=Math.pow(2, (t-8)/12/8); + + // calc tables for vibrato waveforms + this.vibratotable=new Array(); + for(t=0;t<4;t++) { + this.vibratotable[t]=new Array(); + for(i=0;i<64;i++) { + switch(t) { + case 0: + this.vibratotable[t][i]=127*Math.sin(Math.PI*2*(i/64)); + break; + case 1: + this.vibratotable[t][i]=127-4*i; + break; + case 2: + this.vibratotable[t][i]=(i<32)?127:-127; + break; + case 3: + this.vibratotable[t][i]=(1-2*Math.random())*127; + break; + } + } + } + + // effect jumptables + this.effects_t0 = new Array( + this.effect_t0_0, this.effect_t0_1, this.effect_t0_2, this.effect_t0_3, this.effect_t0_4, this.effect_t0_5, this.effect_t0_6, this.effect_t0_7, + this.effect_t0_8, this.effect_t0_9, this.effect_t0_a, this.effect_t0_b, this.effect_t0_c, this.effect_t0_d, this.effect_t0_e, this.effect_t0_f); + this.effects_t0_e = new Array( + this.effect_t0_e0, this.effect_t0_e1, this.effect_t0_e2, this.effect_t0_e3, this.effect_t0_e4, this.effect_t0_e5, this.effect_t0_e6, this.effect_t0_e7, + this.effect_t0_e8, this.effect_t0_e9, this.effect_t0_ea, this.effect_t0_eb, this.effect_t0_ec, this.effect_t0_ed, this.effect_t0_ee, this.effect_t0_ef); + this.effects_t1 = new Array( + this.effect_t1_0, this.effect_t1_1, this.effect_t1_2, this.effect_t1_3, this.effect_t1_4, this.effect_t1_5, this.effect_t1_6, this.effect_t1_7, + this.effect_t1_8, this.effect_t1_9, this.effect_t1_a, this.effect_t1_b, this.effect_t1_c, this.effect_t1_d, this.effect_t1_e, this.effect_t1_f); + this.effects_t1_e = new Array( + this.effect_t1_e0, this.effect_t1_e1, this.effect_t1_e2, this.effect_t1_e3, this.effect_t1_e4, this.effect_t1_e5, this.effect_t1_e6, this.effect_t1_e7, + this.effect_t1_e8, this.effect_t1_e9, this.effect_t1_ea, this.effect_t1_eb, this.effect_t1_ec, this.effect_t1_ed, this.effect_t1_ee, this.effect_t1_ef); + + this.context = null; + this.samplerate=44100; + this.bufferlen=2048; +} + + + +// create the web audio context +Protracker.prototype.createContext = function() +{ + this.context = new webkitAudioContext(); + this.samplerate=this.context.sampleRate; + this.bufferlen=(this.samplerate > 44100) ? 4096 : 2048; + + // fixed filter at 6kHz + this.filterNode=this.context.createBiquadFilter(); + this.filterNode.frequency.value=6000 + + // "LED filter" at 3.5kHz - off by default + this.lowpassNode=this.context.createBiquadFilter(); + this.lowpassNode.frequency.value=28867; + + // mixer + this.mixerNode=this.context.createJavaScriptNode(this.bufferlen, 1, 2); + this.mixerNode.module=this; + this.mixerNode.onaudioprocess=Protracker.prototype.mix; + + // compressor for a bit of volume boost + this.compressorNode=this.context.createDynamicsCompressor(); + + // patch up some cables :) + this.mixerNode.connect(this.filterNode); + this.filterNode.connect(this.lowpassNode); + this.lowpassNode.connect(this.compressorNode); + this.compressorNode.connect(this.context.destination); +} + + + +// play loaded and parsed module with webaudio context +Protracker.prototype.play = function() +{ + if (this.context==null) this.createContext(); + + if (!this.ready) return false; + if (this.paused) { + this.paused=false; + return true; + } + this.paused=false; + this.initialize(); + this.flags=1+2; + this.playing=true; + this.onPlay(); + return true; +} + + + +// pause playback +Protracker.prototype.pause = function() +{ + if (!this.paused) { + this.paused=true; + } else { + this.paused=false; + } +} + + + +// stop playback and release webaudio node +Protracker.prototype.stop = function() +{ + this.playing=false; + this.onStop(); +} + + + +// jump positions forward/back +Protracker.prototype.jump = function(step) +{ + this.tick=0; + this.row=0; + this.position+=step; + this.flags=1+2; + if (this.position<0) this.position=0; + if (this.position >= this.songlen) this.stop(); +} + + + +// set whether module repeats after songlen +Protracker.prototype.setrepeat = function(rep) +{ + this.repeat=rep; +} + + + +// set stereo separation mode (false=paula, true=betterpaula) +Protracker.prototype.setseparation = function(sep) +{ + this.separation=sep; +} + + + +// set amiga video standard (false=NTSC, true=PAL) +Protracker.prototype.setamigatype = function(clock) +{ + this.palclock=clock; +} + + + +// set autostart to play immediately after loading +Protracker.prototype.setautostart = function(st) +{ + this.autostart=st; +} + + + +// clear song data +Protracker.prototype.clearsong = function() +{ + this.title=""; + this.signature=""; + this.songlen=1; + this.repeatpos=0; + this.patterntable=new ArrayBuffer(128); + for(i=0;i<128;i++) this.patterntable[i]=0; + + this.channels=4; + + this.sample=new Array(); + this.samples=31; + for(i=0;i<31;i++) { + this.sample[i]=new Object(); + this.sample[i].name=""; + this.sample[i].length=0; + this.sample[i].finetune=0; + this.sample[i].volume=64; + this.sample[i].loopstart=0; + this.sample[i].looplength=0; + this.sample[i].data=0; + } + + this.patterns=0; + this.pattern=new Array(); + this.note=new Array(); + + this.looprow=0; + this.loopstart=0; + this.loopcount=0; + + this.patterndelay=0; + this.patternwait=0; +} + + +// initialize all player variables +Protracker.prototype.initialize = function() +{ + this.tick=0; + this.position=0; + this.row=0; + this.offset=0; + this.flags=0; + + this.speed=6; + this.bpm=125; + this.breakrow=0; + this.patternjump=0; + this.patterndelay=0; + this.patternwait=0; + + this.channel=new Array(); + for(i=0;i0x1f) && (this.buffer[st+j]<0x7f)) ? + (String.fromCharCode(this.buffer[st+j])) : + (" "); + j++; + } + this.sample[i].length=2*(this.buffer[st+22]*256 + this.buffer[st+23]); + this.sample[i].finetune=this.buffer[st+24]; + if (this.sample[i].finetune > 7) this.sample[i].finetune=this.sample[i].finetune-16; + this.sample[i].volume=this.buffer[st+25]; + this.sample[i].loopstart=2*(this.buffer[st+26]*256 + this.buffer[st+27]); + this.sample[i].looplength=2*(this.buffer[st+28]*256 + this.buffer[st+29]); + if (this.sample[i].looplength==2) this.sample[i].looplength=0; + if (this.sample[i].loopstart>this.sample[i].length) { + this.sample[i].loopstart=0; + this.sample[i].looplength=0; + } + } + + this.songlen=this.buffer[950]; + if (this.buffer[951] != 127) this.repeatpos=this.buffer[951]; + for(i=0;i<128;i++) { + this.patterntable[i]=this.buffer[952+i]; + if (this.patterntable[i] > this.patterns) this.patterns=this.patterntable[i]; + } + this.patterns+=1; + var patlen=4*64*this.channels; + + this.pattern=new Array(); + this.note=new Array(); + for(i=0;ispd) { mod.tick++; mod.offset=0; mod.flags|=1; } + if (mod.tick>=mod.speed) { + + if (mod.patterndelay) { // delay pattern + if (mod.tick < ((mod.patternwait+1)*mod.speed)) { + mod.patternwait++; + } else { + mod.row++; mod.tick=0; mod.flags|=2; mod.patterndelay=0; + + } + } + else { + + if (mod.flags&(16+32+64)) { + if (mod.flags&64) { // loop pattern? + mod.row=mod.looprow; + mod.flags&=0xa1; + mod.flags|=2; + } + else { + if (mod.flags&16) { // pattern jump/break? + //console.log("break to pattern " + mod.patternjump + " row "+mod.breakrow); + mod.position=mod.patternjump; + mod.row=mod.breakrow; + mod.patternjump=0; + mod.breakrow=0; + mod.flags&=0xe1; + mod.flags|=2; + } + } + mod.tick=0; + } else { + mod.row++; mod.tick=0; mod.flags|=2; + } + } + } + + if (mod.row>=64) { mod.position++; mod.row=0; mod.flags|=4; } + if (mod.position>=mod.songlen) { + if (mod.repeat) { + mod.position=0; + } else { + mod.stop(); + } + return; + } +} + + + +// mix an audio buffer with data +Protracker.prototype.mix = function(ape) { + var f; + var p, pp, n, nn; + var mod=ape.srcElement.module; + outp=new Array(); + + var bufs=new Array(ape.outputBuffer.getChannelData(0), ape.outputBuffer.getChannelData(1)); + var buflen=ape.outputBuffer.length; + for(var s=0;s3) mod.channel[ch].vibratopos=0; + mod.channel[ch].flags|=3; // recalc speed + mod.channel[ch].noteon=1; + } else { + mod.channel[ch].slideto=n; + + } + } + nn=mod.pattern[p][pp+0]&0xf0 | mod.pattern[p][pp+2]>>4; + if (nn) { + mod.channel[ch].sample=nn-1; + + mod.channel[ch].volume=mod.sample[nn-1].volume; + if (!n && (mod.channel[ch].samplepos > mod.sample[nn-1].length)) mod.channel[ch].samplepos=0; + } + } + } + mod.channel[ch].voiceperiod=mod.channel[ch].period; + if (mod.channel[ch].samplepos==0) modsample[ch]=mod.channel[ch].sample; + + + // kill empty samples + if (!mod.sample[mod.channel[ch].sample].length) mod.channel[ch].noteon=0; + + // effects + if (mod.flags&1) { + if (!mod.tick) { + // process only on tick 0 + mod.effects_t0[mod.channel[ch].command](mod, ch); + } else { + mod.effects_t1[mod.channel[ch].command](mod, ch); + } + } + + // recalc note number from period + if (mod.channel[ch].flags&2) { + for(var np=0; np=mod.channel[ch].period) mod.channel[ch].note=np; + mod.channel[ch].semitone=7; + if (mod.channel[ch].period>=120) + mod.channel[ch].semitone=mod.baseperiodtable[mod.channel[ch].note]-mod.baseperiodtable[mod.channel[ch].note+1]; + } + + // recalc sample speed and apply finetune + if ((mod.channel[ch].flags&1 || mod.flags&2) && mod.channel[ch].voiceperiod) + mod.channel[ch].samplespeed= + (mod.palclock ? 7093789.2 : 7159090.5)/(mod.channel[ch].voiceperiod*2) * mod.finetunetable[mod.sample[mod.channel[ch].sample].finetune+8] / mod.samplerate; + + // advance vibrato on each new tick + if (mod.flags&1) { + mod.channel[ch].vibratopos+=mod.channel[ch].vibratospeed; + mod.channel[ch].vibratopos&=0x3f; + } + + // mix channel to output + och=och^(ch&1); + f=0.0; + if (mod.channel[ch].noteon) { + if (mod.sample[mod.channel[ch].sample].length > mod.channel[ch].samplepos) + f=(1.0/mod.channels) * + (mod.sample[mod.channel[ch].sample].data[Math.floor(mod.channel[ch].samplepos)]*mod.channel[ch].volume)/64.0; + outp[och]+=f; + mod.channel[ch].samplepos+=mod.channel[ch].samplespeed; + } + if (s==0) mod.vu[ch]=Math.abs(f); + + // loop or end samples + if (mod.channel[ch].noteon) { + if (mod.sample[mod.channel[ch].sample].loopstart || mod.sample[mod.channel[ch].sample].looplength) { + if (mod.channel[ch].samplepos >= (mod.sample[mod.channel[ch].sample].loopstart+mod.sample[mod.channel[ch].sample].looplength)) { + mod.channel[ch].samplepos=mod.sample[mod.channel[ch].sample].loopstart; + } + } else { + if (mod.channel[ch].samplepos >= mod.sample[mod.channel[ch].sample].length) { + mod.channel[ch].noteon=0; + } + } + } + + // clear channel flags + mod.channel[ch].flags=0; + } + mod.offset++; + mod.flags&=0x70; + } + + // a more headphone-friendly stereo separation (aka. betterpaula) + if (mod.separation) { + t=outp[0]; + outp[0]=outp[0]*0.6 + outp[1]*0.4; + outp[1]=outp[1]*0.6 + t*0.4; + } + bufs[0][s]=outp[0]; + bufs[1][s]=outp[1]; + } +} + + + +// +// tick 0 effect functions +// +Protracker.prototype.effect_t0_0=function(mod, ch) { // 0 arpeggio + mod.channel[ch].arpeggio=mod.channel[ch].data; +} +Protracker.prototype.effect_t0_1=function(mod, ch) { // 1 slide up + if (mod.channel[ch].data) mod.channel[ch].slidespeed=mod.channel[ch].data; +} +Protracker.prototype.effect_t0_2=function(mod, ch) { // 2 slide down + if (mod.channel[ch].data) mod.channel[ch].slidespeed=mod.channel[ch].data; +} +Protracker.prototype.effect_t0_3=function(mod, ch) { // 3 slide to note + if (mod.channel[ch].data) mod.channel[ch].slidetospeed=mod.channel[ch].data; +} +Protracker.prototype.effect_t0_4=function(mod, ch) { // 4 vibrato + if (mod.channel[ch].data&0x0f && mod.channel[ch].data&0xf0) { + mod.channel[ch].vibratodepth=(mod.channel[ch].data&0x0f); + mod.channel[ch].vibratospeed=(mod.channel[ch].data&0xf0)>>4; + } + mod.channel[ch].voiceperiod+= + (mod.channel[ch].vibratodepth/32)*mod.channel[ch].semitone*(mod.vibratotable[mod.channel[ch].vibratowave&3][mod.channel[ch].vibratopos]/127); + mod.channel[ch].flags|=1; +} +Protracker.prototype.effect_t0_5=function(mod, ch) { // 5 +} +Protracker.prototype.effect_t0_6=function(mod, ch) { // 6 +} +Protracker.prototype.effect_t0_7=function(mod, ch) { // 7 +} +Protracker.prototype.effect_t0_8=function(mod, ch) { // 8 +} +Protracker.prototype.effect_t0_9=function(mod, ch) { // 9 set sample offset + mod.channel[ch].samplepos=mod.channel[ch].data*256; +} +Protracker.prototype.effect_t0_a=function(mod, ch) { // a +} +Protracker.prototype.effect_t0_b=function(mod, ch) { // b pattern jump + mod.breakrow=0; + mod.patternjump=mod.channel[ch].data; + mod.flags|=16; +} +Protracker.prototype.effect_t0_c=function(mod, ch) { // c set volume + mod.channel[ch].volume=mod.channel[ch].data; +} +Protracker.prototype.effect_t0_d=function(mod, ch) { // d pattern break + mod.breakrow=((mod.channel[ch].data&0xf0)>>4)*10 + (mod.channel[ch].data&0x0f); + if (!(mod.flags&16)) mod.patternjump=mod.position+1; + mod.flags|=16; +} +Protracker.prototype.effect_t0_e=function(mod, ch) { // e + var i=(mod.channel[ch].data&0xf0)>>4; + mod.effects_t0_e[i](mod, ch); +} +Protracker.prototype.effect_t0_f=function(mod, ch) { // f set speed + if (mod.channel[ch].data > 32) { + mod.bpm=mod.channel[ch].data; + } else { + if (mod.channel[ch].data) mod.speed=mod.channel[ch].data; + } +} + + + +// +// tick 0 effect e functions +// +Protracker.prototype.effect_t0_e0=function(mod, ch) { // e0 filter on/off + if (mod.channel[ch].data&0x0f) { + mod.lowpassNode.frequency.value=4280; //3500; + } else { + mod.lowpassNode.frequency.value=28867; + } +} +Protracker.prototype.effect_t0_e1=function(mod, ch) { // e1 fine slide up + mod.channel[ch].period-=mod.channel[ch].data&0x0f; + if (mod.channel[ch].period < 113) mod.channel[ch].period=113; +} +Protracker.prototype.effect_t0_e2=function(mod, ch) { // e2 fine slide down + mod.channel[ch].period+=mod.channel[ch].data&0x0f; + if (mod.channel[ch].period > 856) mod.channel[ch].period=856; + mod.channel[ch].flags|=1; +} +Protracker.prototype.effect_t0_e3=function(mod, ch) { // e3 set glissando +} +Protracker.prototype.effect_t0_e4=function(mod, ch) { // e4 set vibrato waveform + mod.channel[ch].vibratowave=mod.channel[ch].data&0x07; +} +Protracker.prototype.effect_t0_e5=function(mod, ch) { // e5 set finetune +} +Protracker.prototype.effect_t0_e6=function(mod, ch) { // e6 loop pattern + if (mod.channel[ch].data&0x0f) { + if (mod.loopcount) { + mod.loopcount--; + } else { + mod.loopcount=mod.channel[ch].data&0x0f; + } + if (mod.loopcount) mod.flags|=64; + } else { + mod.looprow=mod.row; + } +} +Protracker.prototype.effect_t0_e7=function(mod, ch) { // e7 +} +Protracker.prototype.effect_t0_e8=function(mod, ch) { // e8 +} +Protracker.prototype.effect_t0_e9=function(mod, ch) { // e9 +} +Protracker.prototype.effect_t0_ea=function(mod, ch) { // ea fine volslide up + mod.channel[ch].volume+=mod.channel[ch].data&0x0f; + if (mod.channel[ch].volume > 64) mod.channel[ch].volume=64; +} +Protracker.prototype.effect_t0_eb=function(mod, ch) { // eb fine volslide down + mod.channel[ch].volume-=mod.channel[ch].data&0x0f; + if (mod.channel[ch].volume < 0) mod.channel[ch].volume=0; +} +Protracker.prototype.effect_t0_ec=function(mod, ch) { // ec +} +Protracker.prototype.effect_t0_ed=function(mod, ch) { // ed delay sample + if (mod.tick==(mod.channel[ch].data&0x0f)) { + // start note + var p=mod.patterntable[mod.position]; + var pp=mod.row*4*mod.channels + ch*4; + n=(mod.pattern[p][pp]&0x0f)<<8 | mod.pattern[p][pp+1]; + if (n) { + mod.channel[ch].period=n; + mod.channel[ch].voiceperiod=mod.channel[ch].period; + mod.channel[ch].samplepos=0; + if (mod.channel[ch].vibratowave>3) mod.channel[ch].vibratopos=0; + mod.channel[ch].flags|=3; // recalc speed + mod.channel[ch].noteon=1; + } + n=mod.pattern[p][pp+0]&0xf0 | mod.pattern[p][pp+2]>>4; + if (n) { + mod.channel[ch].sample=n-1; + mod.channel[ch].volume=mod.sample[n-1].volume; + } + } +} +Protracker.prototype.effect_t0_ee=function(mod, ch) { // ee delay pattern + mod.patterndelay=mod.channel[ch].data&0x0f; + mod.patternwait=0; +} +Protracker.prototype.effect_t0_ef=function(mod, ch) { // ef +} + + + +// +// tick 1+ effect functions +// +Protracker.prototype.effect_t1_0=function(mod, ch) { // 0 arpeggio + if (mod.channel[ch].data) { + var apn=mod.channel[ch].note; + if ((mod.tick%3)==1) apn+=mod.channel[ch].arpeggio>>4; + if ((mod.tick%3)==2) apn+=mod.channel[ch].arpeggio&0x0f; + if (apn>=0 && apn <= mod.baseperiodtable.length) + mod.channel[ch].voiceperiod = mod.baseperiodtable[apn]; + mod.channel[ch].flags|=1; + } +} +Protracker.prototype.effect_t1_1=function(mod, ch) { // 1 slide up + mod.channel[ch].period-=mod.channel[ch].slidespeed; + if (mod.channel[ch].period<113) mod.channel[ch].period=113; + mod.channel[ch].flags|=3; // recalc speed +} +Protracker.prototype.effect_t1_2=function(mod, ch) { // 2 slide down + mod.channel[ch].period+=mod.channel[ch].slidespeed; + if (mod.channel[ch].period>856) mod.channel[ch].period=856; + mod.channel[ch].flags|=3; // recalc speed +} +Protracker.prototype.effect_t1_3=function(mod, ch) { // 3 slide to note + if (mod.channel[ch].period < mod.channel[ch].slideto) { + mod.channel[ch].period+=mod.channel[ch].slidetospeed; + if (mod.channel[ch].period > mod.channel[ch].slideto) + mod.channel[ch].period=mod.channel[ch].slideto; + } + if (mod.channel[ch].period > mod.channel[ch].slideto) { + mod.channel[ch].period-=mod.channel[ch].slidetospeed; + if (mod.channel[ch].period>4); + if (mod.channel[ch].volume>64) mod.channel[ch].volume=64; + } + if (!(mod.channel[ch].data&0xf0)) { + // x is zero, slide down + mod.channel[ch].volume-=(mod.channel[ch].data&0x0f); + if (mod.channel[ch].volume<0) mod.channel[ch].volume=0; + } +} +Protracker.prototype.effect_t1_b=function(mod, ch) { // b pattern jump +} +Protracker.prototype.effect_t1_c=function(mod, ch) { // c set volume +} +Protracker.prototype.effect_t1_d=function(mod, ch) { // d pattern break +} +Protracker.prototype.effect_t1_e=function(mod, ch) { // e + var i=(mod.channel[ch].data&0xf0)>>4; + mod.effects_t1_e[i](mod, ch); +} +Protracker.prototype.effect_t1_f=function(mod, ch) { // f +} + + + +// +// tick 1+ effect e functions +// +Protracker.prototype.effect_t1_e0=function(mod, ch) { // e0 +} +Protracker.prototype.effect_t1_e1=function(mod, ch) { // e1 +} +Protracker.prototype.effect_t1_e2=function(mod, ch) { // e2 +} +Protracker.prototype.effect_t1_e3=function(mod, ch) { // e3 +} +Protracker.prototype.effect_t1_e4=function(mod, ch) { // e4 +} +Protracker.prototype.effect_t1_e5=function(mod, ch) { // e5 +} +Protracker.prototype.effect_t1_e6=function(mod, ch) { // e6 +} +Protracker.prototype.effect_t1_e7=function(mod, ch) { // e7 +} +Protracker.prototype.effect_t1_e8=function(mod, ch) { // e8 +} +Protracker.prototype.effect_t1_e9=function(mod, ch) { // e9 retrig sample + if (mod.tick%(mod.channel[ch].data&0x0f)==0) + mod.channel[ch].samplepos=0; +} +Protracker.prototype.effect_t1_ea=function(mod, ch) { // ea +} +Protracker.prototype.effect_t1_eb=function(mod, ch) { // eb +} +Protracker.prototype.effect_t1_ec=function(mod, ch) { // ec cut sample + if (mod.tick==(mod.channel[ch].data&0x0f)) + mod.channel[ch].volume=0; +} +Protracker.prototype.effect_t1_ed=function(mod, ch) { // ed delay sample + mod.effect_t0_ed(mod, ch); +} +Protracker.prototype.effect_t1_ee=function(mod, ch) { // ee +} +Protracker.prototype.effect_t1_ef=function(mod, ch) { // ef +} diff --git a/resources/Project Templates/Basic/Boot.js b/resources/Project Templates/Basic/Boot.js index 297cec2f..ec45e6e2 100644 --- a/resources/Project Templates/Basic/Boot.js +++ b/resources/Project Templates/Basic/Boot.js @@ -6,45 +6,45 @@ BasicGame.Boot = function (game) { BasicGame.Boot.prototype = { - preload: function () { + preload: function () { - // Here we load the assets required for our preloader (in this case a background and a loading bar) - this.load.image('preloaderBackground', 'images/preloader_background.jpg'); - this.load.image('preloaderBar', 'images/preloadr_bar.png'); + // Here we load the assets required for our preloader (in this case a background and a loading bar) + this.load.image('preloaderBackground', 'images/preloader_background.jpg'); + this.load.image('preloaderBar', 'images/preloadr_bar.png'); - }, + }, - create: function () { + create: function () { - // Unless you specifically know your game needs to support multi-touch I would recommend setting this to 1 - this.game.input.maxPointers = 1; + // Unless you specifically know your game needs to support multi-touch I would recommend setting this to 1 + this.game.input.maxPointers = 1; - // Phaser will automatically pause if the browser tab the game is in loses focus. You can disable that here: - this.game.stage.disableVisibilityChange = true; + // Phaser will automatically pause if the browser tab the game is in loses focus. You can disable that here: + this.game.stage.disableVisibilityChange = true; - if (this.game.device.desktop) - { - // If you have any desktop specific settings, they can go in here - this.game.stage.scale.pageAlignHorizontally = true; - } - else - { - // Same goes for mobile settings. - // In this case we're saying "scale the game, no lower than 480x260 and no higher than 1024x768" - this.game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL; - this.game.stage.scale.minWidth = 480; - this.game.stage.scale.minHeight = 260; - this.game.stage.scale.maxWidth = 1024; - this.game.stage.scale.maxHeight = 768; - this.game.stage.scale.forceLandscape = true; - this.game.stage.scale.pageAlignHorizontally = true; - this.game.stage.scale.setScreenSize(true); - } + if (this.game.device.desktop) + { + // If you have any desktop specific settings, they can go in here + this.game.stage.scale.pageAlignHorizontally = true; + } + else + { + // Same goes for mobile settings. + // In this case we're saying "scale the game, no lower than 480x260 and no higher than 1024x768" + this.game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL; + this.game.stage.scale.minWidth = 480; + this.game.stage.scale.minHeight = 260; + this.game.stage.scale.maxWidth = 1024; + this.game.stage.scale.maxHeight = 768; + this.game.stage.scale.forceLandscape = true; + this.game.stage.scale.pageAlignHorizontally = true; + this.game.stage.scale.setScreenSize(true); + } - // By this point the preloader assets have loaded to the cache, we've set the game settings - // So now let's start the real preloader going - this.game.state.start('Preloader'); + // By this point the preloader assets have loaded to the cache, we've set the game settings + // So now let's start the real preloader going + this.game.state.start('Preloader'); - } + } }; diff --git a/resources/Project Templates/Full Screen Mobile/apple-touch-icon.png b/resources/Project Templates/Full Screen Mobile/apple-touch-icon.png new file mode 100644 index 00000000..515a3f39 Binary files /dev/null and b/resources/Project Templates/Full Screen Mobile/apple-touch-icon.png differ diff --git a/resources/Project Templates/Full Screen Mobile/css/stylesheet.css b/resources/Project Templates/Full Screen Mobile/css/stylesheet.css new file mode 100644 index 00000000..8f2bba97 --- /dev/null +++ b/resources/Project Templates/Full Screen Mobile/css/stylesheet.css @@ -0,0 +1,19 @@ +body { + margin: 0px 0px 1px 0px; /* the extra 1px allows the iOS inner/outer check to work */ + background: #000; +} + +#orientation { + margin: 0 auto; + position: absolute; + top: 0; + left: 0; + width: 100%; + height: 100%; + background-image: url(../images/orientation.jpg); + background-repeat: no-repeat; + background-position: center; + background-color: rgb(0, 0, 0); + z-index: 999; + display: none; +} diff --git a/resources/Project Templates/Full Screen Mobile/icons/app_icon_1024x1024.png b/resources/Project Templates/Full Screen Mobile/icons/app_icon_1024x1024.png new file mode 100644 index 00000000..5d3970c0 Binary files /dev/null and b/resources/Project Templates/Full Screen Mobile/icons/app_icon_1024x1024.png differ diff --git a/resources/Project Templates/Full Screen Mobile/icons/app_icon_114x114.png b/resources/Project Templates/Full Screen Mobile/icons/app_icon_114x114.png new file mode 100644 index 00000000..55135823 Binary files /dev/null and b/resources/Project Templates/Full Screen Mobile/icons/app_icon_114x114.png differ diff --git a/resources/Project Templates/Full Screen Mobile/icons/app_icon_120x120.png b/resources/Project Templates/Full Screen Mobile/icons/app_icon_120x120.png new file mode 100644 index 00000000..a792451d Binary files /dev/null and b/resources/Project Templates/Full Screen Mobile/icons/app_icon_120x120.png differ diff --git a/resources/Project Templates/Full Screen Mobile/icons/app_icon_144x144.png b/resources/Project Templates/Full Screen Mobile/icons/app_icon_144x144.png new file mode 100644 index 00000000..515a3f39 Binary files /dev/null and b/resources/Project Templates/Full Screen Mobile/icons/app_icon_144x144.png differ diff --git a/resources/Project Templates/Full Screen Mobile/icons/app_icon_152x152.png b/resources/Project Templates/Full Screen Mobile/icons/app_icon_152x152.png new file mode 100644 index 00000000..accf1a85 Binary files /dev/null and b/resources/Project Templates/Full Screen Mobile/icons/app_icon_152x152.png differ diff --git a/resources/Project Templates/Full Screen Mobile/icons/app_icon_256x256.png b/resources/Project Templates/Full Screen Mobile/icons/app_icon_256x256.png new file mode 100644 index 00000000..f3483adb Binary files /dev/null and b/resources/Project Templates/Full Screen Mobile/icons/app_icon_256x256.png differ diff --git a/resources/Project Templates/Full Screen Mobile/icons/app_icon_512x512.png b/resources/Project Templates/Full Screen Mobile/icons/app_icon_512x512.png new file mode 100644 index 00000000..6a262257 Binary files /dev/null and b/resources/Project Templates/Full Screen Mobile/icons/app_icon_512x512.png differ diff --git a/resources/Project Templates/Full Screen Mobile/icons/app_icon_57x57.png b/resources/Project Templates/Full Screen Mobile/icons/app_icon_57x57.png new file mode 100644 index 00000000..3ede8f9a Binary files /dev/null and b/resources/Project Templates/Full Screen Mobile/icons/app_icon_57x57.png differ diff --git a/resources/Project Templates/Full Screen Mobile/icons/app_icon_60x60.png b/resources/Project Templates/Full Screen Mobile/icons/app_icon_60x60.png new file mode 100644 index 00000000..b91c98e7 Binary files /dev/null and b/resources/Project Templates/Full Screen Mobile/icons/app_icon_60x60.png differ diff --git a/resources/Project Templates/Full Screen Mobile/icons/app_icon_72x72.png b/resources/Project Templates/Full Screen Mobile/icons/app_icon_72x72.png new file mode 100644 index 00000000..88135b25 Binary files /dev/null and b/resources/Project Templates/Full Screen Mobile/icons/app_icon_72x72.png differ diff --git a/resources/Project Templates/Full Screen Mobile/icons/app_icon_76x76.png b/resources/Project Templates/Full Screen Mobile/icons/app_icon_76x76.png new file mode 100644 index 00000000..18b6092b Binary files /dev/null and b/resources/Project Templates/Full Screen Mobile/icons/app_icon_76x76.png differ diff --git a/resources/Project Templates/Full Screen Mobile/images/orientation.jpg b/resources/Project Templates/Full Screen Mobile/images/orientation.jpg new file mode 100644 index 00000000..e29185a2 Binary files /dev/null and b/resources/Project Templates/Full Screen Mobile/images/orientation.jpg differ diff --git a/resources/Project Templates/Full Screen Mobile/index.html b/resources/Project Templates/Full Screen Mobile/index.html new file mode 100644 index 00000000..52377721 --- /dev/null +++ b/resources/Project Templates/Full Screen Mobile/index.html @@ -0,0 +1,65 @@ + + + + Phaser Full Screen Mobile Example + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +
    + + + + + \ No newline at end of file diff --git a/resources/Project Templates/Full Screen Mobile/src/Boot.js b/resources/Project Templates/Full Screen Mobile/src/Boot.js new file mode 100644 index 00000000..80f96731 --- /dev/null +++ b/resources/Project Templates/Full Screen Mobile/src/Boot.js @@ -0,0 +1,86 @@ +BasicGame = { + + /* Here we've just got some global level vars that persist regardless of State swaps */ + score: 0, + + /* If the music in your game needs to play through-out a few State swaps, then you could reference it here */ + music: null, + + /* Your game can check BasicGame.orientated in internal loops to know if it should pause or not */ + orientated: false + +}; + +BasicGame.Boot = function (game) { +}; + +BasicGame.Boot.prototype = { + + preload: function () { + + // Here we load the assets required for our preloader (in this case a background and a loading bar) + this.load.image('preloaderBackground', 'images/preloader_background.jpg'); + this.load.image('preloaderBar', 'images/preloadr_bar.png'); + + }, + + create: function () { + + this.game.input.maxPointers = 1; + this.game.stage.disableVisibilityChange = true; + + if (this.game.device.desktop) + { + this.game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL; + this.game.stage.scale.minWidth = 480; + this.game.stage.scale.minHeight = 260; + this.game.stage.scale.maxWidth = 1024; + this.game.stage.scale.maxHeight = 768; + this.game.stage.scale.pageAlignHorizontally = true; + this.game.stage.scale.pageAlignVertically = true; + this.game.stage.scale.setScreenSize(true); + } + else + { + this.game.stage.scaleMode = Phaser.StageScaleMode.SHOW_ALL; + this.game.stage.scale.minWidth = 480; + this.game.stage.scale.minHeight = 260; + this.game.stage.scale.maxWidth = 1024; + this.game.stage.scale.maxHeight = 768; + this.game.stage.scale.pageAlignHorizontally = true; + this.game.stage.scale.pageAlignVertically = true; + this.game.stage.scale.forceOrientation(true, false); + this.game.stage.scale.hasResized.add(this.gameResized, this); + this.game.stage.scale.enterIncorrectOrientation.add(this.enterIncorrectOrientation, this); + this.game.stage.scale.leaveIncorrectOrientation.add(this.leaveIncorrectOrientation, this); + this.game.stage.scale.setScreenSize(true); + } + + this.game.state.start('Preloader'); + + }, + + gameResized: function (width, height) { + + // This could be handy if you need to do any extra processing if the game resizes. + // A resize could happen if for example swapping orientation on a device. + + }, + + enterIncorrectOrientation: function () { + + BasicGame.orientated = false; + + document.getElementById('orientation').style.display = 'block'; + + }, + + leaveIncorrectOrientation: function () { + + BasicGame.orientated = true; + + document.getElementById('orientation').style.display = 'none'; + + } + +}; \ No newline at end of file diff --git a/resources/Project Templates/Full Screen Mobile/src/Game.js b/resources/Project Templates/Full Screen Mobile/src/Game.js new file mode 100644 index 00000000..6190533d --- /dev/null +++ b/resources/Project Templates/Full Screen Mobile/src/Game.js @@ -0,0 +1,51 @@ + +BasicGame.Game = function (game) { + + // When a State is added to Phaser it automatically has the following properties set on it, even if they already exist: + + this.game; // a reference to the currently running game + this.add; // used to add sprites, text, groups, etc + this.camera; // a reference to the game camera + this.cache; // the game cache + this.input; // the global input manager (you can access this.input.keyboard, this.input.mouse, as well from it) + this.load; // for preloading assets + this.math; // lots of useful common math operations + this.sound; // the sound manager - add a sound, play one, set-up markers, etc + this.stage; // the game stage + this.time; // the clock + this.tweens; // the tween manager + this.world; // the game world + this.particles; // the particle manager + this.physics; // the physics manager + this.rnd; // the repeatable random number generator + + // You can use any of these from any function within this State. + // But do consider them as being 'reserved words', i.e. don't create a property for your own game called "world" or you'll over-write the world reference. + +}; + +BasicGame.Game.prototype = { + + create: function () { + + // Honestly, just about anything could go here. It's YOUR game after all. Eat your heart out! + + }, + + update: function () { + + // Honestly, just about anything could go here. It's YOUR game after all. Eat your heart out! + + }, + + quitGame: function (pointer) { + + // Here you should destroy anything you no longer need. + // Stop music, delete sprites, purge caches, free resources, all that good stuff. + + // Then let's go back to the main menu. + this.game.state.start('MainMenu'); + + } + +}; diff --git a/resources/Project Templates/Full Screen Mobile/src/MainMenu.js b/resources/Project Templates/Full Screen Mobile/src/MainMenu.js new file mode 100644 index 00000000..fe2a1ae1 --- /dev/null +++ b/resources/Project Templates/Full Screen Mobile/src/MainMenu.js @@ -0,0 +1,42 @@ + +BasicGame.MainMenu = function (game) { + + this.music = null; + this.playButton = null; + +}; + +BasicGame.MainMenu.prototype = { + + create: function () { + + // We've already preloaded our assets, so let's kick right into the Main Menu itself. + // Here all we're doing is playing some music and adding a picture and button + // Naturally I expect you to do something significantly better :) + + this.music = this.add.audio('titleMusic'); + this.music.play(); + + this.add.sprite(0, 0, 'titlepage'); + + this.playButton = this.add.button(400, 600, 'playButton', this.startGame, this, 'buttonOver', 'buttonOut', 'buttonOver'); + + }, + + update: function () { + + // Do some nice funky main menu effect here + + }, + + startGame: function (pointer) { + + // Ok, the Play Button has been clicked or touched, so let's stop the music (otherwise it'll carry on playing) + this.music.stop(); + + // And start the actual game + this.game.state.start('Game'); + + } + +}; diff --git a/resources/Project Templates/Full Screen Mobile/src/Preloader.js b/resources/Project Templates/Full Screen Mobile/src/Preloader.js new file mode 100644 index 00000000..434061bb --- /dev/null +++ b/resources/Project Templates/Full Screen Mobile/src/Preloader.js @@ -0,0 +1,61 @@ + +BasicGame.Preloader = function (game) { + + this.background = null; + this.preloadBar = null; + + this.ready = false; + +}; + +BasicGame.Preloader.prototype = { + + preload: function () { + + // These are the assets we loaded in Boot.js + // A nice sparkly background and a loading progress bar + this.background = this.add.sprite(0, 0, 'preloaderBackground'); + this.preloadBar = this.add.sprite(300, 400, 'preloaderBar'); + + // This sets the preloadBar sprite as a loader sprite. + // What that does is automatically crop the sprite from 0 to full-width + // as the files below are loaded in. + this.load.setPreloadSprite(this.preloadBar); + + // Here we load the rest of the assets our game needs. + // As this is just a Project Template I've not provided these assets, the lines below won't work as the files themselves will 404, they are just an example of use. + this.load.image('titlepage', 'images/title.jpg'); + this.load.atlas('playButton', 'images/play_button.png', 'images/play_button.json'); + this.load.audio('titleMusic', ['audio/main_menu.mp3']); + this.load.bitmapFont('caslon', 'fonts/caslon.png', 'fonts/caslon.xml'); + // + lots of other required assets here + + }, + + create: function () { + + // Once the load has finished we disable the crop because we're going to sit in the update loop for a short while as the music decodes + this.preloadBar.cropEnabled = false; + + }, + + update: function () { + + // You don't actually need to do this, but I find it gives a much smoother game experience. + // Basically it will wait for our audio file to be decoded before proceeding to the MainMenu. + // You can jump right into the menu if you want and still play the music, but you'll have a few + // seconds of delay while the mp3 decodes - so if you need your music to be in-sync with your menu + // it's best to wait for it to decode here first, then carry on. + + // If you don't have any music in your game then put the game.state.start line into the create function and delete + // the update function completely. + + if (this.cache.isSoundDecoded('titleMusic') && this.ready == false) + { + this.ready = true; + this.game.state.start('MainMenu'); + } + + } + +}; diff --git a/resources/Screen Shots/phaser-protracker.png b/resources/Screen Shots/phaser-protracker.png new file mode 100644 index 00000000..01ee9835 Binary files /dev/null and b/resources/Screen Shots/phaser-protracker.png differ diff --git a/resources/Screen Shots/phaser_polygons.png b/resources/Screen Shots/phaser_polygons.png new file mode 100644 index 00000000..cf089e5c Binary files /dev/null and b/resources/Screen Shots/phaser_polygons.png differ diff --git a/resources/wip/Degree-Radian_Conversion.svg b/resources/wip/Degree-Radian_Conversion.svg new file mode 100644 index 00000000..116cc38f --- /dev/null +++ b/resources/wip/Degree-Radian_Conversion.svg @@ -0,0 +1,3631 @@ + + + + + + + + + + + + + + + + + + image/svg+xml + + + + + + + + + + sin + cos + tan + cot + sec + csc + + + + + + + + + + + + + + + + + + + + + + + + + sin + cos + tan + cot + sec + csc + + + + + + + + + sin + cos + tan + cot + sec + csc + + + + + + + + + + sin + cos + tan + cot + sec + csc + + + + + + + + 2.3 + + + + + + + + + + + + + + + + + + + + + + + 90 + 80 + 70 + 60 + 50 + 40 + 30 + 20 + 270 + 280 + 10 + 0 & 360 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 100 + 110 + 120 + 130 + 140 + 150 + 160 + 170 + 180 + 190 + 200 + 210 + 220 + 230 + 240 + 250 + 260 + 290 + 300 + 310 + 320 + 330 + 340 + 350 + I + II + III + IV + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + 0 & 2π + + 0.1 + 0.2 + 0.3 + 0.4 + 0.5 + 0.6 + 0.7 + 0.8 + 0.9 + 1.0 + 1.1 + 1.2 + 1.3 + 1.4 + 1.5 + 1.6 + 1.7 + 1.8 + 1.9 + 2.0 + 2.1 + 2.2 + 2.4 + 2.5 + 2.6 + 2.7 + 2.8 + 2.9 + 3.0 + 3.1 + 3.2 + 3.3 + 3.4 + 3.5 + 3.6 + 3.7 + 3.8 + 3.9 + 4.0 + 4.1 + 4.2 + 4.3 + 4.4 + 4.5 + 4.6 + 4.7 + 4.8 + 4.9 + 5.0 + 5.1 + 5.2 + 5.3 + 5.4 + 5.5 + 5.6 + 5.7 + 5.8 + 5.9 + 6.0 + 6.1 + 6.2 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + π + + + π + + 2 + + + + + 3π + + 2 + + + Radians + Degrees + + + + π + + 180 + + + + + + π + + 180 + + + + + + + + + + + + + + + + + + + + + + + + + + π + + 6 + + + + π + + 4 + + + + π + + 3 + + + + 2π + + 3 + + + + 3π + + 4 + + + + 5π + + 6 + + + + 7π + + 6 + + + + 5π + + 4 + + 4π + + 3 + + + + + + + + 5π + + 3 + + + 7π + + 4 + + + 11π + + 6 + + + + + + diff --git a/src/Intro.js b/src/Intro.js index 908be578..da732d48 100644 --- a/src/Intro.js +++ b/src/Intro.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -20,7 +20,7 @@ * * Follow Phaser development progress at http://www.photonstorm.com * -* Many thanks to Adam Saltsman (@ADAMATOMIC) for releasing Flixel, from both which Phaser +* Many thanks to Adam Saltsman (@ADAMATOMIC) for releasing Flixel, from which both Phaser * and my love of game development originate. * * "If you want your children to be intelligent, read them fairy tales." diff --git a/src/IntroDocs.js b/src/IntroDocs.js index 323a0f43..11c06cfb 100644 --- a/src/IntroDocs.js +++ b/src/IntroDocs.js @@ -1,29 +1,15 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** * @overview * -* Phaser - http://www.phaser.io +* Many thanks to Adam Saltsman (@ADAMATOMIC) for creating Flixel, from which both Phaser and my love of game development originate. * -* v1.1.3 - Released November 28th 2013. -* -* By Richard Davey http://www.photonstorm.com @photonstorm -* -* A feature-packed 2D HTML5 game framework born from the smouldering pits of Flixel and -* constructed via plenty of blood, sweat, tears and coffee by Richard Davey (@photonstorm). -* -* Phaser uses Pixi.js for rendering, created by Mat Groves http://matgroves.com/ @Doormat23. -* -* Follow Phaser development progress at http://www.photonstorm.com -* -* Many thanks to Adam Saltsman (@ADAMATOMIC) for releasing Flixel, from both which Phaser -* and my love of game development originate. -* -* "If you want your children to be intelligent, read them fairy tales." -* "If you want them to be more intelligent, read them more fairy tales." +* "If you want your children to be intelligent, read them fairy tales."
    +* "If you want them to be more intelligent, read them more fairy tales."
    * -- Albert Einstein */ diff --git a/src/Phaser.js b/src/Phaser.js index d726a6eb..b8c554ca 100644 --- a/src/Phaser.js +++ b/src/Phaser.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -10,7 +10,7 @@ var Phaser = Phaser || { VERSION: '<%= version %>', - DEV_VERSION: '1.1.3', + DEV_VERSION: '1.1.4', GAMES: [], AUTO: 0, @@ -39,7 +39,10 @@ var Phaser = Phaser || { LEFT: 1, RIGHT: 2, UP: 3, - DOWN: 4 + DOWN: 4, + + CANVAS_PX_ROUND: false, + CANVAS_CLEAR_RECT: true }; diff --git a/src/PixiPatch.js b/src/PixiPatch.js index 23cd92d2..a71923ca 100644 --- a/src/PixiPatch.js +++ b/src/PixiPatch.js @@ -4,6 +4,7 @@ * 1) Added support for Trimmed sprite sheets * 2) Skip display objects with an alpha of zero * 3) Avoid Style Recalculation from the incorrect bgcolor value +* 4) Added support for Canvas unit rounding via Phaser.CANVAS_PX_ROUND boolean (disabled by default). * * Hopefully we can remove this once Pixi has been updated to support these things. */ @@ -23,8 +24,13 @@ PIXI.CanvasRenderer.prototype.render = function(stage) stage.updateTransform(); this.context.setTransform(1, 0, 0, 1, 0, 0); - this.context.clearRect(0, 0, this.width, this.height) - this.renderDisplayObject(stage); + + if (Phaser.CANVAS_CLEAR_RECT) + { + this.context.clearRect(0, 0, this.width, this.height) + } + + this.renderDisplayObject(stage, false); // Remove frame updates if (PIXI.Texture.frameUpdates.length > 0) @@ -34,7 +40,9 @@ PIXI.CanvasRenderer.prototype.render = function(stage) } -PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) +// @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered. + +PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject, renderHidden) { // Once the display object hits this we can break the loop var testObject = displayObject.last._iNext; @@ -42,9 +50,7 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) do { - //transform = displayObject.worldTransform; - - if (!displayObject.visible) + if (!displayObject.visible && !renderHidden) { displayObject = displayObject.last._iNext; continue; @@ -58,19 +64,41 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) if (displayObject instanceof PIXI.Sprite) { - // var frame = displayObject.texture.frame; - if (displayObject.texture.frame) { this.context.globalAlpha = displayObject.worldAlpha; - - if (displayObject.texture.trimmed) + + if (Phaser.CANVAS_PX_ROUND) { - this.context.setTransform(displayObject.worldTransform[0], displayObject.worldTransform[3], displayObject.worldTransform[1], displayObject.worldTransform[4], displayObject.worldTransform[2] + displayObject.texture.trim.x, displayObject.worldTransform[5] + displayObject.texture.trim.y); + this.context.setTransform( + displayObject.worldTransform[0], + displayObject.worldTransform[3], + displayObject.worldTransform[1], + displayObject.worldTransform[4], + Math.floor(displayObject.worldTransform[2]), + Math.floor(displayObject.worldTransform[5])); } else { - this.context.setTransform(displayObject.worldTransform[0], displayObject.worldTransform[3], displayObject.worldTransform[1], displayObject.worldTransform[4], displayObject.worldTransform[2], displayObject.worldTransform[5]); + this.context.setTransform( + displayObject.worldTransform[0], + displayObject.worldTransform[3], + displayObject.worldTransform[1], + displayObject.worldTransform[4], + displayObject.worldTransform[2], + displayObject.worldTransform[5]); + } + + if (displayObject.texture.trimmed) + { + this.context.transform(1, 0, 0, 1, displayObject.texture.trim.x, displayObject.texture.trim.y); + } + + //if smoothingEnabled is supported and we need to change the smoothing property for this texture + if (this.smoothProperty && this.scaleMode !== displayObject.texture.baseTexture.scaleMode) + { + this.scaleMode = displayObject.texture.baseTexture.scaleMode; + this.context[this.smoothProperty] = (this.scaleMode === PIXI.BaseTexture.SCALE_MODE.LINEAR); } this.context.drawImage( @@ -79,8 +107,8 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject) displayObject.texture.frame.y, displayObject.texture.frame.width, displayObject.texture.frame.height, - (displayObject.anchor.x) * -displayObject.texture.frame.width, - (displayObject.anchor.y) * -displayObject.texture.frame.height, + Math.floor((displayObject.anchor.x) * -displayObject.texture.frame.width), + Math.floor((displayObject.anchor.y) * -displayObject.texture.frame.height), displayObject.texture.frame.width, displayObject.texture.frame.height); } diff --git a/src/animation/Animation.js b/src/animation/Animation.js index d3c545bb..b28b4e2d 100644 --- a/src/animation/Animation.js +++ b/src/animation/Animation.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -43,7 +43,7 @@ Phaser.Animation = function (game, parent, name, frameData, frames, delay, loope this.name = name; /** - * @property {object} _frames + * @property {array} _frames * @private */ this._frames = []; @@ -60,7 +60,8 @@ Phaser.Animation = function (game, parent, name, frameData, frames, delay, loope this.looped = looped; /** - * @property {boolean} looped - The loop state of the Animation. + * @property {boolean} killOnComplete - Should the parent of this Animation be killed when the animation completes? + * @default */ this.killOnComplete = false; @@ -327,6 +328,8 @@ Phaser.Animation.prototype = { }; +Phaser.Animation.prototype.constructor = Phaser.Animation; + /** * @name Phaser.Animation#paused * @property {boolean} paused - Gets and sets the paused state of this Animation. diff --git a/src/animation/AnimationManager.js b/src/animation/AnimationManager.js index 043ae6c9..219c5232 100644 --- a/src/animation/AnimationManager.js +++ b/src/animation/AnimationManager.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -266,7 +266,7 @@ Phaser.AnimationManager.prototype = { * * @method Phaser.AnimationManager#getAnimation * @param {string} name - The name of the animation to be returned, e.g. "fire". - * @return {Phaser.Animation|boolean} The Animation instance, if found, otherwise false. + * @return {Phaser.Animation} The Animation instance, if found, otherwise null. */ getAnimation: function (name) { @@ -278,7 +278,7 @@ Phaser.AnimationManager.prototype = { } } - return false; + return null; }, @@ -311,6 +311,8 @@ Phaser.AnimationManager.prototype = { }; +Phaser.AnimationManager.prototype.constructor = Phaser.AnimationManager; + /** * @name Phaser.AnimationManager#frameData * @property {Phaser.FrameData} frameData - The current animations FrameData. diff --git a/src/animation/AnimationParser.js b/src/animation/AnimationParser.js index a3b4acf7..d8bcd720 100644 --- a/src/animation/AnimationParser.js +++ b/src/animation/AnimationParser.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -20,9 +20,11 @@ Phaser.AnimationParser = { * @param {number} frameWidth - The fixed width of each frame of the animation. * @param {number} frameHeight - The fixed height of each frame of the animation. * @param {number} [frameMax=-1] - The total number of animation frames to extact from the Sprite Sheet. The default value of -1 means "extract all frames". + * @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here. + * @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here. * @return {Phaser.FrameData} A FrameData object containing the parsed frames. */ - spriteSheet: function (game, key, frameWidth, frameHeight, frameMax) { + spriteSheet: function (game, key, frameWidth, frameHeight, frameMax, margin, spacing) { // How big is our image? var img = game.cache.getImage(key); @@ -63,8 +65,8 @@ Phaser.AnimationParser = { // Let's create some frames then var data = new Phaser.FrameData(); - var x = 0; - var y = 0; + var x = margin; + var y = margin; for (var i = 0; i < total; i++) { @@ -79,12 +81,12 @@ Phaser.AnimationParser = { height: frameHeight }); - x += frameWidth; + x += frameWidth + spacing; if (x === width) { - x = 0; - y += frameHeight; + x = margin; + y += frameHeight + spacing; } } diff --git a/src/animation/Frame.js b/src/animation/Frame.js index 60f1a2b0..c7cc3ff6 100644 --- a/src/animation/Frame.js +++ b/src/animation/Frame.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -158,3 +158,5 @@ Phaser.Frame.prototype = { } }; + +Phaser.Frame.prototype.constructor = Phaser.Frame; diff --git a/src/animation/FrameData.js b/src/animation/FrameData.js index 6588ac21..ab790fa0 100644 --- a/src/animation/FrameData.js +++ b/src/animation/FrameData.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -223,6 +223,8 @@ Phaser.FrameData.prototype = { }; +Phaser.FrameData.prototype.constructor = Phaser.FrameData; + /** * @name Phaser.FrameData#total * @property {number} total - The total number of frames in this FrameData set. diff --git a/src/core/Camera.js b/src/core/Camera.js index 151e51ac..8d9baa0e 100644 --- a/src/core/Camera.js +++ b/src/core/Camera.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -39,7 +39,7 @@ Phaser.Camera = function (game, id, x, y, width, height) { * Camera view. * The view into the world we wish to render (by default the game dimensions). * The x/y values are in world coordinates, not screen coordinates, the width/height is how many pixels to render. - * Objects outside of this view are not rendered (unless set to ignore the Camera, i.e. UI?). + * Objects outside of this view are not rendered if set to camera cull. * @property {Phaser.Rectangle} view */ this.view = new Phaser.Rectangle(x, y, width, height); @@ -86,6 +86,9 @@ Phaser.Camera = function (game, id, x, y, width, height) { */ this._edge = 0; + /** + * @property {PIXI.DisplayObject} displayObject - The display object to which all game objects are added. Set by World.boot + */ this.displayObject = null; }; @@ -203,6 +206,11 @@ Phaser.Camera.prototype = { }, + /** + * Internal method + * @method Phaser.Camera#updateTarget + * @private + */ updateTarget: function () { if (this.deadzone) @@ -242,9 +250,13 @@ Phaser.Camera.prototype = { }, + /** + * Update the Camera bounds to match the game world. + * @method Phaser.Camera#setBoundsToWorld + */ setBoundsToWorld: function () { - this.bounds.setTo(this.game.world.x, this.game.world.y, this.game.world.width, this.game.world.height); + this.bounds.setTo(this.game.world.bounds.x, this.game.world.bounds.y, this.game.world.bounds.width, this.game.world.bounds.height); }, @@ -264,10 +276,10 @@ Phaser.Camera.prototype = { this.view.x = this.bounds.x; } - if (this.view.x > this.bounds.right - this.width) + if (this.view.right > this.bounds.right) { this.atLimit.x = true; - this.view.x = (this.bounds.right - this.width) + 1; + this.view.x = this.bounds.right - this.width; } if (this.view.y < this.bounds.top) @@ -276,10 +288,10 @@ Phaser.Camera.prototype = { this.view.y = this.bounds.top; } - if (this.view.y > this.bounds.bottom - this.height) + if (this.view.bottom > this.bounds.bottom) { this.atLimit.y = true; - this.view.y = (this.bounds.bottom - this.height) + 1; + this.view.y = this.bounds.bottom - this.height; } this.view.floor(); @@ -322,6 +334,8 @@ Phaser.Camera.prototype = { }; +Phaser.Camera.prototype.constructor = Phaser.Camera; + /** * The Cameras x coordinate. This value is automatically clamped if it falls outside of the World bounds. * @name Phaser.Camera#x diff --git a/src/core/Filter.js b/src/core/Filter.js index 6088ba59..6bedd4e5 100644 --- a/src/core/Filter.js +++ b/src/core/Filter.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -124,6 +124,8 @@ Phaser.Filter.prototype = { }; +Phaser.Filter.prototype.constructor = Phaser.Filter; + /** * @name Phaser.Filter#width * @property {number} width - The width (resolution uniform) diff --git a/src/core/Game.js b/src/core/Game.js index d077209e..13466bc9 100644 --- a/src/core/Game.js +++ b/src/core/Game.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -17,64 +17,68 @@ * @param {number} [width=800] - The width of your game in game pixels. * @param {number} [height=600] - The height of your game in game pixels. * @param {number} [renderer=Phaser.AUTO] - Which renderer to use: Phaser.AUTO will auto-detect, Phaser.WEBGL, Phaser.CANVAS or Phaser.HEADLESS (no rendering at all). -* @param {HTMLElement} [parent=''] - The Games DOM parent. -* @param {any} [state=null] - Description. +* @param {string|HTMLElement} [parent=''] - The DOM element into which this games canvas will be injected. Either a DOM ID (string) or the element itself. +* @param {object} [state=null] - The default state object. A object consisting of Phaser.State functions (preload, create, update, render) or null. * @param {boolean} [transparent=false] - Use a transparent canvas background or not. * @param {boolean} [antialias=true] - Anti-alias graphics. */ Phaser.Game = function (width, height, renderer, parent, state, transparent, antialias) { - width = width || 800; - height = height || 600; - renderer = renderer || Phaser.AUTO; - parent = parent || ''; - state = state || null; - - if (typeof transparent == 'undefined') { transparent = false; } - if (typeof antialias == 'undefined') { antialias = true; } - /** * @property {number} id - Phaser Game ID (for when Pixi supports multiple instances). */ this.id = Phaser.GAMES.push(this) - 1; /** - * @property {HTMLElement} parent - The Games DOM parent. + * @property {object} config - The Phaser.Game configuration object. */ - this.parent = parent; + this.config = null; - // Do some more intelligent size parsing here, so they can set "100%" for example, maybe pass the scale mode in here too? + /** + * @property {HTMLElement} parent - The Games DOM parent. + * @default + */ + this.parent = ''; /** * @property {number} width - The Game width (in pixels). + * @default */ - this.width = width; + this.width = 800; /** * @property {number} height - The Game height (in pixels). + * @default */ - this.height = height; + this.height = 600; /** * @property {boolean} transparent - Use a transparent canvas background or not. + * @default */ - this.transparent = transparent; + this.transparent = false; /** * @property {boolean} antialias - Anti-alias graphics (in WebGL this helps with edges, in Canvas2D it retains pixel-art quality). + * @default */ - this.antialias = antialias; + this.antialias = true; /** * @property {number} renderer - The Pixi Renderer * @default */ - this.renderer = null; + this.renderer = Phaser.AUTO; + + /** + * @property {number} renderType - The Renderer this Phaser.Game will use. Either Phaser.RENDERER_AUTO, Phaser.RENDERER_CANVAS or Phaser.RENDERER_WEBGL. + */ + this.renderType = Phaser.AUTO; /** * @property {number} state - The StateManager. */ - this.state = new Phaser.StateManager(this, state); + this.state = null; /** * @property {boolean} _paused - Is game paused? @@ -83,11 +87,6 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant */ this._paused = false; - /** - * @property {number} renderType - The Renderer this Phaser.Game will use. Either Phaser.RENDERER_AUTO, Phaser.RENDERER_CANVAS or Phaser.RENDERER_WEBGL. - */ - this.renderType = renderer; - /** * @property {boolean} _loadComplete - Whether load complete loading or not. * @private @@ -227,6 +226,68 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant */ this.particles = null; + /** + * @property {boolean} stepping - Enable core loop stepping with Game.enableStep(). + * @default + * @readonly + */ + this.stepping = false; + + /** + * @property {boolean} stepping - An internal property used by enableStep, but also useful to query from your own game objects. + * @default + * @readonly + */ + this.pendingStep = false; + + /** + * @property {number} stepCount - When stepping is enabled this contains the current step cycle. + * @default + * @readonly + */ + this.stepCount = 0; + + // Parse the configuration object (if any) + if (arguments.length === 1 && typeof arguments[0] === 'object') + { + this.parseConfig(arguments[0]); + } + else + { + if (typeof width !== 'undefined') + { + this.width = width; + } + + if (typeof height !== 'undefined') + { + this.height = height; + } + + if (typeof renderer !== 'undefined') + { + this.renderer = renderer; + this.renderType = renderer; + } + + if (typeof parent !== 'undefined') + { + this.parent = parent; + } + + if (typeof transparent !== 'undefined') + { + this.transparent = transparent; + } + + if (typeof antialias !== 'undefined') + { + this.antialias = antialias; + } + + this.state = new Phaser.StateManager(this, state); + } + var _this = this; this._onBoot = function () { @@ -249,6 +310,99 @@ Phaser.Game = function (width, height, renderer, parent, state, transparent, ant Phaser.Game.prototype = { + /** + * Parses a Game configuration object. + * + * @method Phaser.Game#parseConfig + * @protected + */ + parseConfig: function (config) { + + this.config = config; + + if (config['width']) + { + this.width = this.parseDimension(config['width'], 0); + } + + if (config['height']) + { + this.height = this.parseDimension(config['height'], 1); + } + + if (config['renderer']) + { + this.renderer = config['renderer']; + this.renderType = config['renderer']; + } + + if (config['parent']) + { + this.parent = config['parent']; + } + + if (config['transparent']) + { + this.transparent = config['transparent']; + } + + if (config['antialias']) + { + this.antialias = config['antialias']; + } + + var state = null; + + if (config['state']) + { + state = config['state']; + } + + this.state = new Phaser.StateManager(this, state); + + }, + + /** + * Get dimension. + * + * @method Phaser.Game#parseDimension + * @protected + */ + parseDimension: function (size, dimension) { + + var f = 0; + var px = 0; + + if (typeof size === 'string') + { + // %? + if (size.substr(-1) === '%') + { + f = parseInt(size, 10) / 100; + + if (dimension === 0) + { + px = window.innerWidth * f; + } + else + { + px = window.innerHeight * f; + } + } + else + { + px = parseInt(size, 10); + } + } + else + { + px = size; + } + + return px; + + }, + /** * Initialize engine sub modules and start the game. * @@ -298,6 +452,7 @@ Phaser.Game.prototype = { this.net = new Phaser.Net(this); this.debug = new Phaser.Utils.Debug(this); + this.time.boot(); this.stage.boot(); this.world.boot(); this.input.boot(); @@ -372,6 +527,14 @@ Phaser.Game.prototype = { */ setUpRenderer: function () { + /* + if (this.device.trident) + { + // Pixi WebGL renderer on IE11 doesn't work correctly with masks, if you need them you may want to comment this block out + this.renderType = Phaser.CANVAS; + } + */ + if (this.renderType === Phaser.HEADLESS || this.renderType === Phaser.CANVAS || (this.renderType === Phaser.AUTO && this.device.webGL === false)) { if (this.device.canvas) @@ -438,20 +601,28 @@ Phaser.Game.prototype = { } else { - this.plugins.preUpdate(); - this.physics.preUpdate(); + if (!this.pendingStep) + { + if (this.stepping) + { + this.pendingStep = true; + } - this.stage.update(); - this.input.update(); - this.tweens.update(); - this.sound.update(); - this.world.update(); - this.particles.update(); - this.state.update(); - this.plugins.update(); + this.plugins.preUpdate(); + this.world.preUpdate(); - this.world.postUpdate(); - this.plugins.postUpdate(); + this.stage.update(); + this.tweens.update(); + this.sound.update(); + this.input.update(); + this.state.update(); + this.world.update(); + this.particles.update(); + this.plugins.update(); + + this.world.postUpdate(); + this.plugins.postUpdate(); + } if (this.renderType !== Phaser.HEADLESS) { @@ -461,11 +632,49 @@ Phaser.Game.prototype = { this.plugins.postRender(); } - } }, + /** + * Enable core game loop stepping. When enabled you must call game.step() directly (perhaps via a DOM button?) + * Calling step will advance the game loop by one frame. This is extremely useful to hard to track down errors! + * + * @method Phaser.Game#enableStep + */ + enableStep: function () { + + this.stepping = true; + this.pendingStep = false; + this.stepCount = 0; + + }, + + /** + * Disables core game loop stepping. + * + * @method Phaser.Game#disableStep + */ + disableStep: function () { + + this.stepping = false; + this.pendingStep = false; + + }, + + /** + * When stepping is enabled you must call this function directly (perhaps via a DOM button?) to advance the game loop by one frame. + * This is extremely useful to hard to track down errors! Use the internal stepCount property to monitor progress. + * + * @method Phaser.Game#step + */ + step: function () { + + this.pendingStep = false; + this.stepCount++; + + }, + /** * Nuke the entire game from orbit * @@ -493,6 +702,8 @@ Phaser.Game.prototype = { }; +Phaser.Game.prototype.constructor = Phaser.Game; + /** * The paused state of the Game. A paused game doesn't update any of its subsystems. * When a game is paused the onPause event is dispatched. When it is resumed the onResume event is dispatched. diff --git a/src/core/Group.js b/src/core/Group.js index d7bed67c..5fa52339 100644 --- a/src/core/Group.js +++ b/src/core/Group.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -10,32 +10,32 @@ * @classdesc A Group is a container for display objects that allows for fast pooling, recycling and collision checks. * @constructor * @param {Phaser.Game} game - A reference to the currently running game. -* @param {*} parent - The parent Group or DisplayObjectContainer that will hold this group, if any. +* @param {*} parent - The parent Group or DisplayObjectContainer that will hold this group, if any. If undefined it will use game.world. * @param {string} [name=group] - A name for this Group. Not used internally but useful for debugging. * @param {boolean} [useStage=false] - Should the DisplayObjectContainer this Group creates be added to the World (default, false) or direct to the Stage (true). */ Phaser.Group = function (game, parent, name, useStage) { - if (typeof parent === 'undefined' || typeof parent === null) + /** + * @property {Phaser.Game} game - A reference to the currently running Game. + */ + this.game = game; + + if (typeof parent === 'undefined') { parent = game.world; } + /** + * @property {string} name - A name for this Group. Not used internally but useful for debugging. + */ + this.name = name || 'group'; + if (typeof useStage === 'undefined') { useStage = false; } - /** - * @property {Phaser.Game} game - A reference to the currently running Game. - */ - this.game = game; - - /** - * @property {string} name - A name for this Group. Not used internally but useful for debugging. - */ - this.name = name || 'group'; - if (useStage) { this._container = this.game.stage._stage; @@ -50,7 +50,6 @@ Phaser.Group = function (game, parent, name, useStage) { if (parent instanceof Phaser.Group) { parent._container.addChild(this._container); - parent._container.updateTransform(); } else { @@ -71,6 +70,12 @@ Phaser.Group = function (game, parent, name, useStage) { */ this.type = Phaser.GROUP; + /** + * @property {boolean} alive - The alive property is useful for Groups that are children of other Groups and need to be included/excluded in checks like forEachAlive. + * @default + */ + this.alive = true; + /** * @property {boolean} exists - If exists is true the the Group is updated, otherwise it is skipped. * @default @@ -78,9 +83,22 @@ Phaser.Group = function (game, parent, name, useStage) { this.exists = true; /** - * @property {Phaser.Point} scale - Replaces the PIXI.Point with a slightly more flexible one. + * @property {Phaser.Group} group - The parent Group of this Group, if a child of another. */ - this.scale = new Phaser.Point(1, 1); + this.group = null; + + // Replaces the PIXI.Point with a slightly more flexible one. + this._container.scale = new Phaser.Point(1, 1); + + /** + * @property {Phaser.Point} scale - The scane of the Group container. + */ + this.scale = this._container.scale; + + /** + * @property {Phaser.Point} pivot - The pivot point of the Group container. + */ + this.pivot = this._container.pivot; /** * The cursor is a simple way to iterate through the objects in a Group using the Group.next and Group.previous functions. @@ -138,16 +156,27 @@ Phaser.Group.prototype = { if (child.group !== this) { - child.group = this; - - if (child.events) + if (child.type && child.type === Phaser.GROUP) { - child.events.onAddedToGroup.dispatch(child, this); + child.group = this; + + this._container.addChild(child._container); + + child._container.updateTransform(); } + else + { + child.group = this; - this._container.addChild(child); + this._container.addChild(child); - child.updateTransform(); + child.updateTransform(); + + if (child.events) + { + child.events.onAddedToGroup.dispatch(child, this); + } + } if (this.cursor === null) { @@ -172,16 +201,27 @@ Phaser.Group.prototype = { if (child.group !== this) { - child.group = this; - - if (child.events) + if (child.type && child.type === Phaser.GROUP) { - child.events.onAddedToGroup.dispatch(child, this); + child.group = this; + + this._container.addChildAt(child._container, index); + + child._container.updateTransform(); } + else + { + child.group = this; - this._container.addChildAt(child, index); + this._container.addChildAt(child, index); - child.updateTransform(); + child.updateTransform(); + + if (child.events) + { + child.events.onAddedToGroup.dispatch(child, this); + } + } if (this.cursor === null) { @@ -220,7 +260,7 @@ Phaser.Group.prototype = { */ create: function (x, y, key, frame, exists) { - if (typeof exists == 'undefined') { exists = true; } + if (typeof exists === 'undefined') { exists = true; } var child = new Phaser.Sprite(this.game, x, y, key, frame); @@ -229,15 +269,15 @@ Phaser.Group.prototype = { child.visible = exists; child.alive = exists; + this._container.addChild(child); + + child.updateTransform(); + if (child.events) { child.events.onAddedToGroup.dispatch(child, this); } - this._container.addChild(child); - - child.updateTransform(); - if (this.cursor === null) { this.cursor = child; @@ -260,7 +300,7 @@ Phaser.Group.prototype = { */ createMultiple: function (quantity, key, frame, exists) { - if (typeof exists == 'undefined') { exists = false; } + if (typeof exists === 'undefined') { exists = false; } for (var i = 0; i < quantity; i++) { @@ -271,14 +311,15 @@ Phaser.Group.prototype = { child.visible = exists; child.alive = exists; + this._container.addChild(child); + + child.updateTransform(); + if (child.events) { child.events.onAddedToGroup.dispatch(child, this); } - this._container.addChild(child); - child.updateTransform(); - if (this.cursor === null) { this.cursor = child; @@ -332,6 +373,11 @@ Phaser.Group.prototype = { }, + /** + * Internal test. + * + * @method Phaser.Group#childTest + */ childTest: function (prefix, child) { var s = prefix + ' next: '; @@ -360,13 +406,16 @@ Phaser.Group.prototype = { }, + /** + * Internal test. + * + * @method Phaser.Group#swapIndex + */ swapIndex: function (index1, index2) { var child1 = this.getAt(index1); var child2 = this.getAt(index2); - console.log('swapIndex ', index1, ' with ', index2); - this.swap(child1, child2); }, @@ -631,6 +680,32 @@ Phaser.Group.prototype = { }, + /** + * This function allows you to quickly set a property on a single child of this Group to a new value. + * The operation parameter controls how the new value is assigned to the property, from simple replacement to addition and multiplication. + * + * @method Phaser.Group#set + * @param {Phaser.Sprite} child - The child to set the property on. + * @param {string} key - The property, as a string, to be set. For example: 'body.velocity.x' + * @param {*} value - The value that will be set. + * @param {boolean} [checkAlive=false] - If set then the child will only be updated if alive=true. + * @param {boolean} [checkVisible=false] - If set then the child will only be updated if visible=true. + * @param {number} [operation=0] - Controls how the value is assigned. A value of 0 replaces the value with the new one. A value of 1 adds it, 2 subtracts it, 3 multiplies it and 4 divides it. + */ + set: function (child, key, value, checkAlive, checkVisible, operation) { + + key = key.split('.'); + + if (typeof checkAlive === 'undefined') { checkAlive = false; } + if (typeof checkVisible === 'undefined') { checkVisible = false; } + + if ((checkAlive === false || (checkAlive && child.alive)) && (checkVisible === false || (checkVisible && child.visible))) + { + this.setProperty(child, key, value, operation); + } + + }, + /** * This function allows you to quickly set the same property across all children of this Group to a new value. * The operation parameter controls how the new value is assigned to the property, from simple replacement to addition and multiplication. @@ -766,7 +841,7 @@ Phaser.Group.prototype = { }, /** - * Calls a function on all of the children that have exists=true in this Group. + * Returns a reference to a function that exists on a child of the Group based on the given callback array. * * @method Phaser.Group#callbackFromArray * @param {object} child - The object to inspect. @@ -824,7 +899,7 @@ Phaser.Group.prototype = { * * @method Phaser.Group#callAll * @param {string} method - A string containing the name of the function that will be called. The function must exist on the child. - * @param {string} [context=''] - A string containing the context under which the method will be executed. Leave to '' to default to the child. + * @param {string} [context=null] - A string containing the context under which the method will be executed. Set to null to default to the child. * @param {...*} parameter - Additional parameters that will be passed to the method. */ callAll: function (method, context) { @@ -891,6 +966,7 @@ Phaser.Group.prototype = { * Allows you to call your own function on each member of this Group. You must pass the callback and context in which it will run. * After the checkExists parameter you can add as many parameters as you like, which will all be passed to the callback along with the child. * For example: Group.forEach(awardBonusGold, this, true, 100, 500) + * Note: Currently this will skip any children which are Groups themselves. * * @method Phaser.Group#forEach * @param {function} callback - The function that will be called. Each child of the Group will be passed to it as its first parameter. @@ -1041,12 +1117,13 @@ Phaser.Group.prototype = { * @param {number} returnType - How to return the data from this method. Either Phaser.Group.RETURN_NONE, Phaser.Group.RETURN_TOTAL or Phaser.Group.RETURN_CHILD. * @param {function} [callback=null] - Optional function that will be called on each matching child. Each child of the Group will be passed to it as its first parameter. * @param {Object} [callbackContext] - The context in which the function should be called (usually 'this'). + * @return {any} Returns either a numeric total (if RETURN_TOTAL was specified) or the child object. */ iterate: function (key, value, returnType, callback, callbackContext, args) { - if (returnType == Phaser.Group.RETURN_TOTAL && this._container.children.length === 0) + if (returnType === Phaser.Group.RETURN_TOTAL && this._container.children.length === 0) { - return -1; + return 0; } if (typeof callback === 'undefined') @@ -1072,7 +1149,7 @@ Phaser.Group.prototype = { callback.apply(callbackContext, args); } - if (returnType == Phaser.Group.RETURN_CHILD) + if (returnType === Phaser.Group.RETURN_CHILD) { return currentNode; } @@ -1083,11 +1160,11 @@ Phaser.Group.prototype = { while (currentNode != this._container.last._iNext); } - if (returnType == Phaser.Group.RETURN_TOTAL) + if (returnType === Phaser.Group.RETURN_TOTAL) { return total; } - else if (returnType == Phaser.Group.RETURN_CHILD) + else if (returnType === Phaser.Group.RETURN_CHILD) { return null; } @@ -1142,7 +1219,7 @@ Phaser.Group.prototype = { * Call this function to find out how many members of the group are alive. * * @method Phaser.Group#countLiving - * @return {number} The number of children flagged as alive. Returns -1 if Group is empty. + * @return {number} The number of children flagged as alive. */ countLiving: function () { @@ -1154,7 +1231,7 @@ Phaser.Group.prototype = { * Call this function to find out how many members of the group are dead. * * @method Phaser.Group#countDead - * @return {number} The number of children flagged as dead. Returns -1 if Group is empty. + * @return {number} The number of children flagged as dead. */ countDead: function () { @@ -1298,11 +1375,31 @@ Phaser.Group.prototype = { * Destroys this Group. Removes all children, then removes the container from the display list and nulls references. * * @method Phaser.Group#destroy + * @param {boolean} [destroyChildren=false] - Should every child of this Group have its destroy method called? */ - destroy: function () { + destroy: function (destroyChildren) { - this.removeAll(); + if (typeof destroyChildren === 'undefined') { destroyChildren = false; } + if (destroyChildren) + { + if (this._container.children.length > 0) + { + do + { + if (this._container.children[0].group) + { + this._container.children[0].destroy(); + } + } + while (this._container.children.length > 0); + } + } + else + { + this.removeAll(); + } + this._container.parent.removeChild(this._container); this._container = null; @@ -1355,130 +1452,52 @@ Phaser.Group.prototype = { return true; - }, - - /** - * Dumps out a list of Group children and their index positions to the browser console. Useful for group debugging. - * - * @method Phaser.Group#dump - * @param {boolean} [full=false] - If full the dump will include the entire display list, start from the Stage. Otherwise it will only include this container. - */ - dump: function (full) { - - if (typeof full == 'undefined') - { - full = false; - } - - var spacing = 20; - var output = "\n" + Phaser.Utils.pad('Node', spacing) + "|" + Phaser.Utils.pad('Next', spacing) + "|" + Phaser.Utils.pad('Previous', spacing) + "|" + Phaser.Utils.pad('First', spacing) + "|" + Phaser.Utils.pad('Last', spacing); - - console.log(output); - - var output = Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing) + "|" + Phaser.Utils.pad('----------', spacing); - console.log(output); - - if (full) - { - var testObject = this.game.stage._stage.last._iNext; - var displayObject = this.game.stage._stage; - } - else - { - var testObject = this._container.last._iNext; - var displayObject = this._container; - } - - do - { - var name = displayObject.name || '*'; - - if (this.cursor == displayObject) - { - var name = '> ' + name; - } - - var nameNext = '-'; - var namePrev = '-'; - var nameFirst = '-'; - var nameLast = '-'; - - if (displayObject._iNext) - { - nameNext = displayObject._iNext.name; - } - - if (displayObject._iPrev) - { - namePrev = displayObject._iPrev.name; - } - - if (displayObject.first) - { - nameFirst = displayObject.first.name; - } - - if (displayObject.last) - { - nameLast = displayObject.last.name; - } - - if (typeof nameNext === 'undefined') - { - nameNext = '-'; - } - - if (typeof namePrev === 'undefined') - { - namePrev = '-'; - } - - if (typeof nameFirst === 'undefined') - { - nameFirst = '-'; - } - - if (typeof nameLast === 'undefined') - { - nameLast = '-'; - } - - var output = Phaser.Utils.pad(name, spacing) + "|" + Phaser.Utils.pad(nameNext, spacing) + "|" + Phaser.Utils.pad(namePrev, spacing) + "|" + Phaser.Utils.pad(nameFirst, spacing) + "|" + Phaser.Utils.pad(nameLast, spacing); - console.log(output); - - displayObject = displayObject._iNext; - - } - while(displayObject != testObject) - } }; +Phaser.Group.prototype.constructor = Phaser.Group; + /** * @name Phaser.Group#total -* @property {number} total - The total number of children in this Group, regardless of their alive state. +* @property {number} total - The total number of children in this Group who have a state of exists = true. * @readonly */ Object.defineProperty(Phaser.Group.prototype, "total", { get: function () { - return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL); - // return this._container.children.length; + + if (this._container) + { + return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL); + } + else + { + return 0; + } + } }); /** * @name Phaser.Group#length -* @property {number} length - The number of children in this Group. +* @property {number} length - The total number of children in this Group, regardless of their exists/alive status. * @readonly */ Object.defineProperty(Phaser.Group.prototype, "length", { get: function () { - return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL); - // return this._container.children.length; + + if (this._container) + { + return this._container.children.length; + } + else + { + return 0; + } + } }); diff --git a/src/core/LinkedList.js b/src/core/LinkedList.js index 42358592..fd2726c1 100644 --- a/src/core/LinkedList.js +++ b/src/core/LinkedList.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -151,4 +151,6 @@ Phaser.LinkedList.prototype = { } -}; \ No newline at end of file +}; + +Phaser.LinkedList.prototype.constructor = Phaser.LinkedList; diff --git a/src/core/Plugin.js b/src/core/Plugin.js index c54933fb..273f8214 100644 --- a/src/core/Plugin.js +++ b/src/core/Plugin.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -119,3 +119,5 @@ Phaser.Plugin.prototype = { } }; + +Phaser.Plugin.prototype.constructor = Phaser.Plugin; diff --git a/src/core/PluginManager.js b/src/core/PluginManager.js index 2e353890..0dd7538a 100644 --- a/src/core/PluginManager.js +++ b/src/core/PluginManager.js @@ -2,7 +2,7 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -295,3 +295,5 @@ Phaser.PluginManager.prototype = { } }; + +Phaser.PluginManager.prototype.constructor = Phaser.PluginManager; diff --git a/src/core/Signal.js b/src/core/Signal.js index 4caf87e7..2c874287 100644 --- a/src/core/Signal.js +++ b/src/core/Signal.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -300,3 +300,5 @@ Phaser.Signal.prototype = { } }; + +Phaser.Signal.prototype.constructor = Phaser.Signal; diff --git a/src/core/SignalBinding.js b/src/core/SignalBinding.js index cfad9546..8a0a5f7e 100644 --- a/src/core/SignalBinding.js +++ b/src/core/SignalBinding.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -160,3 +160,5 @@ Phaser.SignalBinding.prototype = { } }; + +Phaser.SignalBinding.prototype.constructor = Phaser.SignalBinding; diff --git a/src/core/Stage.js b/src/core/Stage.js index 12b053a2..e766fe6b 100644 --- a/src/core/Stage.js +++ b/src/core/Stage.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -24,7 +24,6 @@ Phaser.Stage = function (game, width, height) { /** * @property {string} game - Background color of the stage (defaults to black). Set via the public backgroundColor property. * @private - * @default 'rgb(0,0,0)' */ this._backgroundColor = 'rgb(0,0,0)'; @@ -34,10 +33,9 @@ Phaser.Stage = function (game, width, height) { this.offset = new Phaser.Point(); /** - * @property {HTMLCanvasElement} canvas - Reference to the newly created <canvas> element. + * @property {HTMLCanvasElement} canvas - Reference to the newly created `canvas` element. */ - this.canvas = Phaser.Canvas.create(width, height); - this.canvas.style['-webkit-full-screen'] = 'width: 100%; height: 100%'; + this.canvas = null; /** * @property {PIXI.Stage} _stage - The Pixi Stage which is hooked to the renderer. @@ -47,11 +45,21 @@ Phaser.Stage = function (game, width, height) { this._stage.name = '_stage_root'; this._stage.interactive = false; + /** + * @property {PIXI.Stage} display - The Pixi Stage which is hooked to the renderer. + */ + this.display = this._stage; + /** * @property {number} scaleMode - The current scaleMode. */ this.scaleMode = Phaser.StageScaleMode.NO_SCALE; + /* + * @property {number} fullScreenScaleMode - Scale mode to be used in fullScreen + */ + this.fullScreenScaleMode = Phaser.StageScaleMode.NO_SCALE; + /** * @property {Phaser.StageScaleMode} scale - The scale of the current running game. */ @@ -62,6 +70,12 @@ Phaser.Stage = function (game, width, height) { */ this.aspectRatio = width / height; + /** + * @property {boolean} disableVisibilityChange - By default if the browser tab loses focus the game will pause. You can stop that behaviour by setting this property to true. + * @default + */ + this.disableVisibilityChange = false; + /** * @property {number} _nextOffsetCheck - The time to run the next offset check. * @private @@ -74,10 +88,73 @@ Phaser.Stage = function (game, width, height) { */ this.checkOffsetInterval = 2500; + if (game.config) + { + this.parseConfig(game.config); + } + else + { + this.canvas = Phaser.Canvas.create(width, height); + this.canvas.style['-webkit-full-screen'] = 'width: 100%; height: 100%'; + } + }; Phaser.Stage.prototype = { + /** + * Parses a Game configuration object. + * + * @method Phaser.Stage#parseConfig + * @protected + */ + parseConfig: function (config) { + + if (config['canvasID']) + { + this.canvas = Phaser.Canvas.create(this.game.width, this.game.height, config['canvasID']); + } + else + { + this.canvas = Phaser.Canvas.create(this.game.width, this.game.height); + } + + if (config['canvasStyle']) + { + this.canvas.stlye = config['canvasStyle']; + } + else + { + this.canvas.style['-webkit-full-screen'] = 'width: 100%; height: 100%'; + } + + if (config['checkOffsetInterval']) + { + this.checkOffsetInterval = config['checkOffsetInterval']; + } + + if (config['disableVisibilityChange']) + { + this.disableVisibilityChange = config['disableVisibilityChange']; + } + + if (config['fullScreenScaleMode']) + { + this.fullScreenScaleMode = config['fullScreenScaleMode']; + } + + if (config['scaleMode']) + { + this.scaleMode = config['scaleMode']; + } + + if (config['backgroundColor']) + { + this.backgroundColor = config['backgroundColor']; + } + + }, + /** * Initialises the stage and adds the event listeners. * @method Phaser.Stage#boot @@ -140,7 +217,7 @@ Phaser.Stage.prototype = { return; } - if (event.type == 'pagehide' || event.type == 'blur' || document['hidden'] === true || document['webkitHidden'] === true) + if (this.game.paused === false && (event.type == 'pagehide' || event.type == 'blur' || document['hidden'] === true || document['webkitHidden'] === true)) { this.game.paused = true; } @@ -153,6 +230,8 @@ Phaser.Stage.prototype = { }; +Phaser.Stage.prototype.constructor = Phaser.Stage; + /** * @name Phaser.Stage#backgroundColor * @property {number|string} backgroundColor - Gets and sets the background color of the stage. The color can be given as a number: 0xff0000 or a hex string: '#ff0000' diff --git a/src/core/State.js b/src/core/State.js index 38a99f21..1a624167 100644 --- a/src/core/State.js +++ b/src/core/State.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -167,3 +167,5 @@ Phaser.State.prototype = { } }; + +Phaser.State.prototype.constructor = Phaser.State; diff --git a/src/core/StateManager.js b/src/core/StateManager.js index ef61ed26..00f70d1a 100644 --- a/src/core/StateManager.js +++ b/src/core/StateManager.js @@ -2,7 +2,7 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -32,7 +32,7 @@ Phaser.StateManager = function (game, pendingState) { */ this._pendingState = null; - if (pendingState !== null) + if (typeof pendingState !== 'undefined' && pendingState !== null) { this._pendingState = pendingState; } @@ -280,7 +280,8 @@ Phaser.StateManager.prototype = { }, /** - * Description. + * Checks i a given phaser state is valid. + * State must exist and have at least one callback function registered.. * @method Phaser.StateManager#checkState * @param {string} key - The key of the state you want to check. * @return {boolean} Description. @@ -347,7 +348,7 @@ Phaser.StateManager.prototype = { * Sets the current State. Should not be called directly (use StateManager.start) * @method Phaser.StateManager#setCurrentState * @param {string} key - State key. - * @protected + * @private */ setCurrentState: function (key) { @@ -377,6 +378,17 @@ Phaser.StateManager.prototype = { }, + /** + * Gets the current State. + * + * @method Phaser.StateManager#getCurrentState + * @return Phaser.State + * @public + */ + getCurrentState: function() { + return this.states[this.current]; + }, + /** * @method Phaser.StateManager#loadComplete * @protected @@ -512,3 +524,5 @@ Phaser.StateManager.prototype = { } }; + +Phaser.StateManager.prototype.constructor = Phaser.StateManager; diff --git a/src/core/World.js b/src/core/World.js index 61114e23..0bb15ddd 100644 --- a/src/core/World.js +++ b/src/core/World.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -12,6 +12,7 @@ * the world at world-based coordinates. By default a world is created the same size as your Stage. * * @class Phaser.World +* @extends Phaser.Group * @constructor * @param {Phaser.Game} game - Reference to the current game instance. */ @@ -19,11 +20,6 @@ Phaser.World = function (game) { Phaser.Group.call(this, game, null, '__world', false); - /** - * @property {Phaser.Point} scale - Replaces the PIXI.Point with a slightly more flexible one. - */ - this.scale = new Phaser.Point(1, 1); - /** * The World has no fixed size, but it does have a bounds outside of which objects are no longer considered as being "in world" and you should use this to clean-up the display list and purge dead objects. * By default we set the Bounds to be from 0,0 to Game.width,Game.height. I.e. it will match the size given to the game constructor with 0,0 representing the top-left of the display. @@ -65,34 +61,21 @@ Phaser.World.prototype.boot = function () { } /** -* This is called automatically every frame, and is where main logic happens. +* This is called automatically after the plugins preUpdate and before the State.update. +* Most objects have preUpdate methods and it's where initial movement, drawing and calculations are done. * * @method Phaser.World#update */ -Phaser.World.prototype.update = function () { - - this.currentRenderOrderID = 0; +Phaser.World.prototype.preUpdate = function () { if (this.game.stage._stage.first._iNext) { var currentNode = this.game.stage._stage.first._iNext; - var skipChildren; do { - skipChildren = false; - - if (currentNode['preUpdate']) - { - skipChildren = (currentNode.preUpdate() === false); - } - - if (currentNode['update']) - { - skipChildren = (currentNode.update() === false) || skipChildren; - } - - if (skipChildren) + // If preUpdate exists, and it returns false, skip PIXI child objects + if (currentNode['preUpdate'] && !currentNode.preUpdate()) { currentNode = currentNode.last._iNext; } @@ -108,48 +91,123 @@ Phaser.World.prototype.update = function () { } /** -* This is called automatically every frame, and is where main logic happens. -* @method Phaser.World#postUpdate +* This is called automatically after the State.update, but before particles or plugins update. +* Most objects won't have an update method set unless explicitly given one. +* +* @method Phaser.World#update */ -Phaser.World.prototype.postUpdate = function () { +Phaser.World.prototype.update = function () { + this.currentRenderOrderID = 0; + if (this.game.stage._stage.first._iNext) { var currentNode = this.game.stage._stage.first._iNext; do { - if (currentNode['postUpdate']) + // If update exists, and it returns false, skip PIXI child objects + if (currentNode['update'] && !currentNode.update()) { - currentNode.postUpdate(); + currentNode = currentNode.last._iNext; + } + else + { + currentNode = currentNode._iNext; } - currentNode = currentNode._iNext; } while (currentNode != this.game.stage._stage.last._iNext) } - this.camera.update(); +} + +/** +* This is called automatically before the renderer runs and after the plugins have updated. +* In postUpdate this is where all the final physics calculatations and object positioning happens. +* The objects are processed in the order of the display list. +* The only exception to this is if the camera is following an object, in which case that is updated first. +* +* @method Phaser.World#postUpdate +*/ +Phaser.World.prototype.postUpdate = function () { + + if (this.camera.target && this.camera.target['postUpdate']) + { + this.camera.target.postUpdate(); + + this.camera.update(); + + if (this.game.stage._stage.first._iNext) + { + var currentNode = this.game.stage._stage.first._iNext; + + do + { + if (currentNode['postUpdate'] && currentNode !== this.camera.target) + { + currentNode.postUpdate(); + } + + currentNode = currentNode._iNext; + } + while (currentNode != this.game.stage._stage.last._iNext) + } + } + else + { + this.camera.update(); + + if (this.game.stage._stage.first._iNext) + { + var currentNode = this.game.stage._stage.first._iNext; + + do + { + if (currentNode['postUpdate']) + { + currentNode.postUpdate(); + } + + currentNode = currentNode._iNext; + } + while (currentNode != this.game.stage._stage.last._iNext) + } + } + } /** * Updates the size of this world. Note that this doesn't modify the world x/y coordinates, just the width and height. -* If you need to adjust the bounds of the world +* * @method Phaser.World#setBounds * @param {number} x - Top left most corner of the world. * @param {number} y - Top left most corner of the world. -* @param {number} width - New width of the world. -* @param {number} height - New height of the world. +* @param {number} width - New width of the world. Can never be smaller than the Game.width. +* @param {number} height - New height of the world. Can never be smaller than the Game.height. */ Phaser.World.prototype.setBounds = function (x, y, width, height) { + if (width < this.game.width) + { + width = this.game.width; + } + + if (height < this.game.height) + { + height = this.game.height; + } + this.bounds.setTo(x, y, width, height); if (this.camera.bounds) { + // The Camera can never be smaller than the game size this.camera.bounds.setTo(x, y, width, height); } + this.game.physics.setBoundsToWorld(); + } /** diff --git a/src/gameobjects/BitmapData.js b/src/gameobjects/BitmapData.js index 1fb08158..ec0c678f 100644 --- a/src/gameobjects/BitmapData.js +++ b/src/gameobjects/BitmapData.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -957,7 +957,9 @@ Phaser.BitmapData.prototype = { } -} +}; + +Phaser.BitmapData.prototype.constructor = Phaser.BitmapData; // EaselJS Tiny API emulation diff --git a/src/gameobjects/BitmapText.js b/src/gameobjects/BitmapText.js index 2ccece4b..2bab27f2 100644 --- a/src/gameobjects/BitmapText.js +++ b/src/gameobjects/BitmapText.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -120,11 +120,6 @@ Phaser.BitmapText = function (game, x, y, text, style) { this._cache.x = this.x; this._cache.y = this.y; - /** - * @property {boolean} renderable - A renderable object will be rendered to the context each frame. - */ - this.renderable = true; - }; Phaser.BitmapText.prototype = Object.create(PIXI.BitmapText.prototype); @@ -153,8 +148,8 @@ Phaser.BitmapText.prototype.update = function() { this._cache.dirty = true; } - this.pivot.x = this.anchor.x*this.width; - this.pivot.y = this.anchor.y*this.height; + this.pivot.x = this.anchor.x * this.width; + this.pivot.y = this.anchor.y * this.height; } diff --git a/src/gameobjects/Button.js b/src/gameobjects/Button.js index bdbad2ab..ad153e26 100644 --- a/src/gameobjects/Button.js +++ b/src/gameobjects/Button.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -19,16 +19,17 @@ * @constructor * * @param {Phaser.Game} game Current game instance. -* @param {number} [x] - X position of the Button. -* @param {number} [y] - Y position of the Button. +* @param {number} [x=0] - X position of the Button. +* @param {number} [y=0] - Y position of the Button. * @param {string} [key] - The image key as defined in the Game.Cache to use as the texture for this Button. * @param {function} [callback] - The function to call when this Button is pressed. * @param {object} [callbackContext] - The context in which the callback will be called (usually 'this'). * @param {string|number} [overFrame] - This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name. * @param {string|number} [outFrame] - This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name. * @param {string|number} [downFrame] - This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name. +* @param {string|number} [upFrame] - This is the frame or frameName that will be set when this button is in an up state. Give either a number to use a frame ID or a string for a frame name. */ -Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame) { +Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame, upFrame) { x = x || 0; y = y || 0; @@ -63,7 +64,7 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, * @default */ this._onDownFrameName = null; - + /** * @property {string} _onUpFrameName - Internal variable. * @private @@ -91,7 +92,7 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, * @default */ this._onDownFrameID = null; - + /** * @property {number} _onUpFrameID - Internal variable. * @private @@ -173,13 +174,13 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame, this.freezeFrames = false; /** - * When the Button is clicked you can optionally force the state to "out". + * When the Button is touched / clicked and then released you can force it to enter a state of "out" instead of "up". * @property {boolean} forceOut * @default */ - this.forceOut = true; + this.forceOut = false; - this.setFrames(overFrame, outFrame, downFrame); + this.setFrames(overFrame, outFrame, downFrame, upFrame); if (callback !== null) { @@ -201,15 +202,38 @@ Phaser.Button.prototype = Phaser.Utils.extend(true, Phaser.Button.prototype, Pha Phaser.Button.prototype.constructor = Phaser.Button; /** -* Used to manually set the frames that will be used for the different states of the button -* exactly like setting them in the constructor. +* Clears all of the frames set on this Button. +* +* @method Phaser.Button.prototype.clearFrames +*/ +Phaser.Button.prototype.clearFrames = function () { + + this._onOverFrameName = null; + this._onOverFrameID = null; + + this._onOutFrameName = null; + this._onOutFrameID = null; + + this._onDownFrameName = null; + this._onDownFrameID = null; + + this._onUpFrameName = null; + this._onUpFrameID = null; + +} + +/** +* Used to manually set the frames that will be used for the different states of the Button. * * @method Phaser.Button.prototype.setFrames * @param {string|number} [overFrame] - This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name. * @param {string|number} [outFrame] - This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name. * @param {string|number} [downFrame] - This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name. +* @param {string|number} [upFrame] - This is the frame or frameName that will be set when this button is in an up state. Give either a number to use a frame ID or a string for a frame name. */ -Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) { +Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame, upFrame) { + + this.clearFrames(); if (overFrame !== null) { @@ -238,7 +262,6 @@ Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) { if (typeof outFrame === 'string') { this._onOutFrameName = outFrame; - this._onUpFrameName = outFrame; if (this.input.pointerOver() === false) { @@ -248,7 +271,6 @@ Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) { else { this._onOutFrameID = outFrame; - this._onUpFrameID = outFrame; if (this.input.pointerOver() === false) { @@ -279,6 +301,28 @@ Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) { } } + if (upFrame !== null) + { + if (typeof upFrame === 'string') + { + this._onUpFrameName = upFrame; + + if (this.input.pointerUp()) + { + this.frameName = upFrame; + } + } + else + { + this._onUpFrameID = upFrame; + + if (this.input.pointerUp()) + { + this.frame = upFrame; + } + } + } + }; /** @@ -300,8 +344,8 @@ Phaser.Button.prototype.setSounds = function (overSound, overMarker, downSound, this.setOverSound(overSound, overMarker); this.setOutSound(outSound, outMarker); - this.setUpSound(upSound, upMarker); this.setDownSound(downSound, downMarker); + this.setUpSound(upSound, upMarker); } @@ -354,31 +398,7 @@ Phaser.Button.prototype.setOutSound = function (sound, marker) { } /** -* The Sound to be played when a Pointer clicks on this Button. -* -* @method Phaser.Button.prototype.setUpSound -* @param {Phaser.Sound} sound - The Sound that will be played. -* @param {string} [marker] - A Sound Marker that will be used in the playback. -*/ -Phaser.Button.prototype.setUpSound = function (sound, marker) { - - this.onUpSound = null; - this.onUpSoundMarker = ''; - - if (sound instanceof Phaser.Sound) - { - this.onUpSound = sound; - } - - if (typeof marker === 'string') - { - this.onUpSoundMarker = marker; - } - -} - -/** -* The Sound to be played when a Pointer clicks on this Button. +* The Sound to be played when a Pointer presses down on this Button. * * @method Phaser.Button.prototype.setDownSound * @param {Phaser.Sound} sound - The Sound that will be played. @@ -401,25 +421,43 @@ Phaser.Button.prototype.setDownSound = function (sound, marker) { } +/** +* The Sound to be played when a Pointer has pressed down and is released from this Button. +* +* @method Phaser.Button.prototype.setUpSound +* @param {Phaser.Sound} sound - The Sound that will be played. +* @param {string} [marker] - A Sound Marker that will be used in the playback. +*/ +Phaser.Button.prototype.setUpSound = function (sound, marker) { + + this.onUpSound = null; + this.onUpSoundMarker = ''; + + if (sound instanceof Phaser.Sound) + { + this.onUpSound = sound; + } + + if (typeof marker === 'string') + { + this.onUpSoundMarker = marker; + } + +} + /** * Internal function that handles input events. * * @protected * @method Phaser.Button.prototype.onInputOverHandler +* @param {Phaser.Button} sprite - The Button that the event occured on. * @param {Phaser.Pointer} pointer - The Pointer that activated the Button. */ -Phaser.Button.prototype.onInputOverHandler = function (pointer) { +Phaser.Button.prototype.onInputOverHandler = function (sprite, pointer) { if (this.freezeFrames === false) { - if (this._onOverFrameName != null) - { - this.frameName = this._onOverFrameName; - } - else if (this._onOverFrameID != null) - { - this.frame = this._onOverFrameID; - } + this.setState(1); } if (this.onOverSound) @@ -438,20 +476,14 @@ Phaser.Button.prototype.onInputOverHandler = function (pointer) { * * @protected * @method Phaser.Button.prototype.onInputOverHandler +* @param {Phaser.Button} sprite - The Button that the event occured on. * @param {Phaser.Pointer} pointer - The Pointer that activated the Button. */ -Phaser.Button.prototype.onInputOutHandler = function (pointer) { +Phaser.Button.prototype.onInputOutHandler = function (sprite, pointer) { if (this.freezeFrames === false) { - if (this._onOutFrameName != null) - { - this.frameName = this._onOutFrameName; - } - else if (this._onOutFrameID != null) - { - this.frame = this._onOutFrameID; - } + this.setState(2); } if (this.onOutSound) @@ -470,20 +502,14 @@ Phaser.Button.prototype.onInputOutHandler = function (pointer) { * * @protected * @method Phaser.Button.prototype.onInputOverHandler +* @param {Phaser.Button} sprite - The Button that the event occured on. * @param {Phaser.Pointer} pointer - The Pointer that activated the Button. */ -Phaser.Button.prototype.onInputDownHandler = function (pointer) { +Phaser.Button.prototype.onInputDownHandler = function (sprite, pointer) { if (this.freezeFrames === false) { - if (this._onDownFrameName != null) - { - this.frameName = this._onDownFrameName; - } - else if (this._onDownFrameID != null) - { - this.frame = this._onDownFrameID; - } + this.setState(3); } if (this.onDownSound) @@ -502,12 +528,100 @@ Phaser.Button.prototype.onInputDownHandler = function (pointer) { * * @protected * @method Phaser.Button.prototype.onInputOverHandler +* @param {Phaser.Button} sprite - The Button that the event occured on. * @param {Phaser.Pointer} pointer - The Pointer that activated the Button. */ -Phaser.Button.prototype.onInputUpHandler = function (pointer) { +Phaser.Button.prototype.onInputUpHandler = function (sprite, pointer, isOver) { - if (this.freezeFrames === false) + if (this.onUpSound) { + this.onUpSound.play(this.onUpSoundMarker); + } + + if (this.onInputUp) + { + this.onInputUp.dispatch(this, pointer, isOver); + } + + if (this.freezeFrames) + { + return; + } + + if (this.forceOut) + { + // Button should be forced to the Out frame when released. + this.setState(2); + } + else + { + if (this._onUpFrameName || this._onUpFrameID) + { + this.setState(4); + } + else + { + if (isOver) + { + this.setState(1); + } + else + { + this.setState(2); + } + } + } + +}; + +/** +* Internal function that handles Button state changes. +* +* @protected +* @method Phaser.Button.prototype.setState +* @param {number} newState - The new State of the Button. +*/ +Phaser.Button.prototype.setState = function (newState) { + + if (newState === 1) + { + // Over + if (this._onOverFrameName != null) + { + this.frameName = this._onOverFrameName; + } + else if (this._onOverFrameID != null) + { + this.frame = this._onOverFrameID; + } + } + else if (newState === 2) + { + // Out + if (this._onOutFrameName != null) + { + this.frameName = this._onOutFrameName; + } + else if (this._onOutFrameID != null) + { + this.frame = this._onOutFrameID; + } + } + else if (newState === 3) + { + // Down + if (this._onDownFrameName != null) + { + this.frameName = this._onDownFrameName; + } + else if (this._onDownFrameID != null) + { + this.frame = this._onDownFrameID; + } + } + else if (newState === 4) + { + // Up if (this._onUpFrameName != null) { this.frameName = this._onUpFrameName; @@ -518,26 +632,4 @@ Phaser.Button.prototype.onInputUpHandler = function (pointer) { } } - if (this.onUpSound) - { - this.onUpSound.play(this.onUpSoundMarker); - } - - if (this.forceOut && this.freezeFrames === false) - { - if (this._onOutFrameName != null) - { - this.frameName = this._onOutFrameName; - } - else if (this._onOutFrameID != null) - { - this.frame = this._onOutFrameID; - } - } - - if (this.onInputUp) - { - this.onInputUp.dispatch(this, pointer); - } - }; diff --git a/src/gameobjects/DOMSprite.js b/src/gameobjects/DOMSprite.js new file mode 100644 index 00000000..1ec45e2f --- /dev/null +++ b/src/gameobjects/DOMSprite.js @@ -0,0 +1,88 @@ +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* Create a new DOMSprite. +* @class Phaser.DOMSprite +* @constructor +* @param {Phaser.Game} game - Current game instance. +* @param {string} id - DOM ID. +* @param {number} x - X position of the new text object. +* @param {number} y - Y position of the new text object. +* @param {string} text - The actual text that will be written. +* @param {object} style - The style object containing style attributes like font, font size , +*/ +Phaser.DOMSprite = function (game, element, x, y, style) { + + x = x || 0; + y = y || 0; + style = style || ''; + + /** + * @property {Phaser.Game} game - A reference to the currently running Game. + */ + this.game = game; + + /** + * @property {boolean} exists - If exists = false then the Text isn't updated by the core game loop. + * @default + */ + this.exists = true; + + /** + * @property {boolean} alive - This is a handy little var your game can use to determine if an object is alive or not, it doesn't effect rendering. + * @default + */ + this.alive = true; + + /** + * @property {Phaser.Group} group - The parent Group of this Text object. + */ + this.group = null; + + /** + * @property {string} name - The user defined name given to this object. + * @default + */ + this.name = ''; + + /** + * @property {number} type - The const type of this object. + * @default + */ + this.type = Phaser.DOMSPRITE; + + /** + * @property {boolean} visible - Sets the visible state of this DOMSprite. + * @default + */ + this.visible = true; + + /* + if (parent) + { + if (typeof parent === 'string') + { + // hopefully an element ID + target = document.getElementById(parent); + } + else if (typeof parent === 'object' && parent.nodeType === 1) + { + // quick test for a HTMLelement + target = parent; + } + + if (overflowHidden) + { + target.style.overflow = 'hidden'; + } + } + */ + +}; + +// Phaser.DOMSprite.prototype = Object.create(PIXI.DOMSprite.prototype); +// Phaser.DOMSprite.prototype.constructor = Phaser.DOMSprite; diff --git a/src/gameobjects/Events.js b/src/gameobjects/Events.js index 44c10956..e3521491 100644 --- a/src/gameobjects/Events.js +++ b/src/gameobjects/Events.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -24,6 +24,7 @@ Phaser.Events = function (sprite) { this.parent = sprite; + this.onAddedToGroup = new Phaser.Signal(); this.onRemovedFromGroup = new Phaser.Signal(); this.onKilled = new Phaser.Signal(); @@ -41,6 +42,9 @@ Phaser.Events = function (sprite) { this.onAnimationComplete = null; this.onAnimationLoop = null; + this.onBeginContact = null; + this.onEndContact = null; + }; Phaser.Events.prototype = { @@ -73,4 +77,6 @@ Phaser.Events.prototype = { } -}; \ No newline at end of file +}; + +Phaser.Events.prototype.constructor = Phaser.Events; diff --git a/src/gameobjects/GameObjectFactory.js b/src/gameobjects/GameObjectFactory.js index 872b89ff..485f0087 100644 --- a/src/gameobjects/GameObjectFactory.js +++ b/src/gameobjects/GameObjectFactory.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -47,15 +47,19 @@ Phaser.GameObjectFactory.prototype = { * @param {number} y - Y position of the new sprite. * @param {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture. * @param {string|number} [frame] - If the sprite uses an image from a texture atlas or sprite sheet you can pass the frame here. Either a number for a frame ID or a string for a frame name. + * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. * @returns {Phaser.Sprite} the newly created sprite object. */ - sprite: function (x, y, key, frame) { + sprite: function (x, y, key, frame, group) { - return this.world.create(x, y, key, frame); + if (typeof group === 'undefined') { group = this.world; } + + return group.create(x, y, key, frame); }, /** + * DEPRECATED - will be removed in Phaser 1.2 * Create a new Sprite with specific position and sprite sheet key that will automatically be added as a child of the given parent. * * @method Phaser.GameObjectFactory#child @@ -89,8 +93,8 @@ Phaser.GameObjectFactory.prototype = { * A Group is a container for display objects that allows for fast pooling, recycling and collision checks. * * @method Phaser.GameObjectFactory#group - * @param {*} parent - The parent Group or DisplayObjectContainer that will hold this group, if any. - * @param {string} [name=group] - A name for this Group. Not used internally but useful for debugging. + * @param {any} parent - The parent Group or DisplayObjectContainer that will hold this group, if any. + * @param {string} [name='group'] - A name for this Group. Not used internally but useful for debugging. * @return {Phaser.Group} The newly created group. */ group: function (parent, name) { @@ -100,7 +104,7 @@ Phaser.GameObjectFactory.prototype = { }, /** - * Creates a new instance of the Sound class. + * Creates a new Sound object. * * @method Phaser.GameObjectFactory#audio * @param {string} key - The Game.cache key of the sound that this object will use. @@ -116,7 +120,23 @@ Phaser.GameObjectFactory.prototype = { }, /** - * Creates a new TileSprite. + * Creates a new Sound object. + * + * @method Phaser.GameObjectFactory#sound + * @param {string} key - The Game.cache key of the sound that this object will use. + * @param {number} [volume=1] - The volume at which the sound will be played. + * @param {boolean} [loop=false] - Whether or not the sound will loop. + * @param {boolean} [connect=true] - Controls if the created Sound object will connect to the master gainNode of the SoundManager when running under WebAudio. + * @return {Phaser.Sound} The newly created text object. + */ + sound: function (key, volume, loop, connect) { + + return this.game.sound.add(key, volume, loop, connect); + + }, + + /** + * Creates a new TileSprite object. * * @method Phaser.GameObjectFactory#tileSprite * @param {number} x - X position of the new tileSprite. @@ -124,33 +144,38 @@ Phaser.GameObjectFactory.prototype = { * @param {number} width - the width of the tilesprite. * @param {number} height - the height of the tilesprite. * @param {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture. - * @param {string|number} frame - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index. + * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. * @return {Phaser.TileSprite} The newly created tileSprite object. */ - tileSprite: function (x, y, width, height, key, frame) { + tileSprite: function (x, y, width, height, key, group) { - return this.world.add(new Phaser.TileSprite(this.game, x, y, width, height, key, frame)); + if (typeof group === 'undefined') { group = this.world; } + + return group.add(new Phaser.TileSprite(this.game, x, y, width, height, key)); }, /** - * Creates a new Text. + * Creates a new Text object. * * @method Phaser.GameObjectFactory#text * @param {number} x - X position of the new text object. * @param {number} y - Y position of the new text object. * @param {string} text - The actual text that will be written. * @param {object} style - The style object containing style attributes like font, font size , etc. + * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. * @return {Phaser.Text} The newly created text object. */ - text: function (x, y, text, style) { + text: function (x, y, text, style, group) { - return this.world.add(new Phaser.Text(this.game, x, y, text, style)); + if (typeof group === 'undefined') { group = this.world; } + + return group.add(new Phaser.Text(this.game, x, y, text, style)); }, /** - * Creates a new Button object. + * Creates a new Button object. * * @method Phaser.GameObjectFactory#button * @param {number} [x] X position of the new button object. @@ -161,25 +186,32 @@ Phaser.GameObjectFactory.prototype = { * @param {string|number} [overFrame] This is the frame or frameName that will be set when this button is in an over state. Give either a number to use a frame ID or a string for a frame name. * @param {string|number} [outFrame] This is the frame or frameName that will be set when this button is in an out state. Give either a number to use a frame ID or a string for a frame name. * @param {string|number} [downFrame] This is the frame or frameName that will be set when this button is in a down state. Give either a number to use a frame ID or a string for a frame name. + * @param {string|number} [upFrame] This is the frame or frameName that will be set when this button is in an up state. Give either a number to use a frame ID or a string for a frame name. + * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. * @return {Phaser.Button} The newly created button object. */ - button: function (x, y, key, callback, callbackContext, overFrame, outFrame, downFrame) { + button: function (x, y, key, callback, callbackContext, overFrame, outFrame, downFrame, upFrame, group) { - return this.world.add(new Phaser.Button(this.game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame)); + if (typeof group === 'undefined') { group = this.world; } + + return group.add(new Phaser.Button(this.game, x, y, key, callback, callbackContext, overFrame, outFrame, downFrame, upFrame)); }, /** - * Creates a new Graphics object. + * Creates a new Graphics object. * * @method Phaser.GameObjectFactory#graphics * @param {number} x - X position of the new graphics object. * @param {number} y - Y position of the new graphics object. + * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. * @return {Phaser.Graphics} The newly created graphics object. */ - graphics: function (x, y) { + graphics: function (x, y, group) { - return this.world.add(new Phaser.Graphics(this.game, x, y)); + if (typeof group === 'undefined') { group = this.world; } + + return group.add(new Phaser.Graphics(this.game, x, y)); }, @@ -201,16 +233,19 @@ Phaser.GameObjectFactory.prototype = { }, /** - * * Create a new BitmapText. + * * Create a new BitmapText object. * * @method Phaser.GameObjectFactory#bitmapText * @param {number} x - X position of the new bitmapText object. * @param {number} y - Y position of the new bitmapText object. * @param {string} text - The actual text that will be written. * @param {object} style - The style object containing style attributes like font, font size , etc. + * @param {Phaser.Group} [group] - Optional Group to add the object to. If not specified it will be added to the World group. * @return {Phaser.BitmapText} The newly created bitmapText object. */ - bitmapText: function (x, y, text, style) { + bitmapText: function (x, y, text, style, group) { + + if (typeof group === 'undefined') { group = this.world; } return this.world.add(new Phaser.BitmapText(this.game, x, y, text, style)); @@ -220,41 +255,13 @@ Phaser.GameObjectFactory.prototype = { * Creates a new Tilemap object. * * @method Phaser.GameObjectFactory#tilemap - * @param {string} key - Asset key for the JSON file. + * @param {string} key - Asset key for the JSON or CSV map data in the cache. + * @param {object|string} tilesets - An object mapping Cache.tileset keys with the tileset names in the JSON file. If a string is provided that will be used. * @return {Phaser.Tilemap} The newly created tilemap object. */ - tilemap: function (key) { + tilemap: function (key, tilesets) { - return new Phaser.Tilemap(this.game, key); - - }, - - /** - * Creates a new Tileset object. - * - * @method Phaser.GameObjectFactory#tileset - * @param {string} key - The image key as defined in the Game.Cache to use as the tileset. - * @return {Phaser.Tileset} The newly created tileset object. - */ - tileset: function (key) { - - return this.game.cache.getTileset(key); - - }, - - /** - * Creates a new Tilemap Layer object. - * - * @method Phaser.GameObjectFactory#tilemapLayer - * @param {number} x - X position of the new tilemapLayer. - * @param {number} y - Y position of the new tilemapLayer. - * @param {number} width - the width of the tilemapLayer. - * @param {number} height - the height of the tilemapLayer. - * @return {Phaser.TilemapLayer} The newly created tilemaplayer object. - */ - tilemapLayer: function (x, y, width, height, tileset, tilemap, layer) { - - return this.world.add(new Phaser.TilemapLayer(this.game, x, y, width, height, tileset, tilemap, layer)); + return new Phaser.Tilemap(this.game, key, tilesets); }, @@ -278,7 +285,7 @@ Phaser.GameObjectFactory.prototype = { }, /** - * A BitmapData object which can be manipulated and drawn to like a traditional Canvas object and used to texture Sprites. + * Experimental: A BitmapData object which can be manipulated and drawn to like a traditional Canvas object and used to texture Sprites. * * @method Phaser.GameObjectFactory#bitmapData * @param {number} [width=256] - The width of the BitmapData in pixels. @@ -311,4 +318,6 @@ Phaser.GameObjectFactory.prototype = { } -}; \ No newline at end of file +}; + +Phaser.GameObjectFactory.prototype.constructor = Phaser.GameObjectFactory; diff --git a/src/gameobjects/Graphics.js b/src/gameobjects/Graphics.js index fc8932fb..742abafc 100644 --- a/src/gameobjects/Graphics.js +++ b/src/gameobjects/Graphics.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ diff --git a/src/gameobjects/RenderTexture.js b/src/gameobjects/RenderTexture.js index 4ab01752..0c98b577 100644 --- a/src/gameobjects/RenderTexture.js +++ b/src/gameobjects/RenderTexture.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -71,16 +71,19 @@ Phaser.RenderTexture.prototype.constructor = PIXI.RenderTexture; /** * This function will draw the display object to the texture. If the display object is a Group or has children it will * draw all children as well. -* -* @method render +* +* @method Phaser.RenderTexture#render +* @memberof Phaser.RenderTexture * @param {DisplayObject} displayObject - The display object to render this texture on. * @param {Phaser.Point} [position] - Where to draw the display object. * @param {boolean} [clear=false] - If true the texture will be cleared before the displayObject is drawn. +* @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered. */ -Phaser.RenderTexture.prototype.render = function(displayObject, position, clear) { +Phaser.RenderTexture.prototype.render = function(displayObject, position, clear, renderHidden) { if (typeof position === 'undefined') { position = false; } if (typeof clear === 'undefined') { clear = false; } + if (typeof renderHidden === 'undefined') { renderHidden = false; } if (displayObject instanceof Phaser.Group) { @@ -89,11 +92,11 @@ Phaser.RenderTexture.prototype.render = function(displayObject, position, clear) if (PIXI.gl) { - this.renderWebGL(displayObject, position, clear); + this.renderWebGL(displayObject, position, clear, renderHidden); } else { - this.renderCanvas(displayObject, position, clear); + this.renderCanvas(displayObject, position, clear, renderHidden); } } @@ -102,29 +105,32 @@ Phaser.RenderTexture.prototype.render = function(displayObject, position, clear) * This function will draw the display object to the texture at the given x/y coordinates. * If the display object is a Group or has children it will draw all children as well. * -* @method renderXY +* @method Phaser.RenderTexture#renderXY +* @memberof Phaser.RenderTexture * @param {DisplayObject} displayObject - The display object to render this texture on. * @param {number} x - The x coordinate to draw the display object at. * @param {number} y - The y coordinate to draw the display object at. * @param {boolean} [clear=false] - If true the texture will be cleared before the displayObject is drawn. +* @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered. */ -Phaser.RenderTexture.prototype.renderXY = function(displayObject, x, y, clear) { +Phaser.RenderTexture.prototype.renderXY = function(displayObject, x, y, clear, renderHidden) { this._tempPoint.x = x; this._tempPoint.y = y; - this.render(displayObject, this._tempPoint, clear); + this.render(displayObject, this._tempPoint, clear, renderHidden); } /** - * Initializes the webgl data for this texture - * - * @method initWebGL - * @private - */ -Phaser.RenderTexture.prototype.initWebGL = function() -{ +* Initializes the webgl data for this texture +* +* @method Phaser.RenderTexture#initWebGL +* @memberof Phaser.RenderTexture +* @private +*/ +Phaser.RenderTexture.prototype.initWebGL = function() { + var gl = PIXI.gl; this.glFramebuffer = gl.createFramebuffer(); @@ -160,7 +166,12 @@ Phaser.RenderTexture.prototype.initWebGL = function() // this.render = this.renderWebGL; } - +/** +* Resizes the RenderTexture. +* +* @method Phaser.RenderTexture#resize +* @memberof Phaser.RenderTexture +*/ Phaser.RenderTexture.prototype.resize = function(width, height) { @@ -186,11 +197,12 @@ Phaser.RenderTexture.prototype.resize = function(width, height) } /** - * Initializes the canvas data for this texture - * - * @method initCanvas - * @private - */ +* Initializes the canvas data for this texture +* +* @method Phaser.RenderTexture#initCanvas +* @memberof Phaser.RenderTexture +* @private +*/ Phaser.RenderTexture.prototype.initCanvas = function() { this.renderer = new PIXI.CanvasRenderer(this.width, this.height, null, 0); @@ -202,14 +214,17 @@ Phaser.RenderTexture.prototype.initCanvas = function() } /** - * This function will draw the display object to the texture. - * - * @method renderWebGL - * @param displayObject {DisplayObject} The display object to render this texture on - * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn - * @private - */ -Phaser.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear) +* This function will draw the display object to the texture. +* +* @method Phaser.RenderTexture#renderWebGL +* @memberof Phaser.RenderTexture +* @private +* @param {DisplayObject} displayObject - The display object to render this texture on. +* @param {Phaser.Point} [position] - Where to draw the display object. +* @param {boolean} [clear=false] - If true the texture will be cleared before the displayObject is drawn. +* @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered. +*/ +Phaser.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear, renderHidden) { var gl = PIXI.gl; @@ -280,12 +295,15 @@ Phaser.RenderTexture.prototype.renderWebGL = function(displayObject, position, c /** * This function will draw the display object to the texture. * - * @method renderCanvas - * @param displayObject {DisplayObject} The display object to render this texture on - * @param clear {Boolean} If true the texture will be cleared before the displayObject is drawn - * @private - */ -Phaser.RenderTexture.prototype.renderCanvas = function(displayObject, position, clear) +* @method Phaser.RenderTexture#renderCanvas +* @memberof Phaser.RenderTexture +* @private +* @param {DisplayObject} displayObject - The display object to render this texture on. +* @param {Phaser.Point} [position] - Where to draw the display object. +* @param {boolean} [clear=false] - If true the texture will be cleared before the displayObject is drawn. +* @param {boolean} [renderHidden=false] - If true displayObjects that have their visible property set to false will still be rendered. +*/ +Phaser.RenderTexture.prototype.renderCanvas = function(displayObject, position, clear, renderHidden) { var children = displayObject.children; @@ -306,10 +324,9 @@ Phaser.RenderTexture.prototype.renderCanvas = function(displayObject, position, { this.renderer.context.clearRect(0, 0, this.width, this.height); } - - this.renderer.renderDisplayObject(displayObject); + + this.renderer.renderDisplayObject(displayObject, renderHidden); this.renderer.context.setTransform(1, 0, 0, 1, 0, 0); - // PIXI.texturesToUpdate.push(this.baseTexture); } diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js index be7ab1e9..1e7ea7ae 100644 --- a/src/gameobjects/Sprite.js +++ b/src/gameobjects/Sprite.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -209,6 +209,7 @@ Phaser.Sprite = function (game, x, y, key, frame) { */ this._cache = { + fresh: true, dirty: false, // Transform cache @@ -354,7 +355,7 @@ Phaser.Sprite = function (game, x, y, key, frame) { /** * @property {Phaser.Point} cameraOffset - If this Sprite is fixed to the camera then use this Point to specify how far away from the Camera x/y it's rendered. */ - this.cameraOffset = new Phaser.Point(); + this.cameraOffset = new Phaser.Point(x, y); /** * You can crop the Sprites texture by modifying the crop properties. For example crop.width = 50 would set the Sprite to only render 50px wide. @@ -370,9 +371,19 @@ Phaser.Sprite = function (game, x, y, key, frame) { */ this.cropEnabled = false; + /** + * @property {boolean} debug - Handy flag to use with Game.enableStep + * @default + */ + this.debug = false; + this.updateCache(); this.updateBounds(); + /** + * @property {PIXI.Point} pivot - The pivot point of the displayObject that it rotates around. + */ + }; // Needed to keep the PIXI.Sprite constructor in the prototype chain (as the core pixi renderer uses an instanceof check sadly) @@ -387,6 +398,24 @@ Phaser.Sprite.prototype.constructor = Phaser.Sprite; */ Phaser.Sprite.prototype.preUpdate = function() { + if (this._cache.fresh) + { + this.world.setTo(this.parent.position.x + this.x, this.parent.position.y + this.y); + this.worldTransform[2] = this.world.x; + this.worldTransform[5] = this.world.y; + this._cache.fresh = false; + + if (this.body) + { + this.body.x = (this.world.x - (this.anchor.x * this.width)) + this.body.offset.x; + this.body.y = (this.world.y - (this.anchor.y * this.height)) + this.body.offset.y; + this.body.preX = this.body.x; + this.body.preY = this.body.y; + } + + return; + } + if (!this.exists || (this.group && !this.group.exists)) { this.renderOrderID = -1; @@ -502,7 +531,6 @@ Phaser.Sprite.prototype.updateAnimation = function() { this._cache.halfHeight = Math.floor(this._cache.height / 2); this._cache.dirty = true; - } }; @@ -597,12 +625,6 @@ Phaser.Sprite.prototype.updateBounds = function() { this.renderable = this._cache.cameraVisible; } - // Update our physics bounds - if (this.body) - { - this.body.updateBounds(this.center.x, this.center.y, this._cache.scaleX, this._cache.scaleY); - } - }; /** @@ -613,9 +635,7 @@ Phaser.Sprite.prototype.updateBounds = function() { * @memberof Phaser.Sprite * @param {Phaser.Point} p - The Point object to store the results in. * @param {number} x - x coordinate within the Sprite to translate. -* @param {number} y - x coordinate within the Sprite to translate. -* @param {number} sx - Scale factor to be applied. -* @param {number} sy - Scale factor to be applied. +* @param {number} y - y coordinate within the Sprite to translate. * @return {Phaser.Point} The translated point. */ Phaser.Sprite.prototype.getLocalPosition = function(p, x, y) { @@ -634,8 +654,8 @@ Phaser.Sprite.prototype.getLocalPosition = function(p, x, y) { * @method Phaser.Sprite#getLocalUnmodifiedPosition * @memberof Phaser.Sprite * @param {Phaser.Point} p - The Point object to store the results in. -* @param {number} x - x coordinate within the Sprite to translate. -* @param {number} y - x coordinate within the Sprite to translate. +* @param {number} gx - x coordinate within the Sprite to translate. +* @param {number} gy - y coordinate within the Sprite to translate. * @return {Phaser.Point} The translated point. */ Phaser.Sprite.prototype.getLocalUnmodifiedPosition = function(p, gx, gy) { @@ -676,7 +696,6 @@ Phaser.Sprite.prototype.postUpdate = function() { if (this.exists) { - // The sprite is positioned in this call, after taking into consideration motion updates and collision if (this.body) { this.body.postUpdate(); @@ -693,8 +712,6 @@ Phaser.Sprite.prototype.postUpdate = function() { this._cache.y = this.y; } - this.world.setTo(this.game.camera.x + this.worldTransform[2], this.game.camera.y + this.worldTransform[5]); - this.position.x = this._cache.x; this.position.y = this._cache.y; } @@ -772,8 +789,17 @@ Phaser.Sprite.prototype.loadTexture = function (key, frame) { */ Phaser.Sprite.prototype.centerOn = function(x, y) { - this.x = x + (this.x - this.center.x); - this.y = y + (this.y - this.center.y); + if (this.fixedToCamera) + { + this.cameraOffset.x = x + (this.cameraOffset.x - this.center.x); + this.cameraOffset.y = y + (this.cameraOffset.y - this.center.y); + } + else + { + this.x = x + (this.x - this.center.x); + this.y = y + (this.y - this.center.y); + } + return this; }; @@ -840,6 +866,11 @@ Phaser.Sprite.prototype.kill = function() { */ Phaser.Sprite.prototype.destroy = function() { + if (this.filters) + { + this.filters = null; + } + if (this.group) { this.group.remove(this); @@ -860,6 +891,11 @@ Phaser.Sprite.prototype.destroy = function() { this.animations.destroy(); } + if (this.body) + { + this.body.destroy(); + } + this.alive = false; this.exists = false; this.visible = false; @@ -911,6 +947,7 @@ Phaser.Sprite.prototype.reset = function(x, y, health) { this.x = x; this.y = y; + this.world.setTo(x, y); this.position.x = this.x; this.position.y = this.y; this.alive = true; @@ -923,7 +960,7 @@ Phaser.Sprite.prototype.reset = function(x, y, health) { if (this.body) { - this.body.reset(); + this.body.reset(false); } return this; @@ -974,6 +1011,34 @@ Phaser.Sprite.prototype.play = function (name, frameRate, loop, killOnComplete) }; +/** +* Returns the delta x value. The difference between Sprite.x now and in the previous step. +* @name Phaser.Sprite#deltaX +* @property {number} deltaX - The delta value. Positive if the motion was to the right, negative if to the left. +* @readonly +*/ +Object.defineProperty(Phaser.Sprite.prototype, 'deltaX', { + + get: function() { + return this.world.x - this._cache.prevX; + } + +}); + +/** +* Returns the delta x value. The difference between Sprite.y now and in the previous step. +* @name Phaser.Sprite#deltaY +* @property {number} deltaY - The delta value. Positive if the motion was downwards, negative if upwards. +* @readonly +*/ +Object.defineProperty(Phaser.Sprite.prototype, 'deltaY', { + + get: function() { + return this.world.y - this._cache.prevY; + } + +}); + /** * Indicates the rotation of the Sprite, in degrees, from its original orientation. Values from 0 to 180 represent clockwise rotation; values from 0 to -180 represent counterclockwise rotation. * Values outside this range are added to or subtracted from 360 to obtain a value within the range. For example, the statement player.angle = 450 is the same as player.angle = 90. @@ -1038,6 +1103,32 @@ Object.defineProperty(Phaser.Sprite.prototype, "inCamera", { }); +/** +* @name Phaser.Sprite#worldCenterX +* @property {number} worldCenterX - The center of the Sprite in world coordinates. +* @readonly +*/ +Object.defineProperty(Phaser.Sprite.prototype, "worldCenterX", { + + get: function () { + return this.game.camera.x + this.center.x; + } + +}); + +/** +* @name Phaser.Sprite#worldCenterY +* @property {number} worldCenterY - The center of the Sprite in world coordinates. +* @readonly +*/ +Object.defineProperty(Phaser.Sprite.prototype, "worldCenterY", { + + get: function () { + return this.game.camera.y + this.center.y; + } + +}); + /** * The width of the sprite in pixels, setting this will actually modify the scale to acheive the value desired. * If you wish to crop the Sprite instead see the Sprite.crop value. @@ -1101,8 +1192,6 @@ Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", { set: function (value) { - console.log('inputEnabled', value, this.input); - if (value) { if (this.input.enabled === false) diff --git a/src/gameobjects/Text.js b/src/gameobjects/Text.js index b5be0621..fbd1b6bd 100644 --- a/src/gameobjects/Text.js +++ b/src/gameobjects/Text.js @@ -1,11 +1,11 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** -* Create a new Text. +* Create a new `Text` object. * @class Phaser.Text * @constructor * @param {Phaser.Game} game - Current game instance. @@ -90,6 +90,18 @@ Phaser.Text = function (game, x, y, text, style) { */ this.scale = new Phaser.Point(1, 1); + /** + * An object that is fixed to the camera ignores the position of any ancestors in the display list and uses its x/y coordinates as offsets from the top left of the camera. + * @property {boolean} fixedToCamera - Fixes this object to the Camera. + * @default + */ + this.fixedToCamera = false; + + /** + * @property {Phaser.Point} cameraOffset - If this object is fixed to the camera then use this Point to specify how far away from the Camera x/y it's rendered. + */ + this.cameraOffset = new Phaser.Point(x, y); + /** * @property {object} _cache - A mini cache for storing all of the calculated values. * @private @@ -141,6 +153,12 @@ Phaser.Text.prototype.update = function() { return; } + if (this.fixedToCamera) + { + this.x = this.game.camera.view.x + this.cameraOffset.x; + this.y = this.game.camera.view.y + this.cameraOffset.y; + } + this._cache.dirty = false; this._cache.x = this.x; diff --git a/src/gameobjects/TileSprite.js b/src/gameobjects/TileSprite.js index 2b82d1c9..76ef22e2 100644 --- a/src/gameobjects/TileSprite.js +++ b/src/gameobjects/TileSprite.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -15,18 +15,16 @@ * @param {number} width - the width of the tilesprite. * @param {number} height - the height of the tilesprite. * @param {string|Phaser.RenderTexture|PIXI.Texture} key - This is the image or texture used by the Sprite during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture or PIXI.Texture. -* @param {string|number} frame - If this Sprite is using part of a sprite sheet or texture atlas you can specify the exact frame to use by giving a string or numeric index. */ -Phaser.TileSprite = function (game, x, y, width, height, key, frame) { +Phaser.TileSprite = function (game, x, y, width, height, key) { x = x || 0; y = y || 0; width = width || 256; height = height || 256; key = key || null; - frame = frame || null; - Phaser.Sprite.call(this, game, x, y, key, frame); + Phaser.Sprite.call(this, game, x, y, key); /** * @property {PIXI.Texture} texture - The texture that the sprite renders with. @@ -51,8 +49,110 @@ Phaser.TileSprite = function (game, x, y, width, height, key, frame) { */ this.tilePosition = new Phaser.Point(0, 0); + this.body.width = width; + this.body.height = height; + }; Phaser.TileSprite.prototype = Phaser.Utils.extend(true, PIXI.TilingSprite.prototype, Phaser.Sprite.prototype); Phaser.TileSprite.prototype.constructor = Phaser.TileSprite; +/** +* Indicates the rotation of the Sprite, in degrees, from its original orientation. Values from 0 to 180 represent clockwise rotation; values from 0 to -180 represent counterclockwise rotation. +* Values outside this range are added to or subtracted from 360 to obtain a value within the range. For example, the statement player.angle = 450 is the same as player.angle = 90. +* If you wish to work in radians instead of degrees use the property Sprite.rotation instead. +* @name Phaser.TileSprite#angle +* @property {number} angle - Gets or sets the Sprites angle of rotation in degrees. +*/ +Object.defineProperty(Phaser.TileSprite.prototype, 'angle', { + + get: function() { + return Phaser.Math.wrapAngle(Phaser.Math.radToDeg(this.rotation)); + }, + + set: function(value) { + this.rotation = Phaser.Math.degToRad(Phaser.Math.wrapAngle(value)); + } + +}); + +/** +* @name Phaser.TileSprite#frame +* @property {number} frame - Gets or sets the current frame index and updates the Texture Cache for display. +*/ +Object.defineProperty(Phaser.TileSprite.prototype, "frame", { + + get: function () { + return this.animations.frame; + }, + + set: function (value) { + this.animations.frame = value; + } + +}); + +/** +* @name Phaser.TileSprite#frameName +* @property {string} frameName - Gets or sets the current frame name and updates the Texture Cache for display. +*/ +Object.defineProperty(Phaser.TileSprite.prototype, "frameName", { + + get: function () { + return this.animations.frameName; + }, + + set: function (value) { + this.animations.frameName = value; + } + +}); + +/** +* @name Phaser.TileSprite#inCamera +* @property {boolean} inCamera - Is this sprite visible to the camera or not? +* @readonly +*/ +Object.defineProperty(Phaser.TileSprite.prototype, "inCamera", { + + get: function () { + return this._cache.cameraVisible; + } + +}); + +/** +* By default a Sprite won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is +* activated for this Sprite instance and it will then start to process click/touch events and more. +* +* @name Phaser.TileSprite#inputEnabled +* @property {boolean} inputEnabled - Set to true to allow this Sprite to receive input events, otherwise false. +*/ +Object.defineProperty(Phaser.TileSprite.prototype, "inputEnabled", { + + get: function () { + + return (this.input.enabled); + + }, + + set: function (value) { + + if (value) + { + if (this.input.enabled === false) + { + this.input.start(); + } + } + else + { + if (this.input.enabled) + { + this.input.stop(); + } + } + + } + +}); diff --git a/src/geom/Circle.js b/src/geom/Circle.js index 78b2765c..86cc21b1 100644 --- a/src/geom/Circle.js +++ b/src/geom/Circle.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -9,9 +9,9 @@ * @class Circle * @classdesc Phaser - Circle * @constructor -* @param {number} [x] The x coordinate of the center of the circle. -* @param {number} [y] The y coordinate of the center of the circle. -* @param {number} [diameter] The diameter of the circle. +* @param {number} [x=0] - The x coordinate of the center of the circle. +* @param {number} [y=0] - The y coordinate of the center of the circle. +* @param {number} [diameter=0] - The diameter of the circle. * @return {Phaser.Circle} This circle object */ Phaser.Circle = function (x, y, diameter) { @@ -195,6 +195,8 @@ Phaser.Circle.prototype = { }; +Phaser.Circle.prototype.constructor = Phaser.Circle; + /** * The largest distance between any two points on the circle. The same as the radius * 2. * @name Phaser.Circle#diameter diff --git a/src/geom/Line.js b/src/geom/Line.js new file mode 100644 index 00000000..2e8e4fe5 --- /dev/null +++ b/src/geom/Line.js @@ -0,0 +1,264 @@ +/** +* @author Richard Davey +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* Creates a new Line object with a start and an end point. +* @class Line +* @classdesc Phaser - Line +* @constructor +* @param {number} [x1=0] - The x coordinate of the start of the line. +* @param {number} [y1=0] - The y coordinate of the start of the line. +* @param {number} [x2=0] - The x coordinate of the end of the line. +* @param {number} [y2=0] - The y coordinate of the end of the line. +* @return {Phaser.Line} This line object +*/ +Phaser.Line = function (x1, y1, x2, y2) { + + x1 = x1 || 0; + y1 = y1 || 0; + x2 = x2 || 0; + y2 = y2 || 0; + + /** + * @property {Phaser.Point} start - The start point of the line. + */ + this.start = new Phaser.Point(x1, y1); + + /** + * @property {Phaser.Point} end - The end point of the line. + */ + this.end = new Phaser.Point(x2, y2); + +}; + +Phaser.Line.prototype = { + + /** + * Sets the components of the Line to the specified values. + * @method Phaser.Line#setTo + * @param {number} [x1=0] - The x coordinate of the start of the line. + * @param {number} [y1=0] - The y coordinate of the start of the line. + * @param {number} [x2=0] - The x coordinate of the end of the line. + * @param {number} [y2=0] - The y coordinate of the end of the line. + * @return {Phaser.Line} This line object + */ + setTo: function (x1, y1, x2, y2) { + + this.start.setTo(x1, y1); + this.end.setTo(x2, y2); + + return this; + + }, + + /** + * Sets the line to match the x/y coordinates of the two given sprites. + * Can optionally be calculated from their center coordinates. + * @method Phaser.Line#fromSprite + * @param {Phaser.Sprite} startSprite - The coordinates of this Sprite will be set to the Line.start point. + * @param {Phaser.Sprite} endSprite - The coordinates of this Sprite will be set to the Line.start point. + * @param {boolean} [useCenter=true] - If true it will use startSprite.center.x, if false startSprite.x. + * @return {Phaser.Line} This line object + */ + fromSprite: function (startSprite, endSprite, useCenter) { + + if (typeof useCenter === 'undefined') { useCenter = true; } + + if (useCenter) + { + return this.setTo(startSprite.center.x, startSprite.center.y, endSprite.center.x, endSprite.center.y); + } + else + { + return this.setTo(startSprite.x, startSprite.y, endSprite.x, endSprite.y); + } + + }, + + /** + * Checks for intersection between this line and another Line. + * If asSegment is true it will check for segment intersection. If asSegment is false it will check for line intersection. + * Returns the intersection segment of AB and EF as a Point, or null if there is no intersection. + * + * @method Phaser.Line#intersects + * @param {Phaser.Line} line - The line to check against this one. + * @param {boolean} [asSegment=true] - If true it will check for segment intersection, otherwise full line intersection. + * @param {Phaser.Point} [result] - A Point object to store the result in, if not given a new one will be created. + * @return {Phaser.Point} The intersection segment of the two lines as a Point, or null if there is no intersection. + */ + intersects: function (line, asSegment, result) { + + return Phaser.Line.intersectsPoints(this.start, this.end, line.start, line.end, asSegment, result); + + }, + + /** + * Tests if the given coordinates fall on this line. See pointOnSegment to test against just the line segment. + * @method Phaser.Line#pointOnLine + * @param {number} x - The line to check against this one. + * @param {number} y - The line to check against this one. + * @return {boolean} True if the point is on the line, false if not. + */ + pointOnLine: function (x, y) { + + return ((x - this.start.x) * (this.end.y - this.end.y) === (this.end.x - this.start.x) * (y - this.end.y)); + + }, + + /** + * Tests if the given coordinates fall on this line and within the segment. See pointOnLine to test against just the line. + * @method Phaser.Line#pointOnSegment + * @param {number} x - The line to check against this one. + * @param {number} y - The line to check against this one. + * @return {boolean} True if the point is on the line and segment, false if not. + */ + pointOnSegment: function (x, y) { + + var xMin = Math.min(this.start.x, this.end.x); + var xMax = Math.max(this.start.x, this.end.x); + var yMin = Math.min(this.start.y, this.end.y); + var yMax = Math.max(this.start.y, this.end.y); + + return (this.pointOnLine(x, y) && (x >= xMin && x <= xMax) && (y >= yMin && y <= yMax)); + + } + +}; + +/** +* @name Phaser.Line#length +* @property {number} length - Gets the length of the line segment. +* @readonly +*/ +Object.defineProperty(Phaser.Line.prototype, "length", { + + get: function () { + return Math.sqrt((this.end.x - this.start.x) * (this.end.x - this.start.x) + (this.end.y - this.start.y) * (this.end.y - this.start.y)); + } + +}); + +/** +* @name Phaser.Line#angle +* @property {number} angle - Gets the angle of the line. +* @readonly +*/ +Object.defineProperty(Phaser.Line.prototype, "angle", { + + get: function () { + return Math.atan2(this.end.x - this.start.x, this.end.y - this.start.y); + } + +}); + +/** +* @name Phaser.Line#slope +* @property {number} slope - Gets the slope of the line (y/x). +* @readonly +*/ +Object.defineProperty(Phaser.Line.prototype, "slope", { + + get: function () { + return (this.end.y - this.start.y) / (this.end.x - this.start.x); + } + +}); + +/** +* @name Phaser.Line#perpSlope +* @property {number} perpSlope - Gets the perpendicular slope of the line (x/y). +* @readonly +*/ +Object.defineProperty(Phaser.Line.prototype, "perpSlope", { + + get: function () { + return -((this.end.x - this.start.x) / (this.end.y - this.start.y)); + } + +}); + +/** +* Checks for intersection between two lines as defined by the given start and end points. +* If asSegment is true it will check for line segment intersection. If asSegment is false it will check for line intersection. +* Returns the intersection segment of AB and EF as a Point, or null if there is no intersection. +* Adapted from code by Keith Hair +* +* @method Phaser.Line.intersects +* @param {Phaser.Point} a - The start of the first Line to be checked. +* @param {Phaser.Point} b - The end of the first line to be checked. +* @param {Phaser.Point} e - The start of the second Line to be checked. +* @param {Phaser.Point} f - The end of the second line to be checked. +* @param {boolean} [asSegment=true] - If true it will check for segment intersection, otherwise full line intersection. +* @param {Phaser.Point} [result] - A Point object to store the result in, if not given a new one will be created. +* @return {Phaser.Point} The intersection segment of the two lines as a Point, or null if there is no intersection. +*/ +Phaser.Line.intersectsPoints = function (a, b, e, f, asSegment, result) { + + if (typeof asSegment === 'undefined') { asSegment = true; } + if (typeof result === 'undefined') { result = new Phaser.Point(); } + + var a1 = b.y - a.y; + var a2 = f.y - e.y; + var b1 = a.x - b.x; + var b2 = e.x - f.x; + var c1 = (b.x * a.y) - (a.x * b.y); + var c2 = (f.x * e.y) - (e.x * f.y); + var denom = (a1 * b2) - (a2 * b1); + + if (denom === 0) + { + return null; + } + + result.x = ((b1 * c2) - (b2 * c1)) / denom; + result.y = ((a2 * c1) - (a1 * c2)) / denom; + + if (asSegment) + { + if (Math.pow((result.x - b.x) + (result.y - b.y), 2) > Math.pow((a.x - b.x) + (a.y - b.y), 2)) + { + return null; + } + + if (Math.pow((result.x - a.x) + (result.y - a.y), 2) > Math.pow((a.x - b.x) + (a.y - b.y), 2)) + { + return null; + } + + if (Math.pow((result.x - f.x) + (result.y - f.y), 2) > Math.pow((e.x - f.x) + (e.y - f.y), 2)) + { + return null; + } + + if (Math.pow((result.x - e.x) + (result.y - e.y), 2) > Math.pow((e.x - f.x) + (e.y - f.y), 2)) + { + return null; + } + } + + return result; + +}; + +/** +* Checks for intersection between two lines. +* If asSegment is true it will check for segment intersection. +* If asSegment is false it will check for line intersection. +* Returns the intersection segment of AB and EF as a Point, or null if there is no intersection. +* Adapted from code by Keith Hair +* +* @method Phaser.Line.intersects +* @param {Phaser.Line} a - The first Line to be checked. +* @param {Phaser.Line} b - The second Line to be checked. +* @param {boolean} [asSegment=true] - If true it will check for segment intersection, otherwise full line intersection. +* @param {Phaser.Point} [result] - A Point object to store the result in, if not given a new one will be created. +* @return {Phaser.Point} The intersection segment of the two lines as a Point, or null if there is no intersection. +*/ +Phaser.Line.intersects = function (a, b, asSegment, result) { + + return Phaser.Line.intersectsPoints(a.start, a.end, b.start, b.end, asSegment, result); + +}; diff --git a/src/geom/Point.js b/src/geom/Point.js index 3b090b5b..029341c5 100644 --- a/src/geom/Point.js +++ b/src/geom/Point.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -288,6 +288,8 @@ Phaser.Point.prototype = { }; +Phaser.Point.prototype.constructor = Phaser.Point; + /** * Adds the coordinates of two points together to create a new point. * @method Phaser.Point.add diff --git a/src/geom/Polygon.js b/src/geom/Polygon.js index 8bb0b875..c81ad370 100644 --- a/src/geom/Polygon.js +++ b/src/geom/Polygon.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ diff --git a/src/geom/Rectangle.js b/src/geom/Rectangle.js index c27aca20..0861dcf3 100644 --- a/src/geom/Rectangle.js +++ b/src/geom/Rectangle.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -266,6 +266,8 @@ Phaser.Rectangle.prototype = { }; +Phaser.Rectangle.prototype.constructor = Phaser.Rectangle; + /** * @name Phaser.Rectangle#halfWidth * @property {number} halfWidth - Half of the width of the Rectangle. @@ -644,12 +646,12 @@ Phaser.Rectangle.intersection = function (a, b, out) { */ Phaser.Rectangle.intersects = function (a, b) { - return (a.x < b.right && b.x < a.right && a.y < b.bottom && b.y < a.bottom); + if (a.width <= 0 || a.height <= 0 || b.width <= 0 || b.height <= 0) + { + return false; + } - // return (a.x <= b.right && b.x <= a.right && a.y <= b.bottom && b.y <= a.bottom); - - // return (a.left <= b.right && b.left <= a.right && a.top <= b.bottom && b.top <= a.bottom); - // return !(a.x > b.right + tolerance || a.right < b.x - tolerance || a.y > b.bottom + tolerance || a.bottom < b.y - tolerance); + return !(a.right < b.x || a.bottom < b.y || a.x > b.right || a.y > b.bottom); }; diff --git a/src/input/Gamepad.js b/src/input/Gamepad.js new file mode 100644 index 00000000..10753344 --- /dev/null +++ b/src/input/Gamepad.js @@ -0,0 +1,578 @@ +/** +* @author @karlmacklin +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* The Gamepad class handles looking after gamepad input for your game. +* Remember to call gamepad.start(); expecting input! +* +* HTML5 GAMEPAD API SUPPORT IS AT AN EXPERIMENTAL STAGE! +* At moment of writing this (end of 2013) only Chrome supports parts of it out of the box. Firefox supports it +* via prefs flags (about:config, search gamepad). The browsers map the same controllers differently. +* This class has constans for Windows 7 Chrome mapping of +* XBOX 360 controller. +* +* @class Phaser.Gamepad +* @constructor +* @param {Phaser.Game} game - A reference to the currently running game. +*/ +Phaser.Gamepad = function (game) { + + /** + * @property {Phaser.Game} game - Local reference to game. + */ + this.game = game; + + /** + * @property {Array} _gamepads - The four Phaser Gamepads. + * @private + */ + this._gamepads = [ + new Phaser.SinglePad(game, this), + new Phaser.SinglePad(game, this), + new Phaser.SinglePad(game, this), + new Phaser.SinglePad(game, this) + ]; + + /** + * @property {Object} _gamepadIndexMap - Maps the browsers gamepad indices to our Phaser Gamepads + * @private + */ + this._gamepadIndexMap = {}; + + /** + * @property {Array} _rawPads - The raw state of the gamepads from the browser + * @private + */ + this._rawPads = []; + + /** + * @property {boolean} _active - Private flag for whether or not the API is polled + * @private + * @default + */ + this._active = false; + + /** + * You can disable all Gamepad Input by setting disabled to true. While true all new input related events will be ignored. + * @property {boolean} disabled - The disabled state of the Gamepad. + * @default + */ + this.disabled = false; + + /** + * Whether or not gamepads are supported in the current browser. Note that as of Dec. 2013 this check is actually not accurate at all due to poor implementation. + * @property {boolean} _gamepadSupportAvailable - Are gamepads supported in this browser or not? + * @private + */ + this._gamepadSupportAvailable = !!navigator.webkitGetGamepads || !!navigator.webkitGamepads || (navigator.userAgent.indexOf('Firefox/') != -1); + + /** + * Used to check for differences between earlier polls and current state of gamepads. + * @property {Array} _prevRawGamepadTypes + * @private + * @default + */ + this._prevRawGamepadTypes = []; + + /** + * Used to check for differences between earlier polls and current state of gamepads. + * @property {Array} _prevTimestamps + * @private + * @default + */ + this._prevTimestamps = []; + + /** + * @property {Object} callbackContext - The context under which the callbacks are run. + */ + this.callbackContext = this; + + /** + * @property {function} onConnectCallback - This callback is invoked every time any gamepad is connected + */ + this.onConnectCallback = null; + + /** + * @property {function} onDisconnectCallback - This callback is invoked every time any gamepad is disconnected + */ + this.onDisconnectCallback = null; + + /** + * @property {function} onDownCallback - This callback is invoked every time any gamepad button is pressed down. + */ + this.onDownCallback = null; + + /** + * @property {function} onUpCallback - This callback is invoked every time any gamepad button is released. + */ + this.onUpCallback = null; + + /** + * @property {function} onAxisCallback - This callback is invoked every time any gamepad axis is changed. + */ + this.onAxisCallback = null; + + /** + * @property {function} onFloatCallback - This callback is invoked every time any gamepad button is changed to a value where value > 0 and value < 1. + */ + this.onFloatCallback = null; + + /** + * @property {function} _ongamepadconnected - Private callback for Firefox gamepad connection handling + * @private + */ + this._ongamepadconnected = null; + + /** + * @property {function} _gamepaddisconnected - Private callback for Firefox gamepad connection handling + * @private + */ + this._gamepaddisconnected = null; +}; + +Phaser.Gamepad.prototype = { + + /** + * Add callbacks to the main Gamepad handler to handle connect/disconnect/button down/button up/axis change/float value buttons + * @method Phaser.Gamepad#addCallbacks + * @param {Object} context - The context under which the callbacks are run. + * @param {Object} callbacks - Object that takes six different callback methods: + * onConnectCallback, onDisconnectCallback, onDownCallback, onUpCallback, onAxisCallback, onFloatCallback + */ + addCallbacks: function (context, callbacks) { + + if (typeof callbacks !== 'undefined') + { + this.onConnectCallback = (typeof callbacks.onConnect === 'function') ? callbacks.onConnect : this.onConnectCallback; + this.onDisconnectCallback = (typeof callbacks.onDisconnect === 'function') ? callbacks.onDisconnect : this.onDisconnectCallback; + this.onDownCallback = (typeof callbacks.onDown === 'function') ? callbacks.onDown : this.onDownCallback; + this.onUpCallback = (typeof callbacks.onUp === 'function') ? callbacks.onUp : this.onUpCallback; + this.onAxisCallback = (typeof callbacks.onAxis === 'function') ? callbacks.onAxis : this.onAxisCallback; + this.onFloatCallback = (typeof callbacks.onFloat === 'function') ? callbacks.onFloat : this.onFloatCallback; + } + + }, + + /** + * Starts the Gamepad event handling. + * This MUST be called manually before Phaser will start polling the Gamepad API. + * + * @method Phaser.Gamepad#start + */ + start: function () { + + this._active = true; + var _this = this; + + this._ongamepadconnected = function(event) { + var newPad = event.gamepad; + _this._rawPads.push(newPad); + _this._gamepads[newPad.index].connect(newPad); + }; + + window.addEventListener('gamepadconnected', this._ongamepadconnected, false); + + this._ongamepaddisconnected = function(event) { + + var removedPad = event.gamepad; + + for (var i in _this._rawPads) + { + if (_this._rawPads[i].index === removedPad.index) + { + _this._rawPads.splice(i,1); + } + } + _this._gamepads[removedPad.index].disconnect(); + }; + + window.addEventListener('gamepaddisconnected', this._ongamepaddisconnected, false); + + }, + + /** + * Main gamepad update loop. Should not be called manually. + * @method Phaser.Gamepad#update + * @private + */ + update: function () { + + this._pollGamepads(); + + for (var i = 0; i < this._gamepads.length; i++) + { + if (this._gamepads[i]._connected) + { + this._gamepads[i].pollStatus(); + } + } + + }, + + /** + * Updating connected gamepads (for Google Chrome). + * Should not be called manually. + * @method Phaser.Gamepad#_pollGamepads + * @private + */ + _pollGamepads: function () { + + var rawGamepads = (navigator.webkitGetGamepads && navigator.webkitGetGamepads()) || navigator.webkitGamepads; + + if (rawGamepads) + { + this._rawPads = []; + + var gamepadsChanged = false; + + for (var i = 0; i < rawGamepads.length; i++) + { + if (typeof rawGamepads[i] !== this._prevRawGamepadTypes[i]) + { + gamepadsChanged = true; + this._prevRawGamepadTypes[i] = typeof rawGamepads[i]; + } + + if (rawGamepads[i]) + { + this._rawPads.push(rawGamepads[i]); + } + + // Support max 4 pads at the moment + if (i === 3) + { + break; + } + } + + if (gamepadsChanged) + { + var validConnections = { rawIndices: {}, padIndices: {} }; + var singlePad; + + for (var j = 0; j < this._gamepads.length; j++) + { + singlePad = this._gamepads[j]; + + if (singlePad.connected) + { + for (var k = 0; k < this._rawPads.length; k++) + { + if (this._rawPads[k].index === singlePad.index) + { + validConnections.rawIndices[singlePad.index] = true; + validConnections.padIndices[j] = true; + } + } + } + } + + for (var l = 0; l < this._gamepads.length; l++) + { + singlePad = this._gamepads[l]; + + if (validConnections.padIndices[l]) + { + continue; + } + + if (this._rawPads.length < 1) + { + singlePad.disconnect(); + } + + for (var m = 0; m < this._rawPads.length; m++) + { + if (validConnections.padIndices[l]) + { + break; + } + + var rawPad = this._rawPads[m]; + + if (rawPad) + { + if (validConnections.rawIndices[rawPad.index]) + { + singlePad.disconnect(); + continue; + } + else + { + singlePad.connect(rawPad); + validConnections.rawIndices[rawPad.index] = true; + validConnections.padIndices[l] = true; + } + } + else + { + singlePad.disconnect(); + } + } + } + } + } + }, + + /** + * Sets the deadZone variable for all four gamepads + * @method Phaser.Gamepad#setDeadZones + */ + setDeadZones: function (value) { + + for (var i = 0; i < this._gamepads.length; i++) + { + this._gamepads[i].deadZone = value; + } + + }, + + /** + * Stops the Gamepad event handling. + * + * @method Phaser.Gamepad#stop + */ + stop: function () { + + this._active = false; + + window.removeEventListener('gamepadconnected', this._ongamepadconnected); + window.removeEventListener('gamepaddisconnected', this._ongamepaddisconnected); + + }, + + /** + * Reset all buttons/axes of all gamepads + * @method Phaser.Gamepad#reset + */ + reset: function () { + + this.update(); + + for (var i = 0; i < this._gamepads.length; i++) + { + this._gamepads[i].reset(); + } + + }, + + /** + * Returns the "just pressed" state of a button from ANY gamepad connected. Just pressed is considered true if the button was pressed down within the duration given (default 250ms). + * @method Phaser.Gamepad#justPressed + * @param {number} buttonCode - The buttonCode of the button to check for. + * @param {number} [duration=250] - The duration below which the button is considered as being just pressed. + * @return {boolean} True if the button is just pressed otherwise false. + */ + justPressed: function (buttonCode, duration) { + + for (var i = 0; i < this._gamepads.length; i++) + { + if (this._gamepads[i].justPressed(buttonCode, duration) === true) + { + return true; + } + } + + return false; + + }, + + /** + * Returns the "just released" state of a button from ANY gamepad connected. Just released is considered as being true if the button was released within the duration given (default 250ms). + * @method Phaser.Gamepad#justPressed + * @param {number} buttonCode - The buttonCode of the button to check for. + * @param {number} [duration=250] - The duration below which the button is considered as being just released. + * @return {boolean} True if the button is just released otherwise false. + */ + justReleased: function (buttonCode, duration) { + + for (var i = 0; i < this._gamepads.length; i++) + { + if (this._gamepads[i].justReleased(buttonCode, duration) === true) + { + return true; + } + } + + return false; + + }, + + /** + * Returns true if the button is currently pressed down, on ANY gamepad. + * @method Phaser.Gamepad#isDown + * @param {number} buttonCode - The buttonCode of the button to check for. + * @return {boolean} True if a button is currently down. + */ + isDown: function (buttonCode) { + + for (var i = 0; i < this._gamepads.length; i++) + { + if (this._gamepads[i].isDown(buttonCode) === true) + { + return true; + } + } + + return false; + } + +}; + +Phaser.Gamepad.prototype.constructor = Phaser.Gamepad; + +/** +* If the gamepad input is active or not - if not active it should not be updated from Input.js +* @name Phaser.Gamepad#active +* @property {boolean} active - If the gamepad input is active or not. +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "active", { + + get: function () { + return this._active; + } + +}); + +/** +* Whether or not gamepads are supported in current browser. +* @name Phaser.Gamepad#supported +* @property {boolean} supported - Whether or not gamepads are supported in current browser. +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "supported", { + + get: function () { + return this._gamepadSupportAvailable; + } + +}); + +/** +* How many live gamepads are currently connected. +* @name Phaser.Gamepad#padsConnected +* @property {boolean} padsConnected - How many live gamepads are currently connected. +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "padsConnected", { + + get: function () { + return this._rawPads.length; + } + +}); + +/** +* Gamepad #1 +* @name Phaser.Gamepad#pad1 +* @property {boolean} pad1 - Gamepad #1; +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "pad1", { + + get: function () { + return this._gamepads[0]; + } + +}); + +/** +* Gamepad #2 +* @name Phaser.Gamepad#pad2 +* @property {boolean} pad2 - Gamepad #2 +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "pad2", { + + get: function () { + return this._gamepads[1]; + } + +}); + +/** +* Gamepad #3 +* @name Phaser.Gamepad#pad3 +* @property {boolean} pad3 - Gamepad #3 +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "pad3", { + + get: function () { + return this._gamepads[2]; + } + +}); + +/** +* Gamepad #4 +* @name Phaser.Gamepad#pad4 +* @property {boolean} pad4 - Gamepad #4 +* @readonly +*/ +Object.defineProperty(Phaser.Gamepad.prototype, "pad4", { + + get: function () { + return this._gamepads[3]; + } + +}); + +Phaser.Gamepad.BUTTON_0 = 0; +Phaser.Gamepad.BUTTON_1 = 1; +Phaser.Gamepad.BUTTON_2 = 2; +Phaser.Gamepad.BUTTON_3 = 3; +Phaser.Gamepad.BUTTON_4 = 4; +Phaser.Gamepad.BUTTON_5 = 5; +Phaser.Gamepad.BUTTON_6 = 6; +Phaser.Gamepad.BUTTON_7 = 7; +Phaser.Gamepad.BUTTON_8 = 8; +Phaser.Gamepad.BUTTON_9 = 9; +Phaser.Gamepad.BUTTON_10 = 10; +Phaser.Gamepad.BUTTON_11 = 11; +Phaser.Gamepad.BUTTON_12 = 12; +Phaser.Gamepad.BUTTON_13 = 13; +Phaser.Gamepad.BUTTON_14 = 14; +Phaser.Gamepad.BUTTON_15 = 15; + +Phaser.Gamepad.AXIS_0 = 0; +Phaser.Gamepad.AXIS_1 = 1; +Phaser.Gamepad.AXIS_2 = 2; +Phaser.Gamepad.AXIS_3 = 3; +Phaser.Gamepad.AXIS_4 = 4; +Phaser.Gamepad.AXIS_5 = 5; +Phaser.Gamepad.AXIS_6 = 6; +Phaser.Gamepad.AXIS_7 = 7; +Phaser.Gamepad.AXIS_8 = 8; +Phaser.Gamepad.AXIS_9 = 9; + +// Below mapping applies to XBOX 360 Wired and Wireless controller on Google Chrome (tested on Windows 7). +// - Firefox uses different map! Separate amount of buttons and axes. DPAD = axis and not a button. +// In other words - discrepancies when using gamepads. + +Phaser.Gamepad.XBOX360_A = 0; +Phaser.Gamepad.XBOX360_B = 1; +Phaser.Gamepad.XBOX360_X = 2; +Phaser.Gamepad.XBOX360_Y = 3; +Phaser.Gamepad.XBOX360_LEFT_BUMPER = 4; +Phaser.Gamepad.XBOX360_RIGHT_BUMPER = 5; +Phaser.Gamepad.XBOX360_LEFT_TRIGGER = 6; +Phaser.Gamepad.XBOX360_RIGHT_TRIGGER = 7; +Phaser.Gamepad.XBOX360_BACK = 8; +Phaser.Gamepad.XBOX360_START = 9; +Phaser.Gamepad.XBOX360_STICK_LEFT_BUTTON = 10; +Phaser.Gamepad.XBOX360_STICK_RIGHT_BUTTON = 11; + +Phaser.Gamepad.XBOX360_DPAD_LEFT = 14; +Phaser.Gamepad.XBOX360_DPAD_RIGHT = 15; +Phaser.Gamepad.XBOX360_DPAD_UP = 12; +Phaser.Gamepad.XBOX360_DPAD_DOWN = 13; + +Phaser.Gamepad.XBOX360_STICK_LEFT_X = 0; +Phaser.Gamepad.XBOX360_STICK_LEFT_Y = 1; +Phaser.Gamepad.XBOX360_STICK_RIGHT_X = 2; +Phaser.Gamepad.XBOX360_STICK_RIGHT_Y = 3; diff --git a/src/input/GamepadButton.js b/src/input/GamepadButton.js new file mode 100644 index 00000000..07d63c25 --- /dev/null +++ b/src/input/GamepadButton.js @@ -0,0 +1,175 @@ +/** +* @author @karlmacklin +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* @class Phaser.GamepadButton +* @classdesc If you need more fine-grained control over the handling of specific buttons you can create and use Phaser.GamepadButton objects. +* @constructor +* @param {Phaser.Game} game - Current game instance. +* @param {number} buttoncode - The button code this GamepadButton is responsible for. +*/ +Phaser.GamepadButton = function (game, buttoncode) { + + /** + * @property {Phaser.Game} game - A reference to the currently running game. + */ + this.game = game; + + /** + * @property {boolean} isDown - The "down" state of the button. + * @default + */ + this.isDown = false; + + /** + * @property {boolean} isUp - The "up" state of the button. + * @default + */ + this.isUp = false; + + /** + * @property {number} timeDown - The timestamp when the button was last pressed down. + * @default + */ + this.timeDown = 0; + + /** + * If the button is down this value holds the duration of that button press and is constantly updated. + * If the button is up it holds the duration of the previous down session. + * @property {number} duration - The number of milliseconds this button has been held down for. + * @default + */ + this.duration = 0; + + /** + * @property {number} timeUp - The timestamp when the button was last released. + * @default + */ + this.timeUp = 0; + + /** + * @property {number} repeats - If a button is held down this holds down the number of times the button has 'repeated'. + * @default + */ + this.repeats = 0; + + /** + * @property {number} value - Button value. Mainly useful for checking analog buttons (like shoulder triggers) + * @default + */ + this.value = 0; + + /** + * @property {number} buttonCode - The buttoncode of this button. + */ + this.buttonCode = buttoncode; + + /** + * @property {Phaser.Signal} onDown - This Signal is dispatched every time this GamepadButton is pressed down. It is only dispatched once (until the button is released again). + */ + this.onDown = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onUp - This Signal is dispatched every time this GamepadButton is pressed down. It is only dispatched once (until the button is released again). + */ + this.onUp = new Phaser.Signal(); + + /** + * @property {Phaser.Signal} onFloat - This Signal is dispatched every time this GamepadButton changes floating value (between (but not exactly) 0 and 1) + */ + this.onFloat = new Phaser.Signal(); + +}; + +Phaser.GamepadButton.prototype = { + + /** + * Called automatically by Phaser.SinglePad. + * @method Phaser.GamepadButton#processButtonDown + * @param {Object} value - Button value + * @protected + */ + processButtonDown: function (value) { + + if (this.isDown) + { + this.duration = this.game.time.now - this.timeDown; + this.repeats++; + } + else + { + this.isDown = true; + this.isUp = false; + this.timeDown = this.game.time.now; + this.duration = 0; + this.repeats = 0; + this.value = value; + + this.onDown.dispatch(this, value); + } + + }, + + /** + * Called automatically by Phaser.SinglePad. + * @method Phaser.GamepadButton#processButtonUp + * @param {Object} value - Button value + * @protected + */ + processButtonUp: function (value) { + + this.isDown = false; + this.isUp = true; + this.timeUp = this.game.time.now; + this.value = value; + + this.onUp.dispatch(this, value); + + }, + + /** + * Called automatically by Phaser.Gamepad. + * @method Phaser.GamepadButton#processButtonFloat + * @param {Object} value - Button value + * @protected + */ + processButtonFloat: function (value) { + + this.value = value; + this.onFloat.dispatch(this, value); + + }, + + /** + * Returns the "just pressed" state of this button. Just pressed is considered true if the button was pressed down within the duration given (default 250ms). + * @method Phaser.GamepadButton#justPressed + * @param {number} [duration=250] - The duration below which the button is considered as being just pressed. + * @return {boolean} True if the button is just pressed otherwise false. + */ + justPressed: function (duration) { + + if (typeof duration === "undefined") { duration = 250; } + + return (this.isDown && this.duration < duration); + + }, + + /** + * Returns the "just released" state of this button. Just released is considered as being true if the button was released within the duration given (default 250ms). + * @method Phaser.GamepadButton#justPressed + * @param {number} [duration=250] - The duration below which the button is considered as being just released. + * @return {boolean} True if the button is just pressed otherwise false. + */ + justReleased: function (duration) { + + if (typeof duration === "undefined") { duration = 250; } + + return (this.isDown === false && (this.game.time.now - this.timeUp < duration)); + } + +}; + +Phaser.GamepadButton.prototype.constructor = Phaser.GamepadButton; diff --git a/src/input/Input.js b/src/input/Input.js index 42d3c0ef..f25e5ab0 100644 --- a/src/input/Input.js +++ b/src/input/Input.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -30,6 +30,16 @@ Phaser.Input = function (game) { * @default */ this.hitContext = null; + + /** + * @property {function} moveCallback - An optional callback that will be fired every time the activePointer receives a move event from the DOM. Set to null to disable. + */ + this.moveCallback = null; + + /** + * @property {object} moveCallbackContext - The context in which the moveCallback will be sent. Defaults to Phaser.Input but can be set to any valid JS object. + */ + this.moveCallbackContext = this; }; @@ -306,6 +316,13 @@ Phaser.Input.prototype = { */ mspointer: null, + /** + * The Gamepad Input manager. + * @property {Phaser.Gamepad} gamepad - The Gamepad Input manager. + * @default + */ + gamepad: null, + /** * A Signal that is dispatched each time a pointer is pressed down. * @property {Phaser.Signal} onDown @@ -355,6 +372,7 @@ Phaser.Input.prototype = { this.keyboard = new Phaser.Keyboard(this.game); this.touch = new Phaser.Touch(this.game); this.mspointer = new Phaser.MSPointer(this.game); + this.gamepad = new Phaser.Gamepad(this.game); this.onDown = new Phaser.Signal(); this.onUp = new Phaser.Signal(); @@ -394,6 +412,24 @@ Phaser.Input.prototype = { this.keyboard.stop(); this.touch.stop(); this.mspointer.stop(); + this.gamepad.stop(); + + this.moveCallback = null; + + }, + + /** + * Sets a callback that is fired every time the activePointer receives a DOM move event such as a mousemove or touchmove. + * It will be called every time the activePointer moves, which in a multi-touch game can be a lot of times, so this is best + * to only use if you've limited input to a single pointer (i.e. mouse or touch) + * @method Phaser.Input#setMoveCallback + * @param {function} callback - The callback that will be called each time the activePointer receives a DOM move event. + * @param {object} callbackContext - The context in which the callback will be called. + */ + setMoveCallback: function (callback, callbackContext) { + + this.moveCallback = callback; + this.moveCallbackContext = callbackContext; }, @@ -447,6 +483,8 @@ Phaser.Input.prototype = { this._oldPosition.copyFrom(this.position); this.mousePointer.update(); + if (this.gamepad.active) { this.gamepad.update(); } + this.pointer1.update(); this.pointer2.update(); @@ -478,6 +516,7 @@ Phaser.Input.prototype = { this.keyboard.reset(); this.mousePointer.reset(); + this.gamepad.reset(); for (var i = 1; i <= 10; i++) { @@ -488,7 +527,11 @@ Phaser.Input.prototype = { } this.currentPointers = 0; - this.game.stage.canvas.style.cursor = "default"; + + if (this.game.canvas.style.cursor !== 'none') + { + this.game.canvas.style.cursor = 'default'; + } if (hard === true) { @@ -685,6 +728,8 @@ Phaser.Input.prototype = { }; +Phaser.Input.prototype.constructor = Phaser.Input; + /** * The X coordinate of the most recently active pointer. This value takes game scaling into account automatically. See Pointer.screenX/clientX for source values. * @name Phaser.Input#x diff --git a/src/input/InputHandler.js b/src/input/InputHandler.js index 9bd137ed..658735f0 100644 --- a/src/input/InputHandler.js +++ b/src/input/InputHandler.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -28,36 +28,6 @@ Phaser.InputHandler = function (sprite) { */ this.enabled = false; - /** - * @property {Description} parent - Description. - * @default - */ - // this.parent = null; - - /** - * @property {Description} next - Linked List - * @default - */ - // this.next = null; - - /** - * @property {Description} prev - Description. - * @default - */ - // this.prev = null; - - /** - * @property {Description} last - Description. - * @default - */ - // this.last = this; - - /** - * @property {Description} first - Description. - * @default - */ - // this.first = this; - /** * @property {number} priorityID - The PriorityID controls which Sprite receives an Input event first if they should overlap. * @default @@ -124,6 +94,18 @@ Phaser.InputHandler = function (sprite) { */ this.snapY = 0; + /** + * @property {number} snapOffsetX - This defines the top-left X coordinate of the snap grid. + * @default + */ + this.snapOffsetX = 0; + + /** + * @property {number} snapOffsetY - This defines the top-left Y coordinate of the snap grid.. + * @default + */ + this.snapOffsetY = 0; + /** * @property {number} pixelPerfect - Should we use pixel perfect hit detection? Warning: expensive. Only enable if you really need it! * @default @@ -199,8 +181,6 @@ Phaser.InputHandler.prototype = { */ start: function (priority, useHandCursor) { - console.log('InputHandler start'); - priority = priority || 0; if (typeof useHandCursor == 'undefined') { useHandCursor = false; } @@ -616,7 +596,7 @@ Phaser.InputHandler.prototype = { if (this.useHandCursor && this._pointerData[pointer.id].isDragged === false) { - this.game.stage.canvas.style.cursor = "pointer"; + this.game.canvas.style.cursor = "pointer"; } this.sprite.events.onInputOver.dispatch(this.sprite, pointer); @@ -637,7 +617,7 @@ Phaser.InputHandler.prototype = { if (this.useHandCursor && this._pointerData[pointer.id].isDragged === false) { - this.game.stage.canvas.style.cursor = "default"; + this.game.canvas.style.cursor = "default"; } if (this.sprite && this.sprite.events) @@ -698,15 +678,18 @@ Phaser.InputHandler.prototype = { // Only release the InputUp signal if the pointer is still over this sprite if (this.checkPointerOver(pointer)) { - //console.log('releasedHandler: ' + Date.now()); - this.sprite.events.onInputUp.dispatch(this.sprite, pointer); + // Release the inputUp signal and provide optional parameter if pointer is still over the sprite or not + this.sprite.events.onInputUp.dispatch(this.sprite, pointer, true); } else { + // Release the inputUp signal and provide optional parameter if pointer is still over the sprite or not + this.sprite.events.onInputUp.dispatch(this.sprite, pointer, false); + // Pointer outside the sprite? Reset the cursor if (this.useHandCursor) { - this.game.stage.canvas.style.cursor = "default"; + this.game.canvas.style.cursor = "default"; } } @@ -733,30 +716,61 @@ Phaser.InputHandler.prototype = { return false; } - if (this.allowHorizontalDrag) + if (this.sprite.fixedToCamera) { - this.sprite.x = pointer.x + this._dragPoint.x + this.dragOffset.x; - } + if (this.allowHorizontalDrag) + { + this.sprite.cameraOffset.x = pointer.x + this._dragPoint.x + this.dragOffset.x; + } - if (this.allowVerticalDrag) - { - this.sprite.y = pointer.y + this._dragPoint.y + this.dragOffset.y; - } + if (this.allowVerticalDrag) + { + this.sprite.cameraOffset.y = pointer.y + this._dragPoint.y + this.dragOffset.y; + } - if (this.boundsRect) - { - this.checkBoundsRect(); - } + if (this.boundsRect) + { + this.checkBoundsRect(); + } - if (this.boundsSprite) - { - this.checkBoundsSprite(); - } + if (this.boundsSprite) + { + this.checkBoundsSprite(); + } - if (this.snapOnDrag) + if (this.snapOnDrag) + { + this.sprite.cameraOffset.x = Math.round((this.sprite.cameraOffset.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX); + this.sprite.cameraOffset.y = Math.round((this.sprite.cameraOffset.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY); + } + } + else { - this.sprite.x = Math.round(this.sprite.x / this.snapX) * this.snapX; - this.sprite.y = Math.round(this.sprite.y / this.snapY) * this.snapY; + if (this.allowHorizontalDrag) + { + this.sprite.x = pointer.x + this._dragPoint.x + this.dragOffset.x; + } + + if (this.allowVerticalDrag) + { + this.sprite.y = pointer.y + this._dragPoint.y + this.dragOffset.y; + } + + if (this.boundsRect) + { + this.checkBoundsRect(); + } + + if (this.boundsSprite) + { + this.checkBoundsSprite(); + } + + if (this.snapOnDrag) + { + this.sprite.x = Math.round((this.sprite.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX); + this.sprite.y = Math.round((this.sprite.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY); + } } return true; @@ -936,14 +950,29 @@ Phaser.InputHandler.prototype = { this._draggedPointerID = pointer.id; this._pointerData[pointer.id].isDragged = true; - if (this.dragFromCenter) + if (this.sprite.fixedToCamera) { - this.sprite.centerOn(pointer.x, pointer.y); - this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y); + if (this.dragFromCenter) + { + this.sprite.centerOn(pointer.x, pointer.y); + this._dragPoint.setTo(this.sprite.cameraOffset.x - pointer.x, this.sprite.cameraOffset.y - pointer.y); + } + else + { + this._dragPoint.setTo(this.sprite.cameraOffset.x - pointer.x, this.sprite.cameraOffset.y - pointer.y); + } } else { - this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y); + if (this.dragFromCenter) + { + this.sprite.centerOn(pointer.x, pointer.y); + this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y); + } + else + { + this._dragPoint.setTo(this.sprite.x - pointer.x, this.sprite.y - pointer.y); + } } this.updateDrag(pointer); @@ -970,8 +999,16 @@ Phaser.InputHandler.prototype = { if (this.snapOnRelease) { - this.sprite.x = Math.round(this.sprite.x / this.snapX) * this.snapX; - this.sprite.y = Math.round(this.sprite.y / this.snapY) * this.snapY; + if (this.sprite.fixedToCamera) + { + this.sprite.cameraOffset.x = Math.round((this.sprite.cameraOffset.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX); + this.sprite.cameraOffset.y = Math.round((this.sprite.cameraOffset.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY); + } + else + { + this.sprite.x = Math.round((this.sprite.x - (this.snapOffsetX % this.snapX)) / this.snapX) * this.snapX + (this.snapOffsetX % this.snapX); + this.sprite.y = Math.round((this.sprite.y - (this.snapOffsetY % this.snapY)) / this.snapY) * this.snapY + (this.snapOffsetY % this.snapY); + } } this.sprite.events.onDragStop.dispatch(this.sprite, pointer); @@ -1008,14 +1045,20 @@ Phaser.InputHandler.prototype = { * @param {number} snapY - The height of the grid cell to snap to. * @param {boolean} [onDrag=true] - If true the sprite will snap to the grid while being dragged. * @param {boolean} [onRelease=false] - If true the sprite will snap to the grid when released. + * @param {number} [snapOffsetX=0] - Used to offset the top-left starting point of the snap grid. + * @param {number} [snapOffsetX=0] - Used to offset the top-left starting point of the snap grid. */ - enableSnap: function (snapX, snapY, onDrag, onRelease) { + enableSnap: function (snapX, snapY, onDrag, onRelease, snappOffsetX, snappOffsetY) { if (typeof onDrag == 'undefined') { onDrag = true; } if (typeof onRelease == 'undefined') { onRelease = false; } + if (typeof snapOffsetX == 'undefined') { snapOffsetX = 0; } + if (typeof snapOffsetY == 'undefined') { snapOffsetY = 0; } this.snapX = snapX; this.snapY = snapY; + this.snapOffsetX = snapOffsetX; + this.snapOffsetY = snapOffsetY; this.snapOnDrag = onDrag; this.snapOnRelease = onRelease; @@ -1038,22 +1081,45 @@ Phaser.InputHandler.prototype = { */ checkBoundsRect: function () { - if (this.sprite.x < this.boundsRect.left) + if (this.sprite.fixedToCamera) { - this.sprite.x = this.boundsRect.x; - } - else if ((this.sprite.x + this.sprite.width) > this.boundsRect.right) - { - this.sprite.x = this.boundsRect.right - this.sprite.width; - } + if (this.sprite.cameraOffset.x < this.boundsRect.left) + { + this.sprite.cameraOffset.x = this.boundsRect.cameraOffset.x; + } + else if ((this.sprite.cameraOffset.x + this.sprite.width) > this.boundsRect.right) + { + this.sprite.cameraOffset.x = this.boundsRect.right - this.sprite.width; + } - if (this.sprite.y < this.boundsRect.top) - { - this.sprite.y = this.boundsRect.top; + if (this.sprite.cameraOffset.y < this.boundsRect.top) + { + this.sprite.cameraOffset.y = this.boundsRect.top; + } + else if ((this.sprite.cameraOffset.y + this.sprite.height) > this.boundsRect.bottom) + { + this.sprite.cameraOffset.y = this.boundsRect.bottom - this.sprite.height; + } } - else if ((this.sprite.y + this.sprite.height) > this.boundsRect.bottom) + else { - this.sprite.y = this.boundsRect.bottom - this.sprite.height; + if (this.sprite.x < this.boundsRect.left) + { + this.sprite.x = this.boundsRect.x; + } + else if ((this.sprite.x + this.sprite.width) > this.boundsRect.right) + { + this.sprite.x = this.boundsRect.right - this.sprite.width; + } + + if (this.sprite.y < this.boundsRect.top) + { + this.sprite.y = this.boundsRect.top; + } + else if ((this.sprite.y + this.sprite.height) > this.boundsRect.bottom) + { + this.sprite.y = this.boundsRect.bottom - this.sprite.height; + } } }, @@ -1064,24 +1130,49 @@ Phaser.InputHandler.prototype = { */ checkBoundsSprite: function () { - if (this.sprite.x < this.boundsSprite.x) + if (this.sprite.fixedToCamera && this.boundsSprite.fixedToCamera) { - this.sprite.x = this.boundsSprite.x; - } - else if ((this.sprite.x + this.sprite.width) > (this.boundsSprite.x + this.boundsSprite.width)) - { - this.sprite.x = (this.boundsSprite.x + this.boundsSprite.width) - this.sprite.width; - } + if (this.sprite.cameraOffset.x < this.boundsSprite.camerOffset.x) + { + this.sprite.cameraOffset.x = this.boundsSprite.camerOffset.x; + } + else if ((this.sprite.cameraOffset.x + this.sprite.width) > (this.boundsSprite.camerOffset.x + this.boundsSprite.width)) + { + this.sprite.cameraOffset.x = (this.boundsSprite.camerOffset.x + this.boundsSprite.width) - this.sprite.width; + } - if (this.sprite.y < this.boundsSprite.y) - { - this.sprite.y = this.boundsSprite.y; + if (this.sprite.cameraOffset.y < this.boundsSprite.camerOffset.y) + { + this.sprite.cameraOffset.y = this.boundsSprite.camerOffset.y; + } + else if ((this.sprite.cameraOffset.y + this.sprite.height) > (this.boundsSprite.camerOffset.y + this.boundsSprite.height)) + { + this.sprite.cameraOffset.y = (this.boundsSprite.camerOffset.y + this.boundsSprite.height) - this.sprite.height; + } } - else if ((this.sprite.y + this.sprite.height) > (this.boundsSprite.y + this.boundsSprite.height)) + else { - this.sprite.y = (this.boundsSprite.y + this.boundsSprite.height) - this.sprite.height; + if (this.sprite.x < this.boundsSprite.x) + { + this.sprite.x = this.boundsSprite.x; + } + else if ((this.sprite.x + this.sprite.width) > (this.boundsSprite.x + this.boundsSprite.width)) + { + this.sprite.x = (this.boundsSprite.x + this.boundsSprite.width) - this.sprite.width; + } + + if (this.sprite.y < this.boundsSprite.y) + { + this.sprite.y = this.boundsSprite.y; + } + else if ((this.sprite.y + this.sprite.height) > (this.boundsSprite.y + this.boundsSprite.height)) + { + this.sprite.y = (this.boundsSprite.y + this.boundsSprite.height) - this.sprite.height; + } } } -}; \ No newline at end of file +}; + +Phaser.InputHandler.prototype.constructor = Phaser.InputHandler; diff --git a/src/input/Key.js b/src/input/Key.js index 161829d9..853502bd 100644 --- a/src/input/Key.js +++ b/src/input/Key.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -169,3 +169,5 @@ Phaser.Key.prototype = { } }; + +Phaser.Key.prototype.constructor = Phaser.Key; diff --git a/src/input/Keyboard.js b/src/input/Keyboard.js index efd82569..c0a4c875 100644 --- a/src/input/Keyboard.js +++ b/src/input/Keyboard.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -100,7 +100,7 @@ Phaser.Keyboard.prototype = { * The Key object can then be polled, have events attached to it, etc. * * @method Phaser.Keyboard#addKey - * @param {number} keycode - The keycode of the key, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR + * @param {number} keycode - The keycode of the key, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR * @return {Phaser.Key} The Key object which you can store locally and reference directly. */ addKey: function (keycode) { @@ -117,7 +117,7 @@ Phaser.Keyboard.prototype = { * Removes a Key object from the Keyboard manager. * * @method Phaser.Keyboard#removeKey - * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR + * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR */ removeKey: function (keycode) { @@ -339,7 +339,7 @@ Phaser.Keyboard.prototype = { /** * Returns the "just pressed" state of the key. Just pressed is considered true if the key was pressed down within the duration given (default 250ms) * @method Phaser.Keyboard#justPressed - * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR + * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR * @param {number} [duration=250] - The duration below which the key is considered as being just pressed. * @return {boolean} True if the key is just pressed otherwise false. */ @@ -358,8 +358,8 @@ Phaser.Keyboard.prototype = { /** * Returns the "just released" state of the Key. Just released is considered as being true if the key was released within the duration given (default 250ms) - * @method Phaser.Keyboard#justPressed - * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR + * @method Phaser.Keyboard#justReleased + * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR * @param {number} [duration=250] - The duration below which the key is considered as being just released. * @return {boolean} True if the key is just released otherwise false. */ @@ -379,7 +379,7 @@ Phaser.Keyboard.prototype = { /** * Returns true of the key is currently pressed down. Note that it can only detect key presses on the web browser. * @method Phaser.Keyboard#isDown - * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACE_BAR + * @param {number} keycode - The keycode of the key to remove, i.e. Phaser.Keyboard.UP or Phaser.Keyboard.SPACEBAR * @return {boolean} True if the key is currently down. */ isDown: function (keycode) { @@ -395,6 +395,8 @@ Phaser.Keyboard.prototype = { }; +Phaser.Keyboard.prototype.constructor = Phaser.Keyboard; + Phaser.Keyboard.A = "A".charCodeAt(0); Phaser.Keyboard.B = "B".charCodeAt(0); Phaser.Keyboard.C = "C".charCodeAt(0); diff --git a/src/input/MSPointer.js b/src/input/MSPointer.js index 80c0f058..5d6f4300 100644 --- a/src/input/MSPointer.js +++ b/src/input/MSPointer.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -165,4 +165,6 @@ Phaser.MSPointer.prototype = { } -}; \ No newline at end of file +}; + +Phaser.MSPointer.prototype.constructor = Phaser.MSPointer; diff --git a/src/input/Mouse.js b/src/input/Mouse.js index 812c35b9..c8ced562 100644 --- a/src/input/Mouse.js +++ b/src/input/Mouse.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -68,7 +68,8 @@ Phaser.Mouse = function (game) { this.pointerLock = new Phaser.Signal(); /** - * @property {MouseEvent} event - The browser mouse event. + * @property {MouseEvent} event - The browser mouse DOM event. Will be set to null if no mouse event has ever been received. + * @default */ this.event = null; @@ -326,3 +327,5 @@ Phaser.Mouse.prototype = { } }; + +Phaser.Mouse.prototype.constructor = Phaser.Mouse; diff --git a/src/input/Pointer.js b/src/input/Pointer.js index 376cfbd4..56fc31bb 100644 --- a/src/input/Pointer.js +++ b/src/input/Pointer.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -207,7 +207,7 @@ Phaser.Pointer.prototype = { } // Fix to stop rogue browser plugins from blocking the visibility state event - if (this.game.paused === true && this.game.stage.scale.incorrectOrientation === false) + if (this.game.stage.disableVisibilityChange === false && this.game.paused && this.game.stage.scale.incorrectOrientation === false) { this.game.paused = false; return this; @@ -257,7 +257,7 @@ Phaser.Pointer.prototype = { }, /** - * Called internall by the Input Manager. + * Called by the Input Manager. * @method Phaser.Pointer#update */ update: function () { @@ -336,12 +336,17 @@ Phaser.Pointer.prototype = { this.game.input.circle.y = this.game.input.y; } - // If the game is paused we don't process any target objects + // If the game is paused we don't process any target objects or callbacks if (this.game.paused) { return this; } + if (this.game.input.moveCallback) + { + this.game.input.moveCallback.call(this.game.input.moveCallbackContext, this, this.x, this.y); + } + // Easy out if we're dragging something and it still exists if (this.targetObject !== null && this.targetObject.isDragged === true) { @@ -583,6 +588,8 @@ Phaser.Pointer.prototype = { }; +Phaser.Pointer.prototype.constructor = Phaser.Pointer; + /** * How long the Pointer has been depressed on the touchscreen. If not currently down it returns -1. * @name Phaser.Pointer#duration diff --git a/src/input/SinglePad.js b/src/input/SinglePad.js new file mode 100644 index 00000000..5c6943e0 --- /dev/null +++ b/src/input/SinglePad.js @@ -0,0 +1,569 @@ +/** +* @author @karlmacklin +* @copyright 2014 Photon Storm Ltd. +* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} +*/ + +/** +* @class Phaser.SinglePad +* @classdesc A single Phaser Gamepad +* @constructor +* @param {Phaser.Game} game - Current game instance. +* @param {Object} padParent - The parent Phaser.Gamepad object (all gamepads reside under this) +*/ +Phaser.SinglePad = function (game, padParent) { + + /** + * @property {Phaser.Game} game - Local reference to game. + */ + this.game = game; + + /** + * @property {Phaser.Gamepad} padParent - Main Phaser Gamepad object + */ + this._padParent = padParent; + + /** + * @property {number} index - The gamepad index as per browsers data + * @default + */ + this._index = null; + + /** + * @property {Object} _rawPad - The 'raw' gamepad data. + * @private + */ + this._rawPad = null; + + /** + * @property {boolean} _connected - Is this pad connected or not. + * @private + */ + this._connected = false; + + /** + * @property {number} _prevTimestamp - Used to check for differences between earlier polls and current state of gamepads. + * @private + */ + this._prevTimestamp = null; + + /** + * @property {Array} _rawButtons - The 'raw' button state. + * @private + */ + this._rawButtons = []; + + /** + * @property {Array} _buttons - Current Phaser state of the buttons. + * @private + */ + this._buttons = []; + + /** + * @property {Array} _axes - Current axes state. + * @private + */ + this._axes = []; + + /** + * @property {Array} _hotkeys - Hotkey buttons. + * @private + */ + this._hotkeys = []; + + /** + * @property {Object} callbackContext - The context under which the callbacks are run. + */ + this.callbackContext = this; + + /** + * @property {function} onConnectCallback - This callback is invoked every time this gamepad is connected + */ + this.onConnectCallback = null; + + /** + * @property {function} onDisconnectCallback - This callback is invoked every time this gamepad is disconnected + */ + this.onDisconnectCallback = null; + + /** + * @property {function} onDownCallback - This callback is invoked every time a button is pressed down. + */ + this.onDownCallback = null; + + /** + * @property {function} onUpCallback - This callback is invoked every time a gamepad button is released. + */ + this.onUpCallback = null; + + /** + * @property {function} onAxisCallback - This callback is invoked every time an axis is changed. + */ + this.onAxisCallback = null; + + /** + * @property {function} onFloatCallback - This callback is invoked every time a button is changed to a value where value > 0 and value < 1. + */ + this.onFloatCallback = null; + + /** + * @property {number} deadZone - Dead zone for axis feedback - within this value you won't trigger updates. + */ + this.deadZone = 0.26; + +}; + +Phaser.SinglePad.prototype = { + + /** + * Add callbacks to the this Gamepad to handle connect/disconnect/button down/button up/axis change/float value buttons + * @method Phaser.Gamepad#addCallbacks + * @param {Object} context - The context under which the callbacks are run. + * @param {Object} callbacks - Object that takes six different callbak methods: + * onConnectCallback, onDisconnectCallback, onDownCallback, onUpCallback, onAxisCallback, onFloatCallback + */ + addCallbacks: function (context, callbacks) { + + if (typeof callbacks !== 'undefined') + { + this.onConnectCallback = (typeof callbacks.onConnect === 'function') ? callbacks.onConnect : this.onConnectCallback; + this.onDisconnectCallback = (typeof callbacks.onDisconnect === 'function') ? callbacks.onDisconnect : this.onDisconnectCallback; + this.onDownCallback = (typeof callbacks.onDown === 'function') ? callbacks.onDown : this.onDownCallback; + this.onUpCallback = (typeof callbacks.onUp === 'function') ? callbacks.onUp : this.onUpCallback; + this.onAxisCallback = (typeof callbacks.onAxis === 'function') ? callbacks.onAxis : this.onAxisCallback; + this.onFloatCallback = (typeof callbacks.onFloat === 'function') ? callbacks.onFloat : this.onFloatCallback; + } + + }, + + /** + * If you need more fine-grained control over a Key you can create a new Phaser.Key object via this method. + * The Key object can then be polled, have events attached to it, etc. + * + * @method Phaser.SinglePad#addButton + * @param {number} buttonCode - The buttonCode of the button, i.e. Phaser.Gamepad.BUTTON_0 or Phaser.Gamepad.BUTTON_1 + * @return {Phaser.GamepadButton} The GamepadButton object which you can store locally and reference directly. + */ + addButton: function (buttonCode) { + + this._hotkeys[buttonCode] = new Phaser.GamepadButton(this.game, buttonCode); + return this._hotkeys[buttonCode]; + + }, + + /** + * Main update function, should be called by Phaser.Gamepad + * @method Phaser.SinglePad#pollStatus + */ + pollStatus: function () { + + if (this._rawPad.timestamp && (this._rawPad.timestamp == this._prevTimestamp)) + { + return; + } + + for (var i = 0; i < this._rawPad.buttons.length; i += 1) + { + var buttonValue = this._rawPad.buttons[i]; + + if (this._rawButtons[i] !== buttonValue) + { + if (buttonValue === 1) + { + this.processButtonDown(i, buttonValue); + } + else if (buttonValue === 0) + { + this.processButtonUp(i, buttonValue); + } + else + { + this.processButtonFloat(i, buttonValue); + } + + this._rawButtons[i] = buttonValue; + } + } + + var axes = this._rawPad.axes; + + for (var j = 0; j < axes.length; j += 1) + { + var axis = axes[j]; + + if (axis > 0 && axis > this.deadZone || axis < 0 && axis < -this.deadZone) + { + this.processAxisChange({axis: j, value: axis}); + } + else + { + this.processAxisChange({axis: j, value: 0}); + } + } + + this._prevTimestamp = this._rawPad.timestamp; + + }, + + /** + * Gamepad connect function, should be called by Phaser.Gamepad + * @param {Object} rawPad - The raw gamepad object + * @method Phaser.SinglePad#connect + */ + connect: function (rawPad) { + + var triggerCallback = !this._connected; + + this._index = rawPad.index; + this._connected = true; + this._rawPad = rawPad; + this._rawButtons = rawPad.buttons; + this._axes = rawPad.axes; + + if (triggerCallback && this._padParent.onConnectCallback) + { + this._padParent.onConnectCallback.call(this._padParent.callbackContext, this._index); + } + + if (triggerCallback && this.onConnectCallback) + { + this.onConnectCallback.call(this.callbackContext); + } + + }, + + /** + * Gamepad disconnect function, should be called by Phaser.Gamepad + * @method Phaser.SinglePad#disconnect + */ + disconnect: function () { + + var triggerCallback = this._connected; + this._connected = false; + this._rawPad = undefined; + this._rawButtons = []; + this._buttons = []; + var disconnectingIndex = this._index; + this._index = null; + + if (triggerCallback && this._padParent.onDisconnectCallback) + { + this._padParent.onDisconnectCallback.call(this._padParent.callbackContext, disconnectingIndex); + } + + if (triggerCallback && this.onDisconnectCallback) + { + this.onDisconnectCallback.call(this.callbackContext); + } + + }, + + /** + * Handles changes in axis + * @param {Object} axisState - State of the relevant axis + * @method Phaser.SinglePad#processAxisChange + */ + processAxisChange: function (axisState) { + + if (this.game.input.disabled || this.game.input.gamepad.disabled) + { + return; + } + + if (this._axes[axisState.axis] === axisState.value) + { + return; + } + + this._axes[axisState.axis] = axisState.value; + + if (this._padParent.onAxisCallback) + { + this._padParent.onAxisCallback.call(this._padParent.callbackContext, axisState, this._index); + } + + if (this.onAxisCallback) + { + this.onAxisCallback.call(this.callbackContext, axisState); + } + + }, + + /** + * Handles button down press + * @param {number} buttonCode - Which buttonCode of this button + * @param {Object} value - Button value + * @method Phaser.SinglePad#processButtonDown + */ + processButtonDown: function (buttonCode, value) { + + if (this.game.input.disabled || this.game.input.gamepad.disabled) + { + return; + } + + if (this._padParent.onDownCallback) + { + this._padParent.onDownCallback.call(this._padParent.callbackContext, buttonCode, value, this._index); + } + + if (this.onDownCallback) + { + this.onDownCallback.call(this.callbackContext, buttonCode, value); + } + + if (this._buttons[buttonCode] && this._buttons[buttonCode].isDown) + { + // Key already down and still down, so update + this._buttons[buttonCode].duration = this.game.time.now - this._buttons[buttonCode].timeDown; + } + else + { + if (!this._buttons[buttonCode]) + { + // Not used this button before, so register it + this._buttons[buttonCode] = { + isDown: true, + timeDown: this.game.time.now, + timeUp: 0, + duration: 0, + value: value + }; + } + else + { + // Button used before but freshly down + this._buttons[buttonCode].isDown = true; + this._buttons[buttonCode].timeDown = this.game.time.now; + this._buttons[buttonCode].duration = 0; + this._buttons[buttonCode].value = value; + } + } + + if (this._hotkeys[buttonCode]) + { + this._hotkeys[buttonCode].processButtonDown(value); + } + + }, + + /** + * Handles button release + * @param {number} buttonCode - Which buttonCode of this button + * @param {Object} value - Button value + * @method Phaser.SinglePad#processButtonUp + */ + processButtonUp: function (buttonCode, value) { + + if (this.game.input.disabled || this.game.input.gamepad.disabled) + { + return; + } + + if (this._padParent.onUpCallback) + { + this._padParent.onUpCallback.call(this._padParent.callbackContext, buttonCode, value, this._index); + } + + if (this.onUpCallback) + { + this.onUpCallback.call(this.callbackContext, buttonCode, value); + } + + if (this._hotkeys[buttonCode]) + { + this._hotkeys[buttonCode].processButtonUp(value); + } + + if (this._buttons[buttonCode]) + { + this._buttons[buttonCode].isDown = false; + this._buttons[buttonCode].timeUp = this.game.time.now; + this._buttons[buttonCode].value = value; + } + else + { + // Not used this button before, so register it + this._buttons[buttonCode] = { + isDown: false, + timeDown: this.game.time.now, + timeUp: this.game.time.now, + duration: 0, + value: value + }; + } + + }, + + /** + * Handles buttons with floating values (like analog buttons that acts almost like an axis but still registers like a button) + * @param {number} buttonCode - Which buttonCode of this button + * @param {Object} value - Button value (will range somewhere between 0 and 1, but not specifically 0 or 1. + * @method Phaser.SinglePad#processButtonFloat + */ + processButtonFloat: function (buttonCode, value) { + + if (this.game.input.disabled || this.game.input.gamepad.disabled) + { + return; + } + + if (this._padParent.onFloatCallback) + { + this._padParent.onFloatCallback.call(this._padParent.callbackContext, buttonCode, value, this._index); + } + + if (this.onFloatCallback) + { + this.onFloatCallback.call(this.callbackContext, buttonCode, value); + } + + if (!this._buttons[buttonCode]) + { + // Not used this button before, so register it + this._buttons[buttonCode] = { value: value }; + } + else + { + // Button used before but freshly down + this._buttons[buttonCode].value = value; + } + + if (this._hotkeys[buttonCode]) + { + this._hotkeys[buttonCode].processButtonFloat(value); + } + + }, + + /** + * Returns value of requested axis + * @method Phaser.SinglePad#isDown + * @param {number} axisCode - The index of the axis to check + * @return {number} Axis value if available otherwise false + */ + axis: function (axisCode) { + + if (this._axes[axisCode]) + { + return this._axes[axisCode]; + } + + return false; + + }, + + /** + * Returns true if the button is currently pressed down. + * @method Phaser.SinglePad#isDown + * @param {number} buttonCode - The buttonCode of the key to check. + * @return {boolean} True if the key is currently down. + */ + isDown: function (buttonCode) { + + if (this._buttons[buttonCode]) + { + return this._buttons[buttonCode].isDown; + } + + return false; + + }, + + /** + * Returns the "just released" state of a button from this gamepad. Just released is considered as being true if the button was released within the duration given (default 250ms). + * @method Phaser.SinglePad#justPressed + * @param {number} buttonCode - The buttonCode of the button to check for. + * @param {number} [duration=250] - The duration below which the button is considered as being just released. + * @return {boolean} True if the button is just released otherwise false. + */ + justReleased: function (buttonCode, duration) { + + if (typeof duration === "undefined") { duration = 250; } + + return (this._buttons[buttonCode] && this._buttons[buttonCode].isDown === false && (this.game.time.now - this._buttons[buttonCode].timeUp < duration)); + + }, + + /** + * Returns the "just pressed" state of a button from this gamepad. Just pressed is considered true if the button was pressed down within the duration given (default 250ms). + * @method Phaser.SinglePad#justPressed + * @param {number} buttonCode - The buttonCode of the button to check for. + * @param {number} [duration=250] - The duration below which the button is considered as being just pressed. + * @return {boolean} True if the button is just pressed otherwise false. + */ + justPressed: function (buttonCode, duration) { + + if (typeof duration === "undefined") { duration = 250; } + + return (this._buttons[buttonCode] && this._buttons[buttonCode].isDown && this._buttons[buttonCode].duration < duration); + + }, + + /** + * Returns the value of a gamepad button. Intended mainly for cases when you have floating button values, for example + * analog trigger buttons on the XBOX 360 controller + * @method Phaser.SinglePad#buttonValue + * @param {number} buttonCode - The buttonCode of the button to check. + * @return {boolean} Button value if available otherwise false. + */ + buttonValue: function (buttonCode) { + + if (this._buttons[buttonCode]) + { + return this._buttons[buttonCode].value; + } + + return false; + + }, + + /** + * Reset all buttons/axes of this gamepad + * @method Phaser.SinglePad#reset + */ + reset: function () { + + for (var i = 0; i < this._buttons.length; i++) + { + this._buttons[i] = 0; + } + + for (var j = 0; j < this._axes.length; j++) + { + this._axes[j] = 0; + } + + } + +}; + +Phaser.SinglePad.prototype.constructor = Phaser.SinglePad; + +/** + * Whether or not this particular gamepad is connected or not. + * @name Phaser.SinglePad#connected + * @property {boolean} connected - Whether or not this particular gamepad is connected or not. + * @readonly + */ +Object.defineProperty(Phaser.SinglePad.prototype, "connected", { + + get: function () { + return this._connected; + } + +}); + +/** + * Gamepad index as per browser data + * @name Phaser.SinglePad#index + * @property {number} index - The gamepad index, used to identify specific gamepads in the browser + * @readonly + */ +Object.defineProperty(Phaser.SinglePad.prototype, "index", { + + get: function () { + return this._index; + } + +}); diff --git a/src/input/Touch.js b/src/input/Touch.js index 65c59e8b..67715f80 100644 --- a/src/input/Touch.js +++ b/src/input/Touch.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -67,7 +67,8 @@ Phaser.Touch = function (game) { this.preventDefault = true; /** - * @property {TouchEvent} event - The browser touch event. + * @property {TouchEvent} event - The browser touch DOM event. Will be set to null if no touch event has ever been received. + * @default */ this.event = null; @@ -268,13 +269,6 @@ Phaser.Touch.prototype = { event.preventDefault(); } - /* - for (var i = 0; i < event.changedTouches.length; i++) - { - //console.log('touch enter'); - } - */ - }, /** @@ -297,13 +291,6 @@ Phaser.Touch.prototype = { event.preventDefault(); } - /* - for (var i = 0; i < event.changedTouches.length; i++) - { - //console.log('touch leave'); - } - */ - }, /** @@ -379,4 +366,6 @@ Phaser.Touch.prototype = { } -}; \ No newline at end of file +}; + +Phaser.Touch.prototype.constructor = Phaser.Touch; diff --git a/src/loader/Cache.js b/src/loader/Cache.js index ab380a3c..0e4cf05f 100644 --- a/src/loader/Cache.js +++ b/src/loader/Cache.js @@ -1,15 +1,14 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** * Phaser.Cache constructor. * -* @class Phaser.Cache -* @classdesc A game only has one instance of a Cache and it is used to store all externally loaded assets such -* as images, sounds and data files as a result of Loader calls. Cache items use string based keys for look-up. +* @class Phaser.Cache +* @classdesc A game only has one instance of a Cache and it is used to store all externally loaded assets such as images, sounds and data files as a result of Loader calls. Cached items use string based keys for look-up. * @constructor * @param {Phaser.Game} game - A reference to the currently running game. */ @@ -57,10 +56,10 @@ Phaser.Cache = function (game) { this._tilemaps = {}; /** - * @property {object} _tilesets - Tileset key-value container. + * @property {object} _binary - Binary file key-value container. * @private */ - this._tilesets = {}; + this._binary = {}; /** * @property {object} _bitmapDatas - BitmapData key-value container. @@ -93,6 +92,18 @@ Phaser.Cache.prototype = { }, + /** + * Add a binary object in to the cache. + * @method Phaser.Cache#addBinary + * @param {string} key - Asset key for this binary data. + * @param {object} binaryData - The binary object to be addded to the cache. + */ + addBinary: function (key, binaryData) { + + this._binary[key] = binaryData; + + }, + /** * Add a BitmapData object in to the cache. * @method Phaser.Cache#addBitmapData @@ -132,40 +143,18 @@ Phaser.Cache.prototype = { * @param {object} data - Extra sprite sheet data. * @param {number} frameWidth - Width of the sprite sheet. * @param {number} frameHeight - Height of the sprite sheet. - * @param {number} frameMax - How many frames stored in the sprite sheet. + * @param {number} [frameMax=-1] - How many frames stored in the sprite sheet. If -1 then it divides the whole sheet evenly. + * @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here. + * @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here. */ - addSpriteSheet: function (key, url, data, frameWidth, frameHeight, frameMax) { + addSpriteSheet: function (key, url, data, frameWidth, frameHeight, frameMax, margin, spacing) { - this._images[key] = { url: url, data: data, spriteSheet: true, frameWidth: frameWidth, frameHeight: frameHeight }; + this._images[key] = { url: url, data: data, spriteSheet: true, frameWidth: frameWidth, frameHeight: frameHeight, margin: margin, spacing: spacing }; PIXI.BaseTextureCache[key] = new PIXI.BaseTexture(data); PIXI.TextureCache[key] = new PIXI.Texture(PIXI.BaseTextureCache[key]); - this._images[key].frameData = Phaser.AnimationParser.spriteSheet(this.game, key, frameWidth, frameHeight, frameMax); - - }, - - /** - * Add a new tile set in to the cache. - * - * @method Phaser.Cache#addTileset - * @param {string} key - The unique key by which you will reference this object. - * @param {string} url - URL of this tile set file. - * @param {object} data - Extra tile set data. - * @param {number} tileWidth - Width of the sprite sheet. - * @param {number} tileHeight - Height of the sprite sheet. - * @param {number} tileMax - How many tiles stored in the sprite sheet. - * @param {number} [tileMargin=0] - If the tiles have been drawn with a margin, specify the amount here. - * @param {number} [tileSpacing=0] - If the tiles have been drawn with spacing between them, specify the amount here. - */ - addTileset: function (key, url, data, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) { - - this._tilesets[key] = { url: url, data: data, tileWidth: tileWidth, tileHeight: tileHeight, tileMargin: tileMargin, tileSpacing: tileSpacing }; - - PIXI.BaseTextureCache[key] = new PIXI.BaseTexture(data); - PIXI.TextureCache[key] = new PIXI.Texture(PIXI.BaseTextureCache[key]); - - this._tilesets[key].tileData = Phaser.TilemapParser.tileset(this.game, key, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing); + this._images[key].frameData = Phaser.AnimationParser.spriteSheet(this.game, key, frameWidth, frameHeight, frameMax, margin, spacing); }, @@ -175,15 +164,13 @@ Phaser.Cache.prototype = { * @method Phaser.Cache#addTilemap * @param {string} key - The unique key by which you will reference this object. * @param {string} url - URL of the tilemap image. - * @param {object} mapData - The tilemap data object. + * @param {object} mapData - The tilemap data object (either a CSV or JSON file). * @param {number} format - The format of the tilemap data. */ addTilemap: function (key, url, mapData, format) { this._tilemaps[key] = { url: url, data: mapData, format: format }; - this._tilemaps[key].layers = Phaser.TilemapParser.parse(this.game, mapData, format); - }, /** @@ -333,12 +320,13 @@ Phaser.Cache.prototype = { decoded = true; } - this._sounds[key] = { url: url, data: data, isDecoding: false, decoded: decoded, webAudio: webAudio, audioTag: audioTag }; + this._sounds[key] = { url: url, data: data, isDecoding: false, decoded: decoded, webAudio: webAudio, audioTag: audioTag, locked: this.game.sound.touchLocked }; }, /** * Reload a sound. + * * @method Phaser.Cache#reloadSound * @param {string} key - Asset key for the sound. */ @@ -359,7 +347,8 @@ Phaser.Cache.prototype = { }, /** - * Description. + * Fires the onSoundUnlock event when the sound has completed reloading. + * * @method Phaser.Cache#reloadSoundComplete * @param {string} key - Asset key for the sound. */ @@ -374,7 +363,8 @@ Phaser.Cache.prototype = { }, /** - * Description. + * Updates the sound object in the cache. + * * @method Phaser.Cache#updateSound * @param {string} key - Asset key for the sound. */ @@ -406,8 +396,8 @@ Phaser.Cache.prototype = { * Get a canvas object from the cache by its key. * * @method Phaser.Cache#getCanvas - * @param {string} key - Asset key of the canvas you want. - * @return {object} The canvas you want. + * @param {string} key - Asset key of the canvas to retrieve from the Cache. + * @return {object} The canvas object. */ getCanvas: function (key) { @@ -415,8 +405,10 @@ Phaser.Cache.prototype = { { return this._canvases[key].canvas; } - - return null; + else + { + console.warn('Phaser.Cache.getCanvas: Invalid key: "' + key + '"'); + } }, @@ -424,7 +416,7 @@ Phaser.Cache.prototype = { * Get a BitmapData object from the cache by its key. * * @method Phaser.Cache#getBitmapData - * @param {string} key - Asset key of the BitmapData object you want. + * @param {string} key - Asset key of the BitmapData object to retrieve from the Cache. * @return {Phaser.BitmapData} The requested BitmapData object if found, or null if not. */ getBitmapData: function (key) { @@ -433,8 +425,10 @@ Phaser.Cache.prototype = { { return this._bitmapDatas[key]; } - - return null; + else + { + console.warn('Phaser.Cache.getBitmapData: Invalid key: "' + key + '"'); + } }, @@ -442,7 +436,7 @@ Phaser.Cache.prototype = { * Checks if an image key exists. * * @method Phaser.Cache#checkImageKey - * @param {string} key - Asset key of the image you want. + * @param {string} key - Asset key of the image to check is in the Cache. * @return {boolean} True if the key exists, otherwise false. */ checkImageKey: function (key) { @@ -460,8 +454,8 @@ Phaser.Cache.prototype = { * Get image data by key. * * @method Phaser.Cache#getImage - * @param {string} key - Asset key of the image you want. - * @return {object} The image data you want. + * @param {string} key - Asset key of the image to retrieve from the Cache. + * @return {object} The image data. */ getImage: function (key) { @@ -469,53 +463,19 @@ Phaser.Cache.prototype = { { return this._images[key].data; } - - return null; - - }, - - /** - * Get tile set image data by key. - * - * @method Phaser.Cache#getTileSetImage - * @param {string} key - Asset key of the image you want. - * @return {object} The image data you want. - */ - getTilesetImage: function (key) { - - if (this._tilesets[key]) + else { - return this._tilesets[key].data; + console.warn('Phaser.Cache.getImage: Invalid key: "' + key + '"'); } - return null; - - }, - - /** - * Get tile set image data by key. - * - * @method Phaser.Cache#getTileset - * @param {string} key - Asset key of the image you want. - * @return {Phaser.Tileset} The tileset data. The tileset image is in the data property, the tile data in tileData. - */ - getTileset: function (key) { - - if (this._tilesets[key]) - { - return this._tilesets[key].tileData; - } - - return null; - }, /** * Get tilemap data by key. * * @method Phaser.Cache#getTilemap - * @param {string} key - Asset key of the tilemap you want. - * @return {Object} The tilemap data. The tileset image is in the data property, the map data in mapData. + * @param {string} key - Asset key of the tilemap data to retrieve from the Cache. + * @return {Object} The raw tilemap data in CSV or JSON format. */ getTilemapData: function (key) { @@ -523,16 +483,19 @@ Phaser.Cache.prototype = { { return this._tilemaps[key]; } + else + { + console.warn('Phaser.Cache.getTilemapData: Invalid key: "' + key + '"'); + } - return null; }, /** * Get frame data by key. * * @method Phaser.Cache#getFrameData - * @param {string} key - Asset key of the frame data you want. - * @return {Phaser.FrameData} The frame data you want. + * @param {string} key - Asset key of the frame data to retrieve from the Cache. + * @return {Phaser.FrameData} The frame data. */ getFrameData: function (key) { @@ -548,8 +511,8 @@ Phaser.Cache.prototype = { * Get a single frame out of a frameData set by key. * * @method Phaser.Cache#getFrameByIndex - * @param {string} key - Asset key of the frame data you want. - * @return {Phaser.Frame} The frame data you want. + * @param {string} key - Asset key of the frame data to retrieve from the Cache. + * @return {Phaser.Frame} The frame object. */ getFrameByIndex: function (key, frame) { @@ -565,8 +528,8 @@ Phaser.Cache.prototype = { * Get a single frame out of a frameData set by key. * * @method Phaser.Cache#getFrameByName - * @param {string} key - Asset key of the frame data you want. - * @return {Phaser.Frame} The frame data you want. + * @param {string} key - Asset key of the frame data to retrieve from the Cache. + * @return {Phaser.Frame} The frame object. */ getFrameByName: function (key, frame) { @@ -582,8 +545,8 @@ Phaser.Cache.prototype = { * Get a single frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image. * * @method Phaser.Cache#getFrame - * @param {string} key - Asset key of the frame data you want. - * @return {Phaser.Frame} The frame data you want. + * @param {string} key - Asset key of the frame data to retrieve from the Cache. + * @return {Phaser.Frame} The frame data. */ getFrame: function (key) { @@ -596,11 +559,11 @@ Phaser.Cache.prototype = { }, /** - * Get a single frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image. + * Get a single texture frame by key. You'd only do this to get the default Frame created for a non-atlas/spritesheet image. * * @method Phaser.Cache#getTextureFrame - * @param {string} key - Asset key of the frame data you want. - * @return {Phaser.Frame} The frame data you want. + * @param {string} key - Asset key of the frame to retrieve from the Cache. + * @return {Phaser.Frame} The frame data. */ getTextureFrame: function (key) { @@ -616,8 +579,8 @@ Phaser.Cache.prototype = { * Get a RenderTexture by key. * * @method Phaser.Cache#getTexture - * @param {string} key - Asset key of the RenderTexture you want. - * @return {Phaser.RenderTexture} The RenderTexture you want. + * @param {string} key - Asset key of the RenderTexture to retrieve from the Cache. + * @return {Phaser.RenderTexture} The RenderTexture object. */ getTexture: function (key) { @@ -625,8 +588,10 @@ Phaser.Cache.prototype = { { return this._textures[key]; } - - return null; + else + { + console.warn('Phaser.Cache.getTexture: Invalid key: "' + key + '"'); + } }, @@ -634,8 +599,8 @@ Phaser.Cache.prototype = { * Get sound by key. * * @method Phaser.Cache#getSound - * @param {string} key - Asset key of the sound you want. - * @return {Phaser.Sound} The sound you want. + * @param {string} key - Asset key of the sound to retrieve from the Cache. + * @return {Phaser.Sound} The sound object. */ getSound: function (key) { @@ -643,8 +608,10 @@ Phaser.Cache.prototype = { { return this._sounds[key]; } - - return null; + else + { + console.warn('Phaser.Cache.getSound: Invalid key: "' + key + '"'); + } }, @@ -652,8 +619,8 @@ Phaser.Cache.prototype = { * Get sound data by key. * * @method Phaser.Cache#getSoundData - * @param {string} key - Asset key of the sound you want. - * @return {object} The sound data you want. + * @param {string} key - Asset key of the sound to retrieve from the Cache. + * @return {object} The sound data. */ getSoundData: function (key) { @@ -661,8 +628,10 @@ Phaser.Cache.prototype = { { return this._sounds[key].data; } - - return null; + else + { + console.warn('Phaser.Cache.getSoundData: Invalid key: "' + key + '"'); + } }, @@ -670,7 +639,7 @@ Phaser.Cache.prototype = { * Check if the given sound has finished decoding. * * @method Phaser.Cache#isSoundDecoded - * @param {string} key - Asset key of the sound you want. + * @param {string} key - Asset key of the sound in the Cache. * @return {boolean} The decoded state of the Sound object. */ isSoundDecoded: function (key) { @@ -686,7 +655,7 @@ Phaser.Cache.prototype = { * Check if the given sound is ready for playback. A sound is considered ready when it has finished decoding and the device is no longer touch locked. * * @method Phaser.Cache#isSoundReady - * @param {string} key - Asset key of the sound you want. + * @param {string} key - Asset key of the sound in the Cache. * @return {boolean} True if the sound is decoded and the device is not touch locked. */ isSoundReady: function (key) { @@ -717,8 +686,8 @@ Phaser.Cache.prototype = { * Get text data by key. * * @method Phaser.Cache#getText - * @param {string} key - Asset key of the text data you want. - * @return {object} The text data you want. + * @param {string} key - Asset key of the text data to retrieve from the Cache. + * @return {object} The text data. */ getText: function (key) { @@ -726,8 +695,30 @@ Phaser.Cache.prototype = { { return this._text[key].data; } + else + { + console.warn('Phaser.Cache.getText: Invalid key: "' + key + '"'); + } + + }, - return null; + /** + * Get binary data by key. + * + * @method Phaser.Cache#getBinary + * @param {string} key - Asset key of the binary data object to retrieve from the Cache. + * @return {object} The binary data object. + */ + getBinary: function (key) { + + if (this._binary[key]) + { + return this._binary[key]; + } + else + { + console.warn('Phaser.Cache.getBinary: Invalid key: "' + key + '"'); + } }, @@ -745,7 +736,7 @@ Phaser.Cache.prototype = { for (var item in array) { - if (item !== '__default') + if (item !== '__default' && item !== '__missing') { output.push(item); } @@ -854,3 +845,5 @@ Phaser.Cache.prototype = { } }; + +Phaser.Cache.prototype.constructor = Phaser.Cache; diff --git a/src/loader/Loader.js b/src/loader/Loader.js index 9213eebb..01ddad88 100644 --- a/src/loader/Loader.js +++ b/src/loader/Loader.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -34,7 +34,7 @@ Phaser.Loader = function (game) { this._fileIndex = 0; /** - * @property {number} _progressChunk - Indicates assets loading progress. (from 0 to 100) + * @property {number} _progressChunk - Indicates the size of 1 file in terms of a percentage out of 100. * @private * @default */ @@ -59,11 +59,17 @@ Phaser.Loader = function (game) { this.hasLoaded = false; /** - * @property {number} progress - The Load progress percentage value (from 0 to 100) + * @property {number} progress - The rounded load progress percentage value (from 0 to 100) * @default */ this.progress = 0; + /** + * @property {number} progressFloat - The non-rounded load progress value (from 0.0 to 100.0) + * @default + */ + this.progressFloat = 0; + /** * You can optionally link a sprite to the preloader. * If you do so the Sprite's width or height will be cropped based on the percentage loaded. @@ -363,6 +369,29 @@ Phaser.Loader.prototype = { }, + /** + * Add a binary file to the Loader. It will be loaded via xhr with a responseType of "arraybuffer". You can specify an optional callback to process the file after load. + * When the callback is called it will be passed 2 parameters: the key of the file and the file data. + * WARNING: If you specify a callback, the file data will be set to whatever your callback returns. So always return the data object, even if you didn't modify it. + * + * @method Phaser.Loader#binary + * @param {string} key - Unique asset key of the binary file. + * @param {string} url - URL of the binary file. + * @param {function} [callback] - Optional callback that will be passed the file after loading, so you can perform additional processing on it. + * @param {function} [callbackContext] - The context under which the callback will be applied. If not specified it will use the callback itself as the context. + * @return {Phaser.Loader} This Loader instance. + */ + binary: function (key, url, callback, callbackContext) { + + if (typeof callback === 'undefined') { callback = false; } + if (callback !== false && typeof callbackContext === 'undefined') { callbackContext = callback; } + + this.addToFileList('binary', key, url, { callback: callback, callbackContext: callbackContext }); + + return this; + + }, + /** * Add a new sprite sheet to the loader. * @@ -372,38 +401,17 @@ Phaser.Loader.prototype = { * @param {number} frameWidth - Width of each single frame. * @param {number} frameHeight - Height of each single frame. * @param {number} [frameMax=-1] - How many frames in this sprite sheet. If not specified it will divide the whole image into frames. + * @param {number} [margin=0] - If the frames have been drawn with a margin, specify the amount here. + * @param {number} [spacing=0] - If the frames have been drawn with spacing between them, specify the amount here. * @return {Phaser.Loader} This Loader instance. */ - spritesheet: function (key, url, frameWidth, frameHeight, frameMax) { + spritesheet: function (key, url, frameWidth, frameHeight, frameMax, margin, spacing) { if (typeof frameMax === "undefined") { frameMax = -1; } + if (typeof margin === "undefined") { margin = 0; } + if (typeof spacing === "undefined") { spacing = 0; } - this.addToFileList('spritesheet', key, url, { frameWidth: frameWidth, frameHeight: frameHeight, frameMax: frameMax }); - - return this; - - }, - - /** - * Add a new tile set to the loader. These are used in the rendering of tile maps. - * - * @method Phaser.Loader#tileset - * @param {string} key - Unique asset key of the tileset file. - * @param {string} url - URL of the tileset. - * @param {number} tileWidth - Width of each single tile in pixels. - * @param {number} tileHeight - Height of each single tile in pixels. - * @param {number} [tileMax=-1] - How many tiles in this tileset. If not specified it will divide the whole image into tiles. - * @param {number} [tileMargin=0] - If the tiles have been drawn with a margin, specify the amount here. - * @param {number} [tileSpacing=0] - If the tiles have been drawn with spacing between them, specify the amount here. - * @return {Phaser.Loader} This Loader instance. - */ - tileset: function (key, url, tileWidth, tileHeight, tileMax, tileMargin, tileSpacing) { - - if (typeof tileMax === "undefined") { tileMax = -1; } - if (typeof tileMargin === "undefined") { tileMargin = 0; } - if (typeof tileSpacing === "undefined") { tileSpacing = 0; } - - this.addToFileList('tileset', key, url, { tileWidth: tileWidth, tileHeight: tileHeight, tileMax: tileMax, tileMargin: tileMargin, tileSpacing: tileSpacing }); + this.addToFileList('spritesheet', key, url, { frameWidth: frameWidth, frameHeight: frameHeight, frameMax: frameMax, margin: margin, spacing: spacing }); return this; @@ -711,6 +719,7 @@ Phaser.Loader.prototype = { } this.progress = 0; + this.progressFloat = 0; this.hasLoaded = false; this.isLoading = true; @@ -725,6 +734,7 @@ Phaser.Loader.prototype = { else { this.progress = 100; + this.progressFloat = 100; this.hasLoaded = true; this.onLoadComplete.dispatch(); } @@ -755,7 +765,6 @@ Phaser.Loader.prototype = { case 'spritesheet': case 'textureatlas': case 'bitmapfont': - case 'tileset': file.data = new Image(); file.data.name = file.key; file.data.onload = function () { @@ -846,6 +855,7 @@ Phaser.Loader.prototype = { break; case 'text': + case 'script': this._xhr.open("GET", this.baseURL + file.url, true); this._xhr.responseType = "text"; this._xhr.onload = function () { @@ -857,10 +867,9 @@ Phaser.Loader.prototype = { this._xhr.send(); break; - case 'script': - + case 'binary': this._xhr.open("GET", this.baseURL + file.url, true); - this._xhr.responseType = "text"; + this._xhr.responseType = "arraybuffer"; this._xhr.onload = function () { return _this.fileComplete(_this._fileIndex); }; @@ -933,7 +942,6 @@ Phaser.Loader.prototype = { console.warn('Phaser.Loader fileComplete invalid index ' + index); return; } - var file = this._fileList[index]; file.loaded = true; @@ -950,12 +958,7 @@ Phaser.Loader.prototype = { case 'spritesheet': - this.game.cache.addSpriteSheet(file.key, file.url, file.data, file.frameWidth, file.frameHeight, file.frameMax); - break; - - case 'tileset': - - this.game.cache.addTileset(file.key, file.url, file.data, file.tileWidth, file.tileHeight, file.tileMax, file.tileMargin, file.tileSpacing); + this.game.cache.addSpriteSheet(file.key, file.url, file.data, file.frameWidth, file.frameHeight, file.frameMax, file.margin, file.spacing); break; case 'textureatlas': @@ -1038,6 +1041,7 @@ Phaser.Loader.prototype = { if (buffer) { that.game.cache.decodedSound(key, buffer); + that.game.sound.onSoundDecode.dispatch(key, that.game.cache.getSound(key)); } }); } @@ -1062,6 +1066,20 @@ Phaser.Loader.prototype = { file.data.text = this._xhr.responseText; document.head.appendChild(file.data); break; + + case 'binary': + if (file.callback) + { + file.data = file.callback.call(file.callbackContext, file.key, this._xhr.response); + } + else + { + file.data = this._xhr.response; + } + + this.game.cache.addBinary(file.key, file.data); + + break; } if (loadNext) @@ -1207,7 +1225,8 @@ Phaser.Loader.prototype = { */ nextFile: function (previousIndex, success) { - this.progress = Math.round(this.progress + this._progressChunk); + this.progressFloat += this._progressChunk; + this.progress = Math.round(this.progressFloat); if (this.progress > 100) { @@ -1290,3 +1309,5 @@ Phaser.Loader.prototype = { } }; + +Phaser.Loader.prototype.constructor = Phaser.Loader; diff --git a/src/loader/LoaderParser.js b/src/loader/LoaderParser.js index 0f91830c..5de53f8a 100644 --- a/src/loader/LoaderParser.js +++ b/src/loader/LoaderParser.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ diff --git a/src/math/Math.js b/src/math/Math.js index c0344090..feec5c53 100644 --- a/src/math/Math.js +++ b/src/math/Math.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -327,7 +327,7 @@ Phaser.Math = { }, /** - * Find the angle of a segment from (x1, y1) -> (x2, y2 ). + * Find the angle of a segment from (x1, y1) -> (x2, y2). * @method Phaser.Math#angleBetween * @param {number} x1 * @param {number} y1 @@ -340,24 +340,58 @@ Phaser.Math = { }, /** - * Set an angle within the bounds of -π toπ. - * @method Phaser.Math#normalizeAngle - * @param {number} angle - * @param {boolean} radians - True if angle size is expressed in radians. - * @return {number} + * Reverses an angle. + * @method Phaser.Math#reverseAngle + * @param {number} angleRad - The angle to reverse, in radians. + * @return {number} Returns the reverse angle, in radians. */ - normalizeAngle: function (angle, radians) { + reverseAngle: function (angleRad) { + return this.normalizeAngle(angleRad + Math.PI, true); + }, - if (typeof radians === "undefined") { radians = true; } + /** + * Normalizes an angle to the [0,2pi) range. + * @method Phaser.Math#normalizeAngle + * @param {number} angleRad - The angle to normalize, in radians. + * @return {number} Returns the angle, fit within the [0,2pi] range, in radians. + */ + normalizeAngle: function (angleRad) { - var rd = (radians) ? Math.PI : 180; - return this.wrap(angle, -rd, rd); + angleRad = angleRad % (2 * Math.PI); + return angleRad >= 0 ? angleRad : angleRad + 2 * Math.PI; }, /** - * Closest angle between two angles from a1 to a2 - * absolute value the return for exact angle + * Normalizes a latitude to the [-90,90] range. Latitudes above 90 or below -90 are capped, not wrapped. + * @method Phaser.Math#normalizeLatitude + * @param {number} lat - The latitude to normalize, in degrees. + * @return {number} Returns the latitude, fit within the [-90,90] range. + */ + normalizeLatitude: function (lat) { + return Math.max(-90, Math.min(90, lat)); + }, + + /** + * Normalizes a longitude to the [-180,180] range. Longitudes above 180 or below -180 are wrapped. + * @method Phaser.Math#normalizeLongitude + * @param {number} lng - The longitude to normalize, in degrees. + * @return {number} Returns the longitude, fit within the [-180,180] range. + */ + normalizeLongitude: function (lng) { + + if (lng % 360 == 180) + { + return 180; + } + + lng = lng % 360; + return lng < -180 ? lng + 360 : lng > 180 ? lng - 360 : lng; + + }, + + /** + * Closest angle between two angles from a1 to a2 absolute value the return for exact angle * @method Phaser.Math#nearestAngleBetween * @param {number} a1 * @param {number} a2 @@ -511,13 +545,13 @@ Phaser.Math = { /** * Ensures that the value always stays between min and max, by wrapping the value around. - *

    max should be larger than min, or the function will return 0

    + * max should be larger than min, or the function will return 0. * * @method Phaser.Math#wrap - * @param value The value to wrap - * @param min The minimum the value is allowed to be - * @param max The maximum the value is allowed to be - * @return {number} The wrapped value + * @param {number} value - The value to wrap. + * @param {number} min - The minimum the value is allowed to be. + * @param {number} max - The maximum the value is allowed to be. + * @return {number} The wrapped value. */ wrap: function (value, min, max) { @@ -626,7 +660,7 @@ Phaser.Math = { }, /** - * Significantly faster version of Math.min + * Updated version of Math.min that can be passed either an array of numbers or the numbers as parameters. * See http://jsperf.com/math-s-min-max-vs-homemade/5 * * @method Phaser.Math#min @@ -634,15 +668,113 @@ Phaser.Math = { */ min: function () { - for (var i =1 , min = 0, len = arguments.length; i < len; i++) + if (arguments.length === 1 && typeof arguments[0] === 'object') { - if (arguments[i] < arguments[min]) + var data = arguments[0]; + } + else + { + var data = arguments; + } + + for (var i = 1, min = 0, len = data.length; i < len; i++) + { + if (data[i] < data[min]) { min = i; } } - return arguments[min]; + return data[min]; + + }, + + /** + * Updated version of Math.max that can be passed either an array of numbers or the numbers as parameters. + * + * @method Phaser.Math#max + * @return {number} The largest value from those given. + */ + max: function () { + + if (arguments.length === 1 && typeof arguments[0] === 'object') + { + var data = arguments[0]; + } + else + { + var data = arguments; + } + + for (var i = 1, max = 0, len = data.length; i < len; i++) + { + if (data[i] > data[max]) + { + max = i; + } + } + + return data[max]; + + }, + + /** + * Updated version of Math.min that can be passed a property and either an array of objects or the objects as parameters. + * It will find the lowest matching property value from the given objects. + * + * @method Phaser.Math#minProperty + * @return {number} The lowest value from those given. + */ + minProperty: function (property) { + + if (arguments.length === 2 && typeof arguments[1] === 'object') + { + var data = arguments[1]; + } + else + { + var data = arguments.slice(1); + } + + for (var i = 1, min = 0, len = data.length; i < len; i++) + { + if (data[i][property] < data[min][property]) + { + min = i; + } + } + + return data[min][property]; + + }, + + /** + * Updated version of Math.max that can be passed a property and either an array of objects or the objects as parameters. + * It will find the largest matching property value from the given objects. + * + * @method Phaser.Math#maxProperty + * @return {number} The largest value from those given. + */ + maxProperty: function (property) { + + if (arguments.length === 2 && typeof arguments[1] === 'object') + { + var data = arguments[1]; + } + else + { + var data = arguments.slice(1); + } + + for (var i = 1, max = 0, len = data.length; i < len; i++) + { + if (data[i][property] > data[max][property]) + { + max = i; + } + } + + return data[max][property]; }, @@ -688,7 +820,7 @@ Phaser.Math = { }, /** - * Description. + * A Linear Interpolation Method, mostly used by Phaser.Tween. * @method Phaser.Math#linearInterpolation * @param {number} v * @param {number} k @@ -715,7 +847,7 @@ Phaser.Math = { }, /** - * Description. + * A Bezier Interpolation Method, mostly used by Phaser.Tween. * @method Phaser.Math#bezierInterpolation * @param {number} v * @param {number} k @@ -736,7 +868,7 @@ Phaser.Math = { }, /** - * Description. + * A Catmull Rom Interpolation Method, mostly used by Phaser.Tween. * @method Phaser.Math#catmullRomInterpolation * @param {number} v * @param {number} k @@ -971,7 +1103,7 @@ Phaser.Math = { * @param {number} y1 * @param {number} x2 * @param {number} y2 - * @return {number} The distance between this Point object and the destination Point object. + * @return {number} The distance between the two sets of coordinates. */ distance: function (x1, y1, x2, y2) { @@ -982,6 +1114,25 @@ Phaser.Math = { }, + /** + * Returns the distance between the two given set of coordinates at the power given. + * + * @method Phaser.Math#distancePow + * @param {number} x1 + * @param {number} y1 + * @param {number} x2 + * @param {number} y2 + * @param {number} [pow=2] + * @return {number} The distance between the two sets of coordinates. + */ + distancePow: function (x1, y1, x2, y2, pow) { + + if (typeof pow === 'undefined') { pow = 2; } + + return Math.sqrt(Math.pow(x2 - x1, pow) + Math.pow(y2 - y1, pow)); + + }, + /** * Returns the rounded distance between the two given set of coordinates. * diff --git a/src/math/QuadTree.js b/src/math/QuadTree.js index 5f2bd374..b145d0d1 100644 --- a/src/math/QuadTree.js +++ b/src/math/QuadTree.js @@ -1,22 +1,22 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ /** - * Javascript QuadTree - * @version 1.0 - * @author Timo Hausmann - * - * @version 1.2, September 4th 2013 - * @author Richard Davey - * The original code was a conversion of the Java code posted to GameDevTuts. However I've tweaked - * it massively to add node indexing, removed lots of temp. var creation and significantly - * increased performance as a result. - * - * Original version at https://github.com/timohausmann/quadtree-js/ - */ +* Javascript QuadTree +* @version 1.0 +* @author Timo Hausmann +* +* @version 1.2, September 4th 2013 +* @author Richard Davey +* The original code was a conversion of the Java code posted to GameDevTuts. However I've tweaked +* it massively to add node indexing, removed lots of temp. var creation and significantly +* increased performance as a result. +* +* Original version at https://github.com/timohausmann/quadtree-js/ +*/ /** * @copyright © 2012 Timo Hausmann @@ -42,27 +42,23 @@ */ /** - * QuadTree Constructor - * - * @class Phaser.QuadTree - * @classdesc A QuadTree implementation. The original code was a conversion of the Java code posted to GameDevTuts. However I've tweaked - * it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result. Original version at https://github.com/timohausmann/quadtree-js/ - * @constructor - * @param {Description} physicsManager - Description. - * @param {Description} x - Description. - * @param {Description} y - Description. - * @param {number} width - The width of your game in game pixels. - * @param {number} height - The height of your game in game pixels. - * @param {number} maxObjects - Description. - * @param {number} maxLevels - Description. - * @param {number} level - Description. - */ -Phaser.QuadTree = function (physicsManager, x, y, width, height, maxObjects, maxLevels, level) { +* QuadTree Constructor +* +* @class Phaser.QuadTree +* @classdesc A QuadTree implementation. The original code was a conversion of the Java code posted to GameDevTuts. +* However I've tweaked it massively to add node indexing, removed lots of temp. var creation and significantly increased performance as a result. +* Original version at https://github.com/timohausmann/quadtree-js/ +* @constructor +* @param {number} x - The top left coordinate of the quadtree. +* @param {number} y - The top left coordinate of the quadtree. +* @param {number} width - The width of the quadtree in pixels. +* @param {number} height - The height of the quadtree in pixels. +* @param {number} [maxObjects=10] - The maximum number of objects per node. +* @param {number} [maxLevels=4] - The maximum number of levels to iterate to. +* @param {number} [level=0] - Which level is this? +*/ +Phaser.QuadTree = function (x, y, width, height, maxObjects, maxLevels, level) { - this.physicsManager = physicsManager; - this.ID = physicsManager.quadTreeID; - physicsManager.quadTreeID++; - this.maxObjects = maxObjects || 10; this.maxLevels = maxLevels || 4; this.level = level || 0; @@ -86,35 +82,60 @@ Phaser.QuadTree = function (physicsManager, x, y, width, height, maxObjects, max Phaser.QuadTree.prototype = { /* - * Split the node into 4 subnodes + * Populates this quadtree with the members of the given Group. * - * @method Phaser.QuadTree#split + * @method Phaser.QuadTree#populate + * @param {Phaser.Group} group - The Group to add to the quadtree. */ - split: function() { + populate: function (group) { - this.level++; - - // top right node - this.nodes[0] = new Phaser.QuadTree(this.physicsManager, this.bounds.right, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); - - // top left node - this.nodes[1] = new Phaser.QuadTree(this.physicsManager, this.bounds.x, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); - - // bottom left node - this.nodes[2] = new Phaser.QuadTree(this.physicsManager, this.bounds.x, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); - - // bottom right node - this.nodes[3] = new Phaser.QuadTree(this.physicsManager, this.bounds.right, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); + group.forEach(this.populateHandler, this, true); }, /* - * Insert the object into the node. If the node - * exceeds the capacity, it will split and add all - * objects to their corresponding subnodes. + * Handler for the populate method. + * + * @method Phaser.QuadTree#populateHandler + * @param {Phaser.Sprite} sprite - The Sprite to check. + */ + populateHandler: function (sprite) { + + if (sprite.body && sprite.body.checkCollision.none === false && sprite.alive) + { + this.insert(sprite.body); + } + + }, + + /* + * Split the node into 4 subnodes + * + * @method Phaser.QuadTree#split + */ + split: function () { + + this.level++; + + // top right node + this.nodes[0] = new Phaser.QuadTree(this.bounds.right, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); + + // top left node + this.nodes[1] = new Phaser.QuadTree(this.bounds.x, this.bounds.y, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); + + // bottom left node + this.nodes[2] = new Phaser.QuadTree(this.bounds.x, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); + + // bottom right node + this.nodes[3] = new Phaser.QuadTree(this.bounds.right, this.bounds.bottom, this.bounds.subWidth, this.bounds.subHeight, this.maxObjects, this.maxLevels, this.level); + + }, + + /* + * Insert the object into the node. If the node exceeds the capacity, it will split and add all objects to their corresponding subnodes. * * @method Phaser.QuadTree#insert - * @param {object} body - Description. + * @param {Phaser.Physics.Arcade.Body|object} body - The Body object to insert into the quadtree. */ insert: function (body) { @@ -166,7 +187,7 @@ Phaser.QuadTree.prototype = { * Determine which node the object belongs to. * * @method Phaser.QuadTree#getIndex - * @param {object} rect - Description. + * @param {Phaser.Rectangle|object} rect - The bounds in which to check. * @return {number} index - Index of the subnode (0-3), or -1 if rect cannot completely fit within a subnode and is part of the parent node. */ getIndex: function (rect) { @@ -206,12 +227,12 @@ Phaser.QuadTree.prototype = { }, - /* - * Return all objects that could collide with the given object. + /* + * Return all objects that could collide with the given Sprite. * * @method Phaser.QuadTree#retrieve - * @param {object} rect - Description. - * @Return {array} - Array with all detected objects. + * @param {Phaser.Sprite} sprite - The sprite to check against. + * @return {array} - Array with all detected objects. */ retrieve: function (sprite) { @@ -220,7 +241,7 @@ Phaser.QuadTree.prototype = { sprite.body.quadTreeIndex = this.getIndex(sprite.body); // Temp store for the node IDs this sprite is in, we can use this for fast elimination later - sprite.body.quadTreeIDs.push(this.ID); + // sprite.body.quadTreeIDs.push(this.ID); if (this.nodes[0]) { @@ -253,7 +274,6 @@ Phaser.QuadTree.prototype = { for (var i = 0, len = this.nodes.length; i < len; i++) { - // if (typeof this.nodes[i] !== 'undefined') if (this.nodes[i]) { this.nodes[i].clear(); @@ -263,3 +283,5 @@ Phaser.QuadTree.prototype = { } }; + +Phaser.QuadTree.prototype.constructor = Phaser.QuadTree; diff --git a/src/math/RandomDataGenerator.js b/src/math/RandomDataGenerator.js index afffa5ce..6a7e95b6 100644 --- a/src/math/RandomDataGenerator.js +++ b/src/math/RandomDataGenerator.js @@ -2,7 +2,7 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -245,3 +245,5 @@ Phaser.RandomDataGenerator.prototype = { } }; + +Phaser.RandomDataGenerator.prototype.constructor = Phaser.RandomDataGenerator; diff --git a/src/net/Net.js b/src/net/Net.js index b41fb5b6..7537d9cf 100644 --- a/src/net/Net.js +++ b/src/net/Net.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -128,8 +128,8 @@ Phaser.Net.prototype = { var output = {}; var keyValues = location.search.substring(1).split('&'); - for (var i in keyValues) { - + for (var i in keyValues) + { var key = keyValues[i].split('='); if (key.length > 1) @@ -162,3 +162,5 @@ Phaser.Net.prototype = { } }; + +Phaser.Net.prototype.constructor = Phaser.Net; diff --git a/src/particles/Particles.js b/src/particles/Particles.js index 9d0f15b1..edad824b 100644 --- a/src/particles/Particles.js +++ b/src/particles/Particles.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -76,4 +76,6 @@ Phaser.Particles.prototype = { } -}; \ No newline at end of file +}; + +Phaser.Particles.prototype.constructor = Phaser.Particles; diff --git a/src/particles/arcade/Emitter.js b/src/particles/arcade/Emitter.js index ab977f69..444d30fe 100644 --- a/src/particles/arcade/Emitter.js +++ b/src/particles/arcade/Emitter.js @@ -1,6 +1,6 @@ /** * @author Richard Davey -* @copyright 2013 Photon Storm Ltd. +* @copyright 2014 Photon Storm Ltd. * @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License} */ @@ -22,7 +22,6 @@ Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) { /** - * The total number of particles in this emitter. * @property {number} maxParticles - The total number of particles in this emitter.. * @default */ @@ -36,7 +35,8 @@ Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) { this.name = 'emitter' + this.game.particles.ID++; /** - * @property {Description} type - Description. + * @property {number} type - Internal Phaser Type value. + * @protected */ this.type = Phaser.EMITTER; @@ -65,140 +65,114 @@ Phaser.Particles.Arcade.Emitter = function (game, x, y, maxParticles) { this.height = 1; /** - * The minimum possible velocity of a particle. - * The default value is (-100,-100). - * @property {Phaser.Point} minParticleSpeed + * @property {Phaser.Point} minParticleSpeed - The minimum possible velocity of a particle. + * @default */ this.minParticleSpeed = new Phaser.Point(-100, -100); /** - * The maximum possible velocity of a particle. - * The default value is (100,100). - * @property {Phaser.Point} maxParticleSpeed + * @property {Phaser.Point} maxParticleSpeed - The maximum possible velocity of a particle. + * @default */ this.maxParticleSpeed = new Phaser.Point(100, 100); /** - * The minimum possible scale of a particle. - * The default value is 1. - * @property {number} minParticleScale + * @property {number} minParticleScale - The minimum possible scale of a particle. * @default */ this.minParticleScale = 1; /** - * The maximum possible scale of a particle. - * The default value is 1. - * @property {number} maxParticleScale + * @property {number} maxParticleScale - The maximum possible scale of a particle. * @default */ this.maxParticleScale = 1; /** - * The minimum possible angular velocity of a particle. The default value is -360. - * @property {number} minRotation + * @property {number} minRotation - The minimum possible angular velocity of a particle. * @default */ this.minRotation = -360; /** - * The maximum possible angular velocity of a particle. The default value is 360. - * @property {number} maxRotation + * @property {number} maxRotation - The maximum possible angular velocity of a particle. * @default */ this.maxRotation = 360; /** - * Sets the gravity.y of each particle to this value on launch. - * @property {number} gravity + * @property {number} gravity - Sets the `body.gravity.y` of each particle sprite to this value on launch. * @default */ - this.gravity = 2; + this.gravity = 100; /** - * Set your own particle class type here. - * @property {Description} particleClass + * @property {any} particleClass - For emitting your own particle class types. * @default */ this.particleClass = null; /** - * The X and Y drag component of particles launched from the emitter. - * @property {Phaser.Point} particleDrag + * @property {number} particleFriction - The friction component of particles launched from the emitter. + * @default */ - this.particleDrag = new Phaser.Point(); + this.particleFriction = 0; /** - * The angular drag component of particles launched from the emitter if they are rotating. - * @property {number} angularDrag + * @property {number} angularDrag - The angular drag component of particles launched from the emitter if they are rotating. * @default */ this.angularDrag = 0; /** - * How often a particle is emitted in ms (if emitter is started with Explode === false). - * @property {boolean} frequency + * @property {boolean} frequency - How often a particle is emitted in ms (if emitter is started with Explode === false). * @default */ this.frequency = 100; /** - * How long each particle lives once it is emitted in ms. Default is 2 seconds. - * Set lifespan to 'zero' for particles to live forever. - * @property {number} lifespan + * @property {number} lifespan - How long each particle lives once it is emitted in ms. Default is 2 seconds. Set lifespan to 'zero' for particles to live forever. * @default */ this.lifespan = 2000; /** - * How much each particle should bounce on each axis. 1 = full bounce, 0 = no bounce. - * @property {Phaser.Point} bounce + * @property {Phaser.Point} bounce - How much each particle should bounce on each axis. 1 = full bounce, 0 = no bounce. */ this.bounce = new Phaser.Point(); /** - * Internal helper for deciding how many particles to launch. - * @property {number} _quantity + * @property {number} _quantity - Internal helper for deciding how many particles to launch. * @private - * @default */ this._quantity = 0; /** - * Internal helper for deciding when to launch particles or kill them. - * @property {number} _timer + * @property {number} _timer - Internal helper for deciding when to launch particles or kill them. * @private - * @default */ this._timer = 0; /** - * Internal counter for figuring out how many particles to launch. - * @property {number} _counter + * @property {number} _counter - Internal counter for figuring out how many particles to launch. * @private - * @default */ this._counter = 0; /** - * Internal helper for the style of particle emission (all at once, or one at a time). - * @property {boolean} _explode + * @property {boolean} _explode - Internal helper for the style of particle emission (all at once, or one at a time). * @private - * @default */ this._explode = true; /** - * Determines whether the emitter is currently emitting particles. - * It is totally safe to directly toggle this. - * @property {boolean} on + * @property {boolean} on - Determines whether the emitter is currently emitting particles. It is totally safe to directly toggle this. * @default */ this.on = false; /** - * Determines whether the emitter is being updated by the core game loop. - * @property {boolean} exists + * @property {boolean} exists - Determines whether the emitter is being updated by the core game loop. * @default */ this.exists = true; @@ -272,43 +246,35 @@ Phaser.Particles.Arcade.Emitter.prototype.update = function () { * This function generates a new array of particle sprites to attach to the emitter. * * @method Phaser.Particles.Arcade.Emitter#makeParticles -* @param {Description} keys - Description. -* @param {number} frames - Description. -* @param {number} quantity - The number of particles to generate when using the "create from image" option. -* @param {number} collide - Description. -* @param {boolean} collideWorldBounds - Description. -* @return This Emitter instance (nice for chaining stuff together, if you're into that). +* @param {array|string} keys - A string or an array of strings that the particle sprites will use as their texture. If an array one is picked at random. +* @param {array|number} frames - A frame number, or array of frames that the sprite will use. If an array one is picked at random. +* @param {number} quantity - The number of particles to generate. +* @param {boolean} [collide=false] - Sets the checkCollision.none flag on the particle sprites body. +* @param {boolean} [collideWorldBounds=false] - A particle can be set to collide against the World bounds automatically and rebound back into the World if this is set to true. Otherwise it will leave the World. +* @return {Phaser.Particles.Arcade.Emitter} This Emitter instance. */ Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames, quantity, collide, collideWorldBounds) { - if (typeof frames == 'undefined') - { - frames = 0; - } - - quantity = quantity || this.maxParticles; - collide = collide || 0; - - if (typeof collideWorldBounds == 'undefined') - { - collideWorldBounds = false; - } + if (typeof frames === 'undefined') { frames = 0; } + if (typeof quantity === 'undefined') { quantity = this.maxParticles; } + if (typeof collide === 'undefined') { collide = false; } + if (typeof collideWorldBounds === 'undefined') { collideWorldBounds = false; } var particle; var i = 0; var rndKey = keys; - var rndFrame = 0; + var rndFrame = frames; while (i < quantity) { - if (this.particleClass == null) + if (this.particleClass === null) { - if (typeof keys == 'object') + if (typeof keys === 'object') { rndKey = this.game.rnd.pick(keys); } - if (typeof frames == 'object') + if (typeof frames === 'object') { rndFrame = this.game.rnd.pick(frames); } @@ -320,14 +286,14 @@ Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames // particle = new this.particleClass(this.game); // } - if (collide > 0) + if (collide) { - particle.body.allowCollision.any = true; - particle.body.allowCollision.none = false; + particle.body.checkCollision.any = true; + particle.body.checkCollision.none = false; } else { - particle.body.allowCollision.none = true; + particle.body.checkCollision.none = true; } particle.body.collideWorldBounds = collideWorldBounds; @@ -347,9 +313,9 @@ Phaser.Particles.Arcade.Emitter.prototype.makeParticles = function (keys, frames } /** - * Call this function to turn off all the particles and the emitter. - * @method Phaser.Particles.Arcade.Emitter#kill - */ +* Call this function to turn off all the particles and the emitter. +* @method Phaser.Particles.Arcade.Emitter#kill +*/ Phaser.Particles.Arcade.Emitter.prototype.kill = function () { this.on = false; @@ -359,10 +325,9 @@ Phaser.Particles.Arcade.Emitter.prototype.kill = function () { } /** - * Handy for bringing game objects "back to life". Just sets alive and exists back to true. - * In practice, this is most often called by Object.reset(). - * @method Phaser.Particles.Arcade.Emitter#revive - */ +* Handy for bringing game objects "back to life". Just sets alive and exists back to true. +* @method Phaser.Particles.Arcade.Emitter#revive +*/ Phaser.Particles.Arcade.Emitter.prototype.revive = function () { this.alive = true; @@ -371,27 +336,19 @@ Phaser.Particles.Arcade.Emitter.prototype.revive = function () { } /** - * Call this function to start emitting particles. - * @method Phaser.Particles.Arcade.Emitter#start - * @param {boolean} explode - Whether the particles should all burst out at once. - * @param {number} lifespan - How long each particle lives once emitted. 0 = forever. - * @param {number} frequency - Ignored if Explode is set to true. Frequency is how often to emit a particle in ms. - * @param {number} quantity - How many particles to launch. 0 = "all of the particles". - */ +* Call this function to start emitting particles. +* @method Phaser.Particles.Arcade.Emitter#start +* @param {boolean} [explode=true] - Whether the particles should all burst out at once. +* @param {number} [lifespan=0] - How long each particle lives once emitted. 0 = forever. +* @param {number} [frequency=250] - Ignored if Explode is set to true. Frequency is how often to emit a particle in ms. +* @param {number} [quantity=0] - How many particles to launch. 0 = "all of the particles". +*/ Phaser.Particles.Arcade.Emitter.prototype.start = function (explode, lifespan, frequency, quantity) { - if (typeof explode !== 'boolean') - { - explode = true; - } - - lifespan = lifespan || 0; - - // How many ms between emissions? - frequency = frequency || 250; - - // Total number of particles to emit - quantity = quantity || 0; + if (typeof explode === 'undefined') { explode = true; } + if (typeof lifespan === 'undefined') { lifespan = 0; } + if (typeof frequency === 'undefined') { frequency = 250; } + if (typeof quantity === 'undefined') { quantity = 0; } this.revive(); @@ -417,9 +374,9 @@ Phaser.Particles.Arcade.Emitter.prototype.start = function (explode, lifespan, f } /** - * This function can be used both internally and externally to emit the next particle. - * @method Phaser.Particles.Arcade.Emitter#emitParticle - */ +* This function can be used both internally and externally to emit the next particle. +* @method Phaser.Particles.Arcade.Emitter#emitParticle +*/ Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () { var particle = this.getFirstExists(false); @@ -477,8 +434,7 @@ Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () { particle.scale.setTo(scale, scale); } - particle.body.drag.x = this.particleDrag.x; - particle.body.drag.y = this.particleDrag.y; + particle.body.friction = this.particleFriction; particle.body.angularDrag = this.angularDrag; } @@ -486,8 +442,8 @@ Phaser.Particles.Arcade.Emitter.prototype.emitParticle = function () { /** * A more compact way of setting the width and height of the emitter. * @method Phaser.Particles.Arcade.Emitter#setSize -* @param {number} width - The desired width of the emitter (particles are spawned randomly within these dimensions). -* @param {number} height - The desired height of the emitter. +* @param {number} width - The desired width of the emitter (particles are spawned randomly within these dimensions). +* @param {number} height - The desired height of the emitter. */ Phaser.Particles.Arcade.Emitter.prototype.setSize = function (width, height) { @@ -499,8 +455,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setSize = function (width, height) { /** * A more compact way of setting the X velocity range of the emitter. * @method Phaser.Particles.Arcade.Emitter#setXSpeed -* @param {number} min - The minimum value for this range. -* @param {number} max - The maximum value for this range. +* @param {number} [min=0] - The minimum value for this range. +* @param {number} [max=0] - The maximum value for this range. */ Phaser.Particles.Arcade.Emitter.prototype.setXSpeed = function (min, max) { @@ -515,8 +471,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setXSpeed = function (min, max) { /** * A more compact way of setting the Y velocity range of the emitter. * @method Phaser.Particles.Arcade.Emitter#setYSpeed -* @param {number} min - The minimum value for this range. -* @param {number} max - The maximum value for this range. +* @param {number} [min=0] - The minimum value for this range. +* @param {number} [max=0] - The maximum value for this range. */ Phaser.Particles.Arcade.Emitter.prototype.setYSpeed = function (min, max) { @@ -531,8 +487,8 @@ Phaser.Particles.Arcade.Emitter.prototype.setYSpeed = function (min, max) { /** * A more compact way of setting the angular velocity constraints of the emitter. * @method Phaser.Particles.Arcade.Emitter#setRotation -* @param {number} min - The minimum value for this range. -* @param {number} max - The maximum value for this range. +* @param {number} [min=0] - The minimum value for this range. +* @param {number} [max=0] - The maximum value for this range. */ Phaser.Particles.Arcade.Emitter.prototype.setRotation = function (min, max) { @@ -545,14 +501,17 @@ Phaser.Particles.Arcade.Emitter.prototype.setRotation = function (min, max) { } /** -* Change the emitter's midpoint to match the midpoint of a Object. +* Change the emitters center to match the center of any object with a `center` property, such as a Sprite. * @method Phaser.Particles.Arcade.Emitter#at -* @param {object} object - The Object that you want to sync up with. +* @param {object|Phaser.Sprite} object - The object that you wish to match the center with. */ Phaser.Particles.Arcade.Emitter.prototype.at = function (object) { - this.emitX = object.center.x; - this.emitY = object.center.y; + if (object.center) + { + this.emitX = object.center.x; + this.emitY = object.center.y; + } } diff --git a/src/physics/advanced/collision/Broadphase.js b/src/physics/advanced/collision/Broadphase.js deleted file mode 100644 index b0d6129c..00000000 --- a/src/physics/advanced/collision/Broadphase.js +++ /dev/null @@ -1,43 +0,0 @@ -var vec2 = require('../math/vec2') -, Nearphase = require('./Nearphase') -, Shape = require('./../shapes/Shape') - -module.exports = Broadphase; - -/** - * Base class for broadphase implementations. - * @class Broadphase - * @constructor - */ -function Broadphase(){ - this.result = []; -}; - -/** - * Get all potential intersecting body pairs. - * @method getCollisionPairs - * @param {World} world The world to search in. - * @return {Array} An array of the bodies, ordered in pairs. Example: A result of [a,b,c,d] means that the potential pairs are: (a,b), (c,d). - */ -Broadphase.prototype.getCollisionPairs = function(world){ - throw new Error("getCollisionPairs must be implemented in a subclass!"); -}; - -// Temp things -var dist = vec2.create(), - worldNormal = vec2.create(), - yAxis = vec2.fromValues(0,1); - -/** - * Check whether the bounding radius of two bodies overlap. - * @method boundingRadiusCheck - * @param {Body} bodyA - * @param {Body} bodyB - * @return {Boolean} - */ -Broadphase.boundingRadiusCheck = function(bodyA, bodyB){ - vec2.sub(dist, bodyA.position, bodyB.position); - var d2 = vec2.squaredLength(dist), - r = bodyA.boundingRadius + bodyB.boundingRadius; - return d2 <= r*r; -}; diff --git a/src/physics/advanced/collision/GridBroadphase.js b/src/physics/advanced/collision/GridBroadphase.js deleted file mode 100644 index 747d78d6..00000000 --- a/src/physics/advanced/collision/GridBroadphase.js +++ /dev/null @@ -1,159 +0,0 @@ -var Circle = require('../shapes/Circle') -, Plane = require('../shapes/Plane') -, Particle = require('../shapes/Particle') -, Broadphase = require('../collision/Broadphase') -, vec2 = require('../math/vec2') - -module.exports = GridBroadphase; - -/** - * Broadphase that uses axis-aligned bins. - * @class GridBroadphase - * @constructor - * @extends Broadphase - * @param {number} xmin Lower x bound of the grid - * @param {number} xmax Upper x bound - * @param {number} ymin Lower y bound - * @param {number} ymax Upper y bound - * @param {number} nx Number of bins along x axis - * @param {number} ny Number of bins along y axis - * @todo test - */ -function GridBroadphase(xmin,xmax,ymin,ymax,nx,ny){ - Broadphase.apply(this); - - nx = nx || 10; - ny = ny || 10; - - this.binsizeX = (xmax-xmin) / nx; - this.binsizeY = (ymax-ymin) / ny; - this.nx = nx; - this.ny = ny; - this.xmin = xmin; - this.ymin = ymin; - this.xmax = xmax; - this.ymax = ymax; -}; -GridBroadphase.prototype = new Broadphase(); - -/** - * Get a bin index given a world coordinate - * @method getBinIndex - * @param {Number} x - * @param {Number} y - * @return {Number} Integer index - */ -GridBroadphase.prototype.getBinIndex = function(x,y){ - var nx = this.nx, - ny = this.ny, - xmin = this.xmin, - ymin = this.ymin, - xmax = this.xmax, - ymax = this.ymax; - - var xi = Math.floor(nx * (x - xmin) / (xmax-xmin)); - var yi = Math.floor(ny * (y - ymin) / (ymax-ymin)); - return xi*ny + yi; -} - -/** - * Get collision pairs. - * @method getCollisionPairs - * @param {World} world - * @return {Array} - */ -GridBroadphase.prototype.getCollisionPairs = function(world){ - var result = [], - collidingBodies = world.bodies, - Ncolliding = Ncolliding=collidingBodies.length, - binsizeX = this.binsizeX, - binsizeY = this.binsizeY; - - var bins=[], Nbins=nx*ny; - for(var i=0; i= 0 && xi*(ny-1) + yi < Nbins) - bins[ xi*(ny-1) + yi ].push(bi); - } - } - } else if(si instanceof Plane){ - // Put in all bins for now - if(bi.angle === 0){ - var y = bi.position[1]; - for(var j=0; j!==Nbins && ymin+binsizeY*(j-1) pos0 && pos < pos1){ - // We got contact! - - if(justTest) return true; - - var c = this.createContactEquation(circleBody,lineBody); - - vec2.scale(c.ni, orthoDist, -1); - vec2.normalize(c.ni, c.ni); - - vec2.scale( c.ri, c.ni, circleRadius); - add(c.ri, c.ri, circleOffset); - sub(c.ri, c.ri, circleBody.position); - - sub(c.rj, projectedPoint, lineOffset); - add(c.rj, c.rj, lineOffset); - sub(c.rj, c.rj, lineBody.position); - - this.contactEquations.push(c); - - if(this.enableFriction){ - this.frictionEquations.push(this.createFrictionFromContact(c)); - } - - return true; - } - } - - // Add corner - var verts = [worldVertex0, worldVertex1]; - - for(var i=0; i 0){ - - // Now project the circle onto the edge - vec2.scale(orthoDist, worldTangent, d); - sub(projectedPoint, circleOffset, orthoDist); - - // Check if the point is within the edge span - var pos = dot(worldEdgeUnit, projectedPoint); - var pos0 = dot(worldEdgeUnit, worldVertex0); - var pos1 = dot(worldEdgeUnit, worldVertex1); - - if(pos > pos0 && pos < pos1){ - // We got contact! - - var c = this.createContactEquation(circleBody,convexBody); - - vec2.scale(c.ni, orthoDist, -1); - vec2.normalize(c.ni, c.ni); - - vec2.scale( c.ri, c.ni, circleShape.radius); - add(c.ri, c.ri, circleOffset); - sub(c.ri, c.ri, circleBody.position); - - sub( c.rj, projectedPoint, convexOffset); - add(c.rj, c.rj, convexOffset); - sub(c.rj, c.rj, convexBody.position); - - this.contactEquations.push(c); - - if(this.enableFriction){ - this.frictionEquations.push( this.createFrictionFromContact(c) ); - } - - return true; - } - } - } - - // Check all vertices - for(var i=0; i= 0){ - - // Now project the particle onto the edge - vec2.scale(orthoDist, worldTangent, d); - sub(projectedPoint, particleOffset, orthoDist); - - // Check if the point is within the edge span - var pos = dot(worldEdgeUnit, projectedPoint); - var pos0 = dot(worldEdgeUnit, worldVertex0); - var pos1 = dot(worldEdgeUnit, worldVertex1); - - if(pos > pos0 && pos < pos1){ - // We got contact! - if(justTest) return true; - - if(closestEdgeDistance === null || d*d r*r){ - return false; - } - - if(justTest) return true; - - var c = this.createContactEquation(bodyA,bodyB); - sub(c.ni, offsetB, offsetA); - vec2.normalize(c.ni,c.ni); - - vec2.scale( c.ri, c.ni, shapeA.radius); - vec2.scale( c.rj, c.ni, -shapeB.radius); - - add(c.ri, c.ri, offsetA); - sub(c.ri, c.ri, bodyA.position); - - add(c.rj, c.rj, offsetB); - sub(c.rj, c.rj, bodyB.position); - - this.contactEquations.push(c); - - if(this.enableFriction){ - this.frictionEquations.push(this.createFrictionFromContact(c)); - } - return true; -}; - -/** - * Convex/Plane nearphase - * @method convexPlane - * @param {Body} bi - * @param {Convex} si - * @param {Array} xi - * @param {Number} ai - * @param {Body} bj - * @param {Plane} sj - * @param {Array} xj - * @param {Number} aj - */ -Nearphase.prototype.convexPlane = function( bi,si,xi,ai, bj,sj,xj,aj ){ - var convexBody = bi, - convexOffset = xi, - convexShape = si, - convexAngle = ai, - planeBody = bj, - planeShape = sj, - planeOffset = xj, - planeAngle = aj; - - var worldVertex = tmp1, - worldNormal = tmp2, - dist = tmp3; - - var numReported = 0; - vec2.rotate(worldNormal, yAxis, planeAngle); - - for(var i=0; i= 2) - break; - } - } - return numReported > 0; -}; - -/** - * Nearphase for particle vs plane - * @method particlePlane - * @param {Body} bi The particle body - * @param {Particle} si Particle shape - * @param {Array} xi World position for the particle - * @param {Number} ai World angle for the particle - * @param {Body} bj Plane body - * @param {Plane} sj Plane shape - * @param {Array} xj World position for the plane - * @param {Number} aj World angle for the plane - */ -Nearphase.prototype.particlePlane = function( bi,si,xi,ai, bj,sj,xj,aj, justTest ){ - var particleBody = bi, - particleShape = si, - particleOffset = xi, - planeBody = bj, - planeShape = sj, - planeOffset = xj, - planeAngle = aj; - - var dist = tmp1, - worldNormal = tmp2; - - planeAngle = planeAngle || 0; - - sub(dist, particleOffset, planeOffset); - vec2.rotate(worldNormal, yAxis, planeAngle); - - var d = dot(dist, worldNormal); - - if(d > 0) return false; - if(justTest) return true; - - var c = this.createContactEquation(planeBody,particleBody); - - vec2.copy(c.ni, worldNormal); - vec2.scale( dist, c.ni, d ); - // dist is now the distance vector in the normal direction - - // ri is the particle position projected down onto the plane, from the plane center - sub( c.ri, particleOffset, dist); - sub( c.ri, c.ri, planeBody.position); - - // rj is from the body center to the particle center - sub( c.rj, particleOffset, particleBody.position ); - - this.contactEquations.push(c); - - if(this.enableFriction){ - this.frictionEquations.push(this.createFrictionFromContact(c)); - } - return true; -}; - -/** - * Circle/Particle nearphase - * @method circleParticle - * @param {Body} bi - * @param {Circle} si - * @param {Array} xi - * @param {Number} ai - * @param {Body} bj - * @param {Particle} sj - * @param {Array} xj - * @param {Number} aj - */ -Nearphase.prototype.circleParticle = function( bi,si,xi,ai, bj,sj,xj,aj, justTest ){ - var circleBody = bi, - circleShape = si, - circleOffset = xi, - particleBody = bj, - particleShape = sj, - particleOffset = xj, - dist = tmp1; - - sub(dist, particleOffset, circleOffset); - if(vec2.squaredLength(dist) > circleShape.radius*circleShape.radius) return false; - if(justTest) return true; - - var c = this.createContactEquation(circleBody,particleBody); - vec2.copy(c.ni, dist); - vec2.normalize(c.ni,c.ni); - - // Vector from circle to contact point is the normal times the circle radius - vec2.scale(c.ri, c.ni, circleShape.radius); - add(c.ri, c.ri, circleOffset); - sub(c.ri, c.ri, circleBody.position); - - // Vector from particle center to contact point is zero - sub(c.rj, particleOffset, particleBody.position); - - this.contactEquations.push(c); - - if(this.enableFriction){ - this.frictionEquations.push(this.createFrictionFromContact(c)); - } - - return true; -}; - -var capsulePlane_tmpCircle = new Circle(1), - capsulePlane_tmp1 = vec2.create(), - capsulePlane_tmp2 = vec2.create(), - capsulePlane_tmp3 = vec2.create(); -Nearphase.prototype.capsulePlane = function( bi,si,xi,ai, bj,sj,xj,aj ){ - var end1 = capsulePlane_tmp1, - end2 = capsulePlane_tmp2, - circle = capsulePlane_tmpCircle, - dst = capsulePlane_tmp3; - - // Compute world end positions - vec2.set(end1, -si.length/2, 0); - vec2.rotate(end1,end1,ai); - add(end1,end1,xi); - - vec2.set(end2, si.length/2, 0); - vec2.rotate(end2,end2,ai); - add(end2,end2,xi); - - circle.radius = si.radius; - - // Do nearphase as two circles - this.circlePlane(bi,circle,end1,0, bj,sj,xj,aj); - this.circlePlane(bi,circle,end2,0, bj,sj,xj,aj); -}; - -/** - * Creates ContactEquations and FrictionEquations for a collision. - * @method circlePlane - * @param {Body} bi The first body that should be connected to the equations. - * @param {Circle} si The circle shape participating in the collision. - * @param {Array} xi Extra offset to take into account for the Shape, in addition to the one in circleBody.position. Will *not* be rotated by circleBody.angle (maybe it should, for sake of homogenity?). Set to null if none. - * @param {Body} bj The second body that should be connected to the equations. - * @param {Plane} sj The Plane shape that is participating - * @param {Array} xj Extra offset for the plane shape. - * @param {Number} aj Extra angle to apply to the plane - */ -Nearphase.prototype.circlePlane = function( bi,si,xi,ai, bj,sj,xj,aj ){ - var circleBody = bi, - circleShape = si, - circleOffset = xi, // Offset from body center, rotated! - planeBody = bj, - shapeB = sj, - planeOffset = xj, - planeAngle = aj; - - planeAngle = planeAngle || 0; - - // Vector from plane to circle - var planeToCircle = tmp1, - worldNormal = tmp2, - temp = tmp3; - - sub(planeToCircle, circleOffset, planeOffset); - - // World plane normal - vec2.rotate(worldNormal, yAxis, planeAngle); - - // Normal direction distance - var d = dot(worldNormal, planeToCircle); - - if(d > circleShape.radius) return false; // No overlap. Abort. - - // Create contact - var contact = this.createContactEquation(planeBody,circleBody); - - // ni is the plane world normal - vec2.copy(contact.ni, worldNormal); - - // rj is the vector from circle center to the contact point - vec2.scale(contact.rj, contact.ni, -circleShape.radius); - add(contact.rj, contact.rj, circleOffset); - sub(contact.rj, contact.rj, circleBody.position); - - // ri is the distance from plane center to contact. - vec2.scale(temp, contact.ni, d); - sub(contact.ri, planeToCircle, temp ); // Subtract normal distance vector from the distance vector - add(contact.ri, contact.ri, planeOffset); - sub(contact.ri, contact.ri, planeBody.position); - - this.contactEquations.push(contact); - - if(this.enableFriction){ - this.frictionEquations.push( this.createFrictionFromContact(contact) ); - } - - return true; -}; - - -/** - * Convex/convex nearphase.See this article for more info. - * @method convexConvex - * @param {Body} bi - * @param {Convex} si - * @param {Array} xi - * @param {Number} ai - * @param {Body} bj - * @param {Convex} sj - * @param {Array} xj - * @param {Number} aj - */ -Nearphase.prototype.convexConvex = function( bi,si,xi,ai, bj,sj,xj,aj ){ - var sepAxis = tmp1, - worldPoint = tmp2, - worldPoint0 = tmp3, - worldPoint1 = tmp4, - worldEdge = tmp5, - projected = tmp6, - penetrationVec = tmp7, - dist = tmp8, - worldNormal = tmp9; - - var found = Nearphase.findSeparatingAxis(si,xi,ai,sj,xj,aj,sepAxis); - if(!found) return false; - - // Make sure the separating axis is directed from shape i to shape j - sub(dist,xj,xi); - if(dot(sepAxis,dist) > 0){ - vec2.scale(sepAxis,sepAxis,-1); - } - - // Find edges with normals closest to the separating axis - var closestEdge1 = Nearphase.getClosestEdge(si,ai,sepAxis,true), // Flipped axis - closestEdge2 = Nearphase.getClosestEdge(sj,aj,sepAxis); - - if(closestEdge1==-1 || closestEdge2==-1) return false; - - // Loop over the shapes - for(var k=0; k<2; k++){ - - var closestEdgeA = closestEdge1, - closestEdgeB = closestEdge2, - shapeA = si, shapeB = sj, - offsetA = xi, offsetB = xj, - angleA = ai, angleB = aj, - bodyA = bi, bodyB = bj; - - if(k==0){ - // Swap! - var tmp; - tmp = closestEdgeA; closestEdgeA = closestEdgeB; closestEdgeB = tmp; - tmp = shapeA; shapeA = shapeB; shapeB = tmp; - tmp = offsetA; offsetA = offsetB; offsetB = tmp; - tmp = angleA; angleA = angleB; angleB = tmp; - tmp = bodyA; bodyA = bodyB; bodyB = tmp; - } - - // Loop over 2 points in convex B - for(var j=closestEdgeB; j max) max = value; - if(min === null || value < min) min = value; - } - - if(min > max){ - var t = min; - min = max; - max = t; - } - - // Project the position of the body onto the axis - need to add this to the result - var offset = dot(convexOffset, worldAxis); - - vec2.set( result, min + offset, max + offset); -}; - -// .findSeparatingAxis is called by other functions, need local tmp vectors -var fsa_tmp1 = vec2.fromValues(0,0) -, fsa_tmp2 = vec2.fromValues(0,0) -, fsa_tmp3 = vec2.fromValues(0,0) -, fsa_tmp4 = vec2.fromValues(0,0) -, fsa_tmp5 = vec2.fromValues(0,0) -, fsa_tmp6 = vec2.fromValues(0,0) - -/** - * Find a separating axis between the shapes, that maximizes the separating distance between them. - * @method findSeparatingAxis - * @static - * @param {Convex} c1 - * @param {Array} offset1 - * @param {Number} angle1 - * @param {Convex} c2 - * @param {Array} offset2 - * @param {Number} angle2 - * @param {Array} sepAxis The resulting axis - * @return {Boolean} Whether the axis could be found. - */ -Nearphase.findSeparatingAxis = function(c1,offset1,angle1,c2,offset2,angle2,sepAxis){ - var maxDist = null, - overlap = false, - found = false, - edge = fsa_tmp1, - worldPoint0 = fsa_tmp2, - worldPoint1 = fsa_tmp3, - normal = fsa_tmp4, - span1 = fsa_tmp5, - span2 = fsa_tmp6; - - for(var j=0; j!==2; j++){ - var c = c1, - angle = angle1; - if(j===1){ - c = c2; - angle = angle2; - } - - for(var i=0; i!==c.vertices.length; i++){ - // Get the world edge - vec2.rotate(worldPoint0, c.vertices[i], angle); - vec2.rotate(worldPoint1, c.vertices[(i+1)%c.vertices.length], angle); - - sub(edge, worldPoint1, worldPoint0); - - // Get normal - just rotate 90 degrees since vertices are given in CCW - vec2.rotate(normal, edge, -Math.PI / 2); - vec2.normalize(normal,normal); - - // Project hulls onto that normal - Nearphase.projectConvexOntoAxis(c1,offset1,angle1,normal,span1); - Nearphase.projectConvexOntoAxis(c2,offset2,angle2,normal,span2); - - // Order by span position - var a=span1, - b=span2, - swapped = false; - if(span1[0] > span2[0]){ - b=span1; - a=span2; - swapped = true; - } - - // Get separating distance - var dist = b[0] - a[1]; - overlap = dist < 0; - - if(maxDist===null || dist > maxDist){ - vec2.copy(sepAxis, normal); - maxDist = dist; - found = overlap; - } - } - } - - return found; -}; - -// .getClosestEdge is called by other functions, need local tmp vectors -var gce_tmp1 = vec2.fromValues(0,0) -, gce_tmp2 = vec2.fromValues(0,0) -, gce_tmp3 = vec2.fromValues(0,0) - -/** - * Get the edge that has a normal closest to an axis. - * @method getClosestEdge - * @static - * @param {Convex} c - * @param {Number} angle - * @param {Array} axis - * @param {Boolean} flip - * @return {Number} Index of the edge that is closest. This index and the next spans the resulting edge. Returns -1 if failed. - */ -Nearphase.getClosestEdge = function(c,angle,axis,flip){ - var localAxis = gce_tmp1, - edge = gce_tmp2, - normal = gce_tmp3; - - // Convert the axis to local coords of the body - vec2.rotate(localAxis, axis, -angle); - if(flip){ - vec2.scale(localAxis,localAxis,-1); - } - - var closestEdge = -1, - N = c.vertices.length, - halfPi = Math.PI / 2; - for(var i=0; i!==N; i++){ - // Get the edge - sub(edge, c.vertices[(i+1)%N], c.vertices[i%N]); - - // Get normal - just rotate 90 degrees since vertices are given in CCW - vec2.rotate(normal, edge, -halfPi); - vec2.normalize(normal,normal); - - var d = dot(normal,localAxis); - if(closestEdge == -1 || d > maxDot){ - closestEdge = i % N; - maxDot = d; - } - } - - return closestEdge; -}; - diff --git a/src/physics/advanced/collision/QuadTree.js b/src/physics/advanced/collision/QuadTree.js deleted file mode 100644 index 1cf5c58b..00000000 --- a/src/physics/advanced/collision/QuadTree.js +++ /dev/null @@ -1,376 +0,0 @@ -var Plane = require("../shapes/Plane"); -var Broadphase = require("../collision/Broadphase"); - -module.exports = { - QuadTree : QuadTree, - Node : Node, - BoundsNode : BoundsNode, -}; - -/** - * QuadTree data structure. See https://github.com/mikechambers/ExamplesByMesh/tree/master/JavaScript/QuadTree - * @class QuadTree - * @constructor - * @param {Object} An object representing the bounds of the top level of the QuadTree. The object - * should contain the following properties : x, y, width, height - * @param {Boolean} pointQuad Whether the QuadTree will contain points (true), or items with bounds - * (width / height)(false). Default value is false. - * @param {Number} maxDepth The maximum number of levels that the quadtree will create. Default is 4. - * @param {Number} maxChildren The maximum number of children that a node can contain before it is split into sub-nodes. - */ -function QuadTree(bounds, pointQuad, maxDepth, maxChildren){ - var node; - if(pointQuad){ - node = new Node(bounds, 0, maxDepth, maxChildren); - } else { - node = new BoundsNode(bounds, 0, maxDepth, maxChildren); - } - - /** - * The root node of the QuadTree which covers the entire area being segmented. - * @property root - * @type Node - */ - this.root = node; -} - -/** - * Inserts an item into the QuadTree. - * @method insert - * @param {Object|Array} item The item or Array of items to be inserted into the QuadTree. The item should expose x, y - * properties that represents its position in 2D space. - */ -QuadTree.prototype.insert = function(item){ - if(item instanceof Array){ - var len = item.length; - for(var i = 0; i < len; i++){ - this.root.insert(item[i]); - } - } else { - this.root.insert(item); - } -} - -/** - * Clears all nodes and children from the QuadTree - * @method clear - */ -QuadTree.prototype.clear = function(){ - this.root.clear(); -} - -/** - * Retrieves all items / points in the same node as the specified item / point. If the specified item - * overlaps the bounds of a node, then all children in both nodes will be returned. - * @method retrieve - * @param {Object} item An object representing a 2D coordinate point (with x, y properties), or a shape - * with dimensions (x, y, width, height) properties. - */ -QuadTree.prototype.retrieve = function(item){ - //get a copy of the array of items - var out = this.root.retrieve(item).slice(0); - return out; -} - -QuadTree.prototype.getCollisionPairs = function(world){ - - var result = []; - - // Add all bodies - this.insert(world.bodies); - - /* - console.log("bodies",world.bodies.length); - console.log("maxDepth",this.root.maxDepth,"maxChildren",this.root.maxChildren); - */ - - for(var i=0; i!==world.bodies.length; i++){ - var b = world.bodies[i], - items = this.retrieve(b); - - //console.log("items",items.length); - - // Check results - for(var j=0, len=items.length; j!==len; j++){ - var item = items[j]; - - if(b === item) continue; // Do not add self - - // Check if they were already added - var found = false; - for(var k=0, numAdded=result.length; k= this.maxDepth) && len > this.maxChildren) { - this.subdivide(); - - for(var i = 0; i < len; i++){ - this.insert(this.children[i]); - } - - this.children.length = 0; - } -} - -Node.prototype.retrieve = function(item){ - if(this.nodes.length){ - var index = this.findIndex(item); - return this.nodes[index].retrieve(item); - } - - return this.children; -} - -Node.prototype.findIndex = function(item){ - var b = this.bounds; - var left = (item.position[0]-item.boundingRadius > b.x + b.width / 2) ? false : true; - var top = (item.position[1]-item.boundingRadius > b.y + b.height / 2) ? false : true; - - if(item instanceof Plane){ - left = top = false; // Will overlap the left/top boundary since it is infinite - } - - //top left - var index = Node.TOP_LEFT; - if(left){ - if(!top){ - index = Node.BOTTOM_LEFT; - } - } else { - if(top){ - index = Node.TOP_RIGHT; - } else { - index = Node.BOTTOM_RIGHT; - } - } - - return index; -} - - -Node.prototype.subdivide = function(){ - var depth = this.depth + 1; - - var bx = this.bounds.x; - var by = this.bounds.y; - - //floor the values - var b_w_h = (this.bounds.width / 2); - var b_h_h = (this.bounds.height / 2); - var bx_b_w_h = bx + b_w_h; - var by_b_h_h = by + b_h_h; - - //top left - this.nodes[Node.TOP_LEFT] = new this.classConstructor({ - x:bx, - y:by, - width:b_w_h, - height:b_h_h - }, - depth); - - //top right - this.nodes[Node.TOP_RIGHT] = new this.classConstructor({ - x:bx_b_w_h, - y:by, - width:b_w_h, - height:b_h_h - }, - depth); - - //bottom left - this.nodes[Node.BOTTOM_LEFT] = new this.classConstructor({ - x:bx, - y:by_b_h_h, - width:b_w_h, - height:b_h_h - }, - depth); - - - //bottom right - this.nodes[Node.BOTTOM_RIGHT] = new this.classConstructor({ - x:bx_b_w_h, - y:by_b_h_h, - width:b_w_h, - height:b_h_h - }, - depth); -} - -Node.prototype.clear = function(){ - this.children.length = 0; - - var len = this.nodes.length; - for(var i = 0; i < len; i++){ - this.nodes[i].clear(); - } - - this.nodes.length = 0; -} - - -// BoundsQuadTree - -function BoundsNode(bounds, depth, maxChildren, maxDepth){ - Node.call(this, bounds, depth, maxChildren, maxDepth); - this.stuckChildren = []; -} - -BoundsNode.prototype = new Node(); -BoundsNode.prototype.classConstructor = BoundsNode; -BoundsNode.prototype.stuckChildren = null; - -//we use this to collect and conctenate items being retrieved. This way -//we dont have to continuously create new Array instances. -//Note, when returned from QuadTree.retrieve, we then copy the array -BoundsNode.prototype.out = []; - -BoundsNode.prototype.insert = function(item){ - if(this.nodes.length){ - var index = this.findIndex(item); - var node = this.nodes[index]; - - /* - console.log("radius:",item.boundingRadius); - console.log("item x:",item.position[0] - item.boundingRadius,"x range:",node.bounds.x,node.bounds.x+node.bounds.width); - console.log("item y:",item.position[1] - item.boundingRadius,"y range:",node.bounds.y,node.bounds.y+node.bounds.height); - */ - - //todo: make _bounds bounds - if( !(item instanceof Plane) && // Plane is infinite.. Make it a "stuck" child - item.position[0] - item.boundingRadius >= node.bounds.x && - item.position[0] + item.boundingRadius <= node.bounds.x + node.bounds.width && - item.position[1] - item.boundingRadius >= node.bounds.y && - item.position[1] + item.boundingRadius <= node.bounds.y + node.bounds.height){ - this.nodes[index].insert(item); - } else { - this.stuckChildren.push(item); - } - - return; - } - - this.children.push(item); - - var len = this.children.length; - - if(this.depth < this.maxDepth && len > this.maxChildren){ - this.subdivide(); - - for(var i=0; i