From eddce653e9033c8a5928b6c94963dc97a5912a21 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Wed, 5 Feb 2014 21:02:41 +0000
Subject: [PATCH 01/26] Preparing for 1.1.5 development.
---
README.md | 169 ++-------------------------------------------
bower.json | 2 +-
changelog.md | 176 +++++++++++++++++++++++++++++++++++++++++++++++
package.json | 2 +-
src/IntroDocs.js | 15 ----
src/Phaser.js | 2 +-
6 files changed, 183 insertions(+), 183 deletions(-)
delete mode 100644 src/IntroDocs.js
diff --git a/README.md b/README.md
index 5338ceda..152278d4 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@

-Phaser 1.1.4
-============
+Phaser 1.1.5-dev
+================
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.4 "Kandor" - Released: February 5th 2014
+Version: 1.1.5 "Saldaea" - Released: -in development-
By Richard Davey, [Photon Storm](http://www.photonstorm.com)
@@ -57,179 +57,22 @@ There is also an [un-official Getting Started Guide](http://www.antonoffplus.com
Change Log
----------
-Version 1.1.4 - "Kandor" - February 5th 2014
+Version 1.1.5 - "Saldaea" - -in development-
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.
-* 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
@@ -379,10 +222,6 @@ 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.
diff --git a/bower.json b/bower.json
index 70ab4e24..e16a55b9 100644
--- a/bower.json
+++ b/bower.json
@@ -1,6 +1,6 @@
{
"name": "phaser",
- "version": "1.1.4",
+ "version": "1.1.5",
"homepage": "http://phaser.io",
"authors": [
"photonstorm "
diff --git a/changelog.md b/changelog.md
index b8556ae2..d4338b3f 100644
--- a/changelog.md
+++ b/changelog.md
@@ -1,6 +1,182 @@
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.
+* 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.
+
+
Version 1.1.3 - "Arafel" - November 29th 2013
---------------------------------------------
diff --git a/package.json b/package.json
index c3c07166..75e8c09f 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
{
"name": "Phaser",
- "version": "1.1.4",
+ "version": "1.1.5",
"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/src/IntroDocs.js b/src/IntroDocs.js
deleted file mode 100644
index 11c06cfb..00000000
--- a/src/IntroDocs.js
+++ /dev/null
@@ -1,15 +0,0 @@
-/**
-* @author Richard Davey
-* @copyright 2014 Photon Storm Ltd.
-* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
-*/
-
-/**
-* @overview
-*
-* Many thanks to Adam Saltsman (@ADAMATOMIC) for creating Flixel, from which both 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
-*/
diff --git a/src/Phaser.js b/src/Phaser.js
index b8c554ca..786bbd48 100644
--- a/src/Phaser.js
+++ b/src/Phaser.js
@@ -10,7 +10,7 @@
var Phaser = Phaser || {
VERSION: '<%= version %>',
- DEV_VERSION: '1.1.4',
+ DEV_VERSION: '1.1.5',
GAMES: [],
AUTO: 0,
From 68d5c73fea7b0453ecd06cd41d458c65e1b9b9be Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Wed, 5 Feb 2014 22:35:35 +0000
Subject: [PATCH 02/26] Explicitly paused Timer continues if you un-focus and
focus the browser window. Added TimerEvent.pendingDelete and checks in
Timer.update, so that removing an event in a callback no longer throws an
exception.
---
README.md | 2 ++
examples/wip/timer simple.js | 40 +++++++++++++++++++-------------
src/time/Timer.js | 44 +++++++++++++++++++++++++++---------
src/time/TimerEvent.js | 6 +++++
4 files changed, 65 insertions(+), 27 deletions(-)
diff --git a/README.md b/README.md
index 152278d4..6e10445f 100644
--- a/README.md
+++ b/README.md
@@ -73,6 +73,8 @@ Updates:
Bug Fixes:
+* Explicitly paused Timer continues if you un-focus and focus the browser window (thanks georgiee)
+* Added TimerEvent.pendingDelete and checks in Timer.update, so that removing an event in a callback no longer throws an exception (thanks georgiee)
You can view the Change Log for all previous versions at https://github.com/photonstorm/phaser/changelog.md
diff --git a/examples/wip/timer simple.js b/examples/wip/timer simple.js
index f7b85429..bee855ad 100644
--- a/examples/wip/timer simple.js
+++ b/examples/wip/timer simple.js
@@ -1,45 +1,53 @@
-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, render: render });
function preload() {
- game.load.image('mushroom', 'assets/sprites/mushroom2.png');
- game.load.image('sonic', 'assets/sprites/pangball.png');
+ game.load.image('ball', 'assets/sprites/pangball.png');
}
-var timer;
+var t;
function create() {
- game.stage.backgroundColor = '#007236';
+ game.stage.backgroundColor = '#6688ee';
+ t = game.time.create(false);
+ t.repeat(Phaser.Timer.SECOND * 2, 10, createBall, this);
+ t.repeat(Phaser.Timer.SECOND * 3, 10, createBall, this);
- // 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');
+ t.start();
- // 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');
+ game.input.onDown.add(killThem, this);
}
-function addSprite(key) {
+function createBall() {
-console.log(arguments);
+ // 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;
+
+console.log('nuked');
+ game.time.removeAll();
+ // t.removeAll();
- game.add.sprite(game.world.randomX, game.world.randomY, key);
}
-function update() {
+function killThem() {
+
}
function render() {
- game.debug.renderText(game.time._timer.ms, 32, 32);
- // game.debug.renderCameraInfo(game.camera, 32, 32);
+ game.debug.renderText("Time until event: " + t.duration.toFixed(0), 32, 32);
+ game.debug.renderText("Next tick: " + t.next.toFixed(0), 32, 64);
}
diff --git a/src/time/Timer.js b/src/time/Timer.js
index ee170f9c..410c41bf 100644
--- a/src/time/Timer.js
+++ b/src/time/Timer.js
@@ -245,7 +245,7 @@ Phaser.Timer.prototype = {
{
if (this.events[i] === event)
{
- this.events.splice(i, 1);
+ this.events[i].pendingDelete = true;
return true;
}
}
@@ -308,6 +308,21 @@ Phaser.Timer.prototype = {
this._len = this.events.length;
+ this._i = 0;
+
+ while (this._i < this._len)
+ {
+ if (this.events[this._i].pendingDelete)
+ {
+ this.events.splice(this._i, 1);
+ this._len--;
+ }
+
+ this._i++;
+ }
+
+ this._len = this.events.length;
+
if (this.running && this._now >= this.nextTick && this._len > 0)
{
this._i = 0;
@@ -371,9 +386,12 @@ Phaser.Timer.prototype = {
*/
pause: function () {
- this._pauseStarted = this.game.time.now;
+ if (this.running && !this.expired)
+ {
+ this._pauseStarted = this.game.time.now;
- this.paused = true;
+ this.paused = true;
+ }
},
@@ -383,17 +401,20 @@ Phaser.Timer.prototype = {
*/
resume: function () {
- var pauseDuration = this.game.time.now - this._pauseStarted;
-
- for (var i = 0; i < this.events.length; i++)
+ if (this.running && !this.expired)
{
- this.events[i].tick += pauseDuration;
+ 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;
}
- this.nextTick += pauseDuration;
-
- this.paused = false;
-
},
/**
@@ -405,6 +426,7 @@ Phaser.Timer.prototype = {
this.onComplete.removeAll();
this.running = false;
this.events = [];
+ this._i = this._len;
}
diff --git a/src/time/TimerEvent.js b/src/time/TimerEvent.js
index 9bc152c5..1acd75d8 100644
--- a/src/time/TimerEvent.js
+++ b/src/time/TimerEvent.js
@@ -62,6 +62,12 @@ Phaser.TimerEvent = function (timer, delay, tick, repeatCount, loop, callback, c
*/
this.args = args;
+ /**
+ * @property {boolean} pendingDelete - A flag that controls if the TimerEvent is pending deletion.
+ * @protected
+ */
+ this.pendingDelete = false;
+
};
Phaser.TimerEvent.prototype.constructor = Phaser.TimerEvent;
From 9737710200be158bdc01fc143c919a3bd03c650d Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Thu, 6 Feb 2014 00:19:46 +0000
Subject: [PATCH 03/26] Upgraded to Pixi.js 1.4.4
---
README.md | 13 +-
src/pixi/InteractionData.js | 63 +
src/pixi/InteractionManager.js | 276 ++---
src/pixi/Pixi.js | 38 +
src/pixi/core/Circle.js | 14 +-
src/pixi/core/Ellipse.js | 20 +-
src/pixi/core/Matrix.js | 327 +-----
src/pixi/core/Point.js | 10 +-
src/pixi/core/Polygon.js | 8 +-
src/pixi/core/Rectangle.js | 9 +-
src/pixi/display/DisplayObject.js | 420 +++----
src/pixi/display/DisplayObjectContainer.js | 428 +++----
src/pixi/display/MovieClip.js | 2 +-
src/pixi/display/Sprite.js | 325 +++++-
src/pixi/display/SpriteBatch copy.js | 371 ++++++
src/pixi/display/SpriteBatch.js | 156 +++
src/pixi/display/Stage.js | 21 +-
src/pixi/extras/CustomRenderable.js | 58 -
src/pixi/extras/Rope.js | 30 +-
src/pixi/extras/Strip.js | 25 +
src/pixi/extras/TilingSprite.js | 342 +++++-
src/pixi/filters/AbstractFilter.js | 21 +-
src/pixi/filters/AlphaMaskFilter.js | 93 ++
src/pixi/filters/BlurFilter.js | 4 +-
src/pixi/filters/BlurXFilter.js | 2 +-
src/pixi/filters/BlurYFilter.js | 2 +-
src/pixi/filters/ColorMatrixFilter.js | 4 +-
src/pixi/filters/ColorStepFilter.js | 6 +-
src/pixi/filters/CrossHatchFilter.js | 2 +-
src/pixi/filters/DisplacementFilter.js | 5 +-
src/pixi/filters/DotScreenFilter.js | 6 +-
src/pixi/filters/GrayFilter.js | 4 +-
src/pixi/filters/InvertFilter.js | 4 +-
src/pixi/filters/NormalMapFilter.js | 225 ++++
src/pixi/filters/PixelateFilter.js | 4 +-
src/pixi/filters/RGBSplitFilter.js | 2 +-
src/pixi/filters/SepiaFilter.js | 4 +-
src/pixi/filters/TwistFilter.js | 6 +-
src/pixi/loaders/AssetLoader.js | 7 +-
src/pixi/loaders/AtlasLoader.js | 16 +-
src/pixi/loaders/BitmapFontLoader.js | 56 +-
src/pixi/loaders/ImageLoader.js | 4 +-
src/pixi/loaders/JsonLoader.js | 24 +-
src/pixi/loaders/SpineLoader.js | 19 +-
src/pixi/loaders/SpriteSheetLoader.js | 48 +-
src/pixi/primitives/Graphics.js | 482 ++++++--
src/pixi/renderers/canvas/CanvasGraphics.js | 8 +-
src/pixi/renderers/canvas/CanvasRenderer.js | 354 +++---
.../canvas/utils/CanvasMaskManager.js | 51 +
.../renderers/canvas/utils/CanvasTinter.js | 243 ++++
src/pixi/renderers/webgl/WebGLBatch.js | 572 ---------
src/pixi/renderers/webgl/WebGLRenderGroup.js | 1028 -----------------
src/pixi/renderers/webgl/WebGLRenderer.js | 537 ++++++---
src/pixi/renderers/webgl/WebGLShaders.js | 117 --
.../renderers/webgl/shaders/PixiFastShader.js | 146 +++
.../webgl/{ => shaders}/PixiShader.js | 147 ++-
.../webgl/{ => shaders}/PrimitiveShader.js | 58 +-
.../webgl/{ => shaders}/StripShader.js | 19 +-
.../renderers/webgl/utils/FilterTexture.js | 84 ++
.../webgl/utils/WebGLFastSpriteBatch.js | 351 ++++++
.../webgl/{ => utils}/WebGLFilterManager.js | 319 +++--
.../webgl/{ => utils}/WebGLGraphics.js | 109 +-
.../renderers/webgl/utils/WebGLMaskManager.js | 97 ++
.../webgl/utils/WebGLShaderManager.js | 161 +++
.../renderers/webgl/utils/WebGLShaderUtils.js | 55 +
.../renderers/webgl/utils/WebGLSpriteBatch.js | 496 ++++++++
src/pixi/text/BitmapText.js | 51 +-
src/pixi/text/Text.js | 45 +-
src/pixi/textures/BaseTexture.js | 94 +-
src/pixi/textures/RenderTexture.js | 174 +--
src/pixi/textures/Texture.js | 63 +-
src/pixi/utils/Detector.js | 21 +-
src/pixi/utils/EventTarget.js | 38 +-
src/pixi/utils/Polyk.js | 31 +-
src/pixi/utils/Utils.js | 105 +-
75 files changed, 5794 insertions(+), 3786 deletions(-)
create mode 100644 src/pixi/InteractionData.js
create mode 100644 src/pixi/display/SpriteBatch copy.js
create mode 100644 src/pixi/display/SpriteBatch.js
delete mode 100644 src/pixi/extras/CustomRenderable.js
create mode 100644 src/pixi/filters/AlphaMaskFilter.js
create mode 100644 src/pixi/filters/NormalMapFilter.js
create mode 100644 src/pixi/renderers/canvas/utils/CanvasMaskManager.js
create mode 100644 src/pixi/renderers/canvas/utils/CanvasTinter.js
delete mode 100644 src/pixi/renderers/webgl/WebGLBatch.js
delete mode 100644 src/pixi/renderers/webgl/WebGLRenderGroup.js
delete mode 100644 src/pixi/renderers/webgl/WebGLShaders.js
create mode 100644 src/pixi/renderers/webgl/shaders/PixiFastShader.js
rename src/pixi/renderers/webgl/{ => shaders}/PixiShader.js (61%)
rename src/pixi/renderers/webgl/{ => shaders}/PrimitiveShader.js (58%)
rename src/pixi/renderers/webgl/{ => shaders}/StripShader.js (85%)
create mode 100644 src/pixi/renderers/webgl/utils/FilterTexture.js
create mode 100644 src/pixi/renderers/webgl/utils/WebGLFastSpriteBatch.js
rename src/pixi/renderers/webgl/{ => utils}/WebGLFilterManager.js (62%)
rename src/pixi/renderers/webgl/{ => utils}/WebGLGraphics.js (77%)
create mode 100644 src/pixi/renderers/webgl/utils/WebGLMaskManager.js
create mode 100644 src/pixi/renderers/webgl/utils/WebGLShaderManager.js
create mode 100644 src/pixi/renderers/webgl/utils/WebGLShaderUtils.js
create mode 100644 src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js
diff --git a/README.md b/README.md
index 6e10445f..77600118 100644
--- a/README.md
+++ b/README.md
@@ -1,11 +1,11 @@

-Phaser 1.1.5-dev
-================
+Phaser 1.2-dev
+==============
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.5 "Saldaea" - Released: -in development-
+Version: 1.2 "Shienar" - Released: -in development-
By Richard Davey, [Photon Storm](http://www.photonstorm.com)
@@ -57,10 +57,11 @@ There is also an [un-official Getting Started Guide](http://www.antonoffplus.com
Change Log
----------
-Version 1.1.5 - "Saldaea" - -in development-
+Version 1.2 - "Shienar" - -in development-
Significant API changes:
+* Upgraded to Pixi.js 1.4.4
New features:
@@ -224,10 +225,6 @@ Road Map
Here is what's on our road map for the coming months:
-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.
diff --git a/src/pixi/InteractionData.js b/src/pixi/InteractionData.js
new file mode 100644
index 00000000..909fcbe2
--- /dev/null
+++ b/src/pixi/InteractionData.js
@@ -0,0 +1,63 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+/**
+ * Holds all information related to an Interaction event
+ *
+ * @class InteractionData
+ * @constructor
+ */
+PIXI.InteractionData = function()
+{
+ /**
+ * This point stores the global coords of where the touch/mouse event happened
+ *
+ * @property global
+ * @type Point
+ */
+ this.global = new PIXI.Point();
+
+ // this is here for legacy... but will remove
+ this.local = new PIXI.Point();
+
+ /**
+ * The target Sprite that was interacted with
+ *
+ * @property target
+ * @type Sprite
+ */
+ this.target = null;
+
+ /**
+ * When passed to an event handler, this will be the original DOM Event that was captured
+ *
+ * @property originalEvent
+ * @type Event
+ */
+ this.originalEvent = null;
+};
+
+/**
+ * This will return the local coordinates of the specified displayObject for this InteractionData
+ *
+ * @method getLocalPosition
+ * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
+ * @return {Point} A point containing the coordinates of the InteractionData position relative to the DisplayObject
+ */
+PIXI.InteractionData.prototype.getLocalPosition = function(displayObject)
+{
+ var worldTransform = displayObject.worldTransform;
+ var global = this.global;
+
+ // do a cheeky transform to get the mouse coords;
+ var a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx,
+ a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty,
+ id = 1 / (a00 * a11 + a01 * -a10);
+ // set the mouse coords...
+ return new PIXI.Point(a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
+ a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id);
+};
+
+// constructor
+PIXI.InteractionData.prototype.constructor = PIXI.InteractionData;
\ No newline at end of file
diff --git a/src/pixi/InteractionManager.js b/src/pixi/InteractionManager.js
index d1e80556..e87ae3f2 100644
--- a/src/pixi/InteractionManager.js
+++ b/src/pixi/InteractionManager.js
@@ -4,6 +4,7 @@
/**
* The interaction manager deals with mouse and touch events. Any DisplayObject can be interactive
+ * if its interactive parameter is set to true
* This manager also supports multitouch.
*
* @class InteractionManager
@@ -13,7 +14,7 @@
PIXI.InteractionManager = function(stage)
{
/**
- * a refference to the stage
+ * a reference to the stage
*
* @property stage
* @type Stage
@@ -38,7 +39,6 @@ PIXI.InteractionManager = function(stage)
// helpers
this.tempPoint = new PIXI.Point();
- //this.tempMatrix = mat3.create();
this.mouseoverEnabled = true;
@@ -58,6 +58,10 @@ PIXI.InteractionManager = function(stage)
this.onTouchEnd = this.onTouchEnd.bind(this);
this.onTouchMove = this.onTouchMove.bind(this);
this.last = 0;
+
+ this.currentCursorStyle = 'inherit';
+
+ this.mouseOut = false;
};
// constructor
@@ -124,36 +128,24 @@ PIXI.InteractionManager.prototype.setTarget = function(target)
this.setTargetDomElement( target.view );
}
- document.body.addEventListener('mouseup', this.onMouseUp, true);
+
};
/**
- * Sets the dom element which will receive mouse/touch events. This is useful for when you have other DOM
- * elements ontop of the renderers Canvas element. With this you'll be able to delegate another dom element
+ * Sets the DOM element which will receive mouse/touch events. This is useful for when you have other DOM
+ * elements on top of the renderers Canvas element. With this you'll be able to delegate another DOM element
* to receive those events
*
* @method setTargetDomElement
- * @param domElement {DOMElement} the dom element which will receive mouse and touch events
+ * @param domElement {DOMElement} the DOM element which will receive mouse and touch events
* @private
*/
PIXI.InteractionManager.prototype.setTargetDomElement = function(domElement)
{
//remove previouse listeners
- if( this.interactionDOMElement !== null )
- {
- this.interactionDOMElement.style['-ms-content-zooming'] = '';
- this.interactionDOMElement.style['-ms-touch-action'] = '';
- this.interactionDOMElement.removeEventListener('mousemove', this.onMouseMove, true);
- this.interactionDOMElement.removeEventListener('mousedown', this.onMouseDown, true);
- this.interactionDOMElement.removeEventListener('mouseout', this.onMouseOut, true);
-
- // aint no multi touch just yet!
- this.interactionDOMElement.removeEventListener('touchstart', this.onTouchStart, true);
- this.interactionDOMElement.removeEventListener('touchend', this.onTouchEnd, true);
- this.interactionDOMElement.removeEventListener('touchmove', this.onTouchMove, true);
- }
+ this.removeEvents();
if (window.navigator.msPointerEnabled)
@@ -175,6 +167,30 @@ PIXI.InteractionManager.prototype.setTargetDomElement = function(domElement)
domElement.addEventListener('touchstart', this.onTouchStart, true);
domElement.addEventListener('touchend', this.onTouchEnd, true);
domElement.addEventListener('touchmove', this.onTouchMove, true);
+
+ document.body.addEventListener('mouseup', this.onMouseUp, true);
+};
+
+
+PIXI.InteractionManager.prototype.removeEvents = function()
+{
+ if(!this.interactionDOMElement)return;
+
+ this.interactionDOMElement.style['-ms-content-zooming'] = '';
+ this.interactionDOMElement.style['-ms-touch-action'] = '';
+
+ this.interactionDOMElement.removeEventListener('mousemove', this.onMouseMove, true);
+ this.interactionDOMElement.removeEventListener('mousedown', this.onMouseDown, true);
+ this.interactionDOMElement.removeEventListener('mouseout', this.onMouseOut, true);
+
+ // aint no multi touch just yet!
+ this.interactionDOMElement.removeEventListener('touchstart', this.onTouchStart, true);
+ this.interactionDOMElement.removeEventListener('touchend', this.onTouchEnd, true);
+ this.interactionDOMElement.removeEventListener('touchmove', this.onTouchMove, true);
+
+ this.interactionDOMElement = null;
+
+ document.body.removeEventListener('mouseup', this.onMouseUp, true);
};
/**
@@ -190,7 +206,7 @@ PIXI.InteractionManager.prototype.update = function()
// frequency of 30fps??
var now = Date.now();
var diff = now - this.last;
- diff = (diff * 30) / 1000;
+ diff = (diff * PIXI.INTERACTION_FREQUENCY ) / 1000;
if(diff < 1)return;
this.last = now;
//
@@ -199,7 +215,7 @@ PIXI.InteractionManager.prototype.update = function()
// ok.. so mouse events??
// yes for now :)
- // OPTIMSE - how often to check??
+ // OPTIMISE - how often to check??
if(this.dirty)
{
this.dirty = false;
@@ -220,7 +236,10 @@ PIXI.InteractionManager.prototype.update = function()
// loop through interactive objects!
var length = this.interactiveItems.length;
- this.interactionDOMElement.style.cursor = 'inherit';
+
+
+ var cursor = 'inherit';
+ var over = false;
for (i = 0; i < length; i++)
{
@@ -232,42 +251,55 @@ PIXI.InteractionManager.prototype.update = function()
// OPTIMISATION - only calculate every time if the mousemove function exists..
// OK so.. does the object have any other interactive functions?
// hit-test the clip!
-
-
- if(item.mouseover || item.mouseout || item.buttonMode)
+ // if(item.mouseover || item.mouseout || item.buttonMode)
+ // {
+ // ok so there are some functions so lets hit test it..
+ item.__hit = this.hitTest(item, this.mouse);
+ this.mouse.target = item;
+ // ok so deal with interactions..
+ // looks like there was a hit!
+ if(item.__hit && !over)
{
- // ok so there are some functions so lets hit test it..
- item.__hit = this.hitTest(item, this.mouse);
- this.mouse.target = item;
- // ok so deal with interactions..
- // loks like there was a hit!
- if(item.__hit)
+ if(item.buttonMode) cursor = item.defaultCursor;
+
+ if(!item.interactiveChildren)over = true;
+
+ if(!item.__isOver)
{
- if(item.buttonMode) this.interactionDOMElement.style.cursor = item.defaultCursor;
- if(!item.__isOver)
- {
+ if(item.mouseover)item.mouseover(this.mouse);
+ item.__isOver = true;
+
+ // just the one!
+ //break;
+
- if(item.mouseover)item.mouseover(this.mouse);
- item.__isOver = true;
- }
}
- else
+ //break;
+ }
+ else
+ {
+ if(item.__isOver)
{
- if(item.__isOver)
- {
- // roll out!
- if(item.mouseout)item.mouseout(this.mouse);
- item.__isOver = false;
- }
+ // roll out!
+ if(item.mouseout)item.mouseout(this.mouse);
+ item.__isOver = false;
}
}
+ // }
// --->
}
+
+ if( this.currentCursorStyle !== cursor )
+ {
+ this.currentCursorStyle = cursor;
+ this.interactionDOMElement.style.cursor = cursor;
+ }
+
};
/**
- * Is called when the mouse moves accross the renderer element
+ * Is called when the mouse moves across the renderer element
*
* @method onMouseMove
* @param event {Event} The DOM event of the mouse moving
@@ -307,7 +339,9 @@ PIXI.InteractionManager.prototype.onMouseDown = function(event)
{
this.mouse.originalEvent = event || window.event; //IE uses window.event
- // loop through inteaction tree...
+ if(PIXI.AUTO_PREVENT_DEFAULT)this.mouse.originalEvent.preventDefault();
+
+ // loop through interaction tree...
// hit test each item! ->
// get interactive items under point??
//stage.__i
@@ -337,7 +371,13 @@ PIXI.InteractionManager.prototype.onMouseDown = function(event)
}
};
-
+/**
+ * Is called when the mouse button is moved out of the renderer element
+ *
+ * @method onMouseDown
+ * @param event {Event} The DOM event of a mouse button being moved out
+ * @private
+ */
PIXI.InteractionManager.prototype.onMouseOut = function()
{
var length = this.interactiveItems.length;
@@ -347,7 +387,6 @@ PIXI.InteractionManager.prototype.onMouseOut = function()
for (var i = 0; i < length; i++)
{
var item = this.interactiveItems[i];
-
if(item.__isOver)
{
this.mouse.target = item;
@@ -355,6 +394,12 @@ PIXI.InteractionManager.prototype.onMouseOut = function()
item.__isOver = false;
}
}
+
+ this.mouseOut = true;
+
+ // move the mouse to an impossible position
+ this.mouse.global.x = -10000;
+ this.mouse.global.y = -10000;
};
/**
@@ -366,6 +411,7 @@ PIXI.InteractionManager.prototype.onMouseOut = function()
*/
PIXI.InteractionManager.prototype.onMouseUp = function(event)
{
+
this.mouse.originalEvent = event || window.event; //IE uses window.event
var length = this.interactiveItems.length;
@@ -375,55 +421,57 @@ PIXI.InteractionManager.prototype.onMouseUp = function(event)
{
var item = this.interactiveItems[i];
- if(item.mouseup || item.mouseupoutside || item.click)
+ //if(item.mouseup || item.mouseupoutside || item.click)
+ //{
+ item.__hit = this.hitTest(item, this.mouse);
+
+ if(item.__hit && !up)
{
- item.__hit = this.hitTest(item, this.mouse);
-
- if(item.__hit && !up)
+ //call the function!
+ if(item.mouseup)
{
- //call the function!
- if(item.mouseup)
- {
- item.mouseup(this.mouse);
- }
- if(item.__isDown)
- {
- if(item.click)item.click(this.mouse);
- }
-
- if(!item.interactiveChildren)up = true;
+ item.mouseup(this.mouse);
}
- else
+ if(item.__isDown)
{
- if(item.__isDown)
- {
- if(item.mouseupoutside)item.mouseupoutside(this.mouse);
- }
+ if(item.click)item.click(this.mouse);
}
- item.__isDown = false;
+ if(!item.interactiveChildren)up = true;
}
+ else
+ {
+ if(item.__isDown)
+ {
+ if(item.mouseupoutside)item.mouseupoutside(this.mouse);
+ }
+ }
+
+ item.__isDown = false;
+ //}
}
};
/**
- * Tests if the current mouse coords hit a sprite
+ * Tests if the current mouse coordinates hit a sprite
*
* @method hitTest
* @param item {DisplayObject} The displayObject to test for a hit
- * @param interactionData {InteractionData} The interactiondata object to update in the case of a hit
+ * @param interactionData {InteractionData} The interactionData object to update in the case there is a hit
* @private
*/
PIXI.InteractionManager.prototype.hitTest = function(item, interactionData)
{
var global = interactionData.global;
- if(item.vcount !== PIXI.visibleCount)return false;
+ if( !item.worldVisible )return false;
+ // temp fix for if the element is in a non visible
+
var isSprite = (item instanceof PIXI.Sprite),
worldTransform = item.worldTransform,
- a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2],
- a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5],
+ a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx,
+ a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty,
id = 1 / (a00 * a11 + a01 * -a10),
x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id;
@@ -480,10 +528,10 @@ PIXI.InteractionManager.prototype.hitTest = function(item, interactionData)
};
/**
- * Is called when a touch is moved accross the renderer element
+ * Is called when a touch is moved across the renderer element
*
* @method onTouchMove
- * @param event {Event} The DOM event of a touch moving accross the renderer view
+ * @param event {Event} The DOM event of a touch moving across the renderer view
* @private
*/
PIXI.InteractionManager.prototype.onTouchMove = function(event)
@@ -502,6 +550,10 @@ PIXI.InteractionManager.prototype.onTouchMove = function(event)
// update the touch position
touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width);
touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height);
+ if(navigator.isCocoonJS) {
+ touchData.global.x = touchEvent.clientX;
+ touchData.global.y = touchEvent.clientY;
+ }
}
var length = this.interactiveItems.length;
@@ -524,6 +576,8 @@ PIXI.InteractionManager.prototype.onTouchStart = function(event)
{
var rect = this.interactionDOMElement.getBoundingClientRect();
+ if(PIXI.AUTO_PREVENT_DEFAULT)event.preventDefault();
+
var changedTouches = event.changedTouches;
for (var i=0; i < changedTouches.length; i++)
{
@@ -537,6 +591,10 @@ PIXI.InteractionManager.prototype.onTouchStart = function(event)
this.touchs[touchEvent.identifier] = touchData;
touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width);
touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height);
+ if(navigator.isCocoonJS) {
+ touchData.global.x = touchEvent.clientX;
+ touchData.global.y = touchEvent.clientY;
+ }
var length = this.interactiveItems.length;
@@ -582,6 +640,10 @@ PIXI.InteractionManager.prototype.onTouchEnd = function(event)
var up = false;
touchData.global.x = (touchEvent.clientX - rect.left) * (this.target.width / rect.width);
touchData.global.y = (touchEvent.clientY - rect.top) * (this.target.height / rect.height);
+ if(navigator.isCocoonJS) {
+ touchData.global.x = touchEvent.clientX;
+ touchData.global.y = touchEvent.clientY;
+ }
var length = this.interactiveItems.length;
for (var j = 0; j < length; j++)
@@ -633,64 +695,4 @@ PIXI.InteractionManager.prototype.onTouchEnd = function(event)
this.pool.push(touchData);
this.touchs[touchEvent.identifier] = null;
}
-};
-
-/**
- * Holds all information related to an Interaction event
- *
- * @class InteractionData
- * @constructor
- */
-PIXI.InteractionData = function()
-{
- /**
- * This point stores the global coords of where the touch/mouse event happened
- *
- * @property global
- * @type Point
- */
- this.global = new PIXI.Point();
-
- // this is here for legacy... but will remove
- this.local = new PIXI.Point();
-
- /**
- * The target Sprite that was interacted with
- *
- * @property target
- * @type Sprite
- */
- this.target = null;
-
- /**
- * When passed to an event handler, this will be the original DOM Event that was captured
- *
- * @property originalEvent
- * @type Event
- */
- this.originalEvent = null;
-};
-
-/**
- * This will return the local coords of the specified displayObject for this InteractionData
- *
- * @method getLocalPosition
- * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
- * @return {Point} A point containing the coords of the InteractionData position relative to the DisplayObject
- */
-PIXI.InteractionData.prototype.getLocalPosition = function(displayObject)
-{
- var worldTransform = displayObject.worldTransform;
- var global = this.global;
-
- // do a cheeky transform to get the mouse coords;
- var a00 = worldTransform[0], a01 = worldTransform[1], a02 = worldTransform[2],
- a10 = worldTransform[3], a11 = worldTransform[4], a12 = worldTransform[5],
- id = 1 / (a00 * a11 + a01 * -a10);
- // set the mouse coords...
- return new PIXI.Point(a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
- a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id);
-};
-
-// constructor
-PIXI.InteractionData.prototype.constructor = PIXI.InteractionData;
+};
\ No newline at end of file
diff --git a/src/pixi/Pixi.js b/src/pixi/Pixi.js
index bc71d47c..768ef4e4 100644
--- a/src/pixi/Pixi.js
+++ b/src/pixi/Pixi.js
@@ -6,3 +6,41 @@
* @module PIXI
*/
var PIXI = PIXI || {};
+
+PIXI.WEBGL_RENDERER = 0;
+PIXI.CANVAS_RENDERER = 1;
+
+// useful for testing against if your lib is using pixi.
+PIXI.VERSION = "v1.4.4";
+
+// the various blend modes supported by pixi
+PIXI.blendModes = {
+ NORMAL:0,
+ ADD:1,
+ MULTIPLY:2,
+ SCREEN:3,
+ OVERLAY:4,
+ DARKEN:5,
+ LIGHTEN:6,
+ COLOR_DODGE:7,
+ COLOR_BURN:8,
+ HARD_LIGHT:9,
+ SOFT_LIGHT:10,
+ DIFFERENCE:11,
+ EXCLUSION:12,
+ HUE:13,
+ SATURATION:14,
+ COLOR:15,
+ LUMINOSITY:16
+};
+
+// the scale modes
+PIXI.scaleModes = {
+ DEFAULT:0,
+ LINEAR:0,
+ NEAREST:1
+};
+
+// interaction frequency
+PIXI.INTERACTION_FREQUENCY = 30;
+PIXI.AUTO_PREVENT_DEFAULT = true;
\ No newline at end of file
diff --git a/src/pixi/core/Circle.js b/src/pixi/core/Circle.js
index d1724619..114b498a 100644
--- a/src/pixi/core/Circle.js
+++ b/src/pixi/core/Circle.js
@@ -3,12 +3,12 @@
*/
/**
- * The Circle object can be used to specify a hit area for displayobjects
+ * The Circle object can be used to specify a hit area for displayObjects
*
* @class Circle
* @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this circle
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this circle
+ * @param x {Number} The X coordinate of the upper-left corner of the framing rectangle of this circle
+ * @param y {Number} The Y coordinate of the upper-left corner of the framing rectangle of this circle
* @param radius {Number} The radius of the circle
*/
PIXI.Circle = function(x, y, radius)
@@ -47,12 +47,12 @@ PIXI.Circle.prototype.clone = function()
};
/**
- * Checks if the x, and y coords passed to this function are contained within this circle
+ * Checks whether the x, and y coordinates passed to this function are contained within this circle
*
* @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this polygon
+ * @param x {Number} The X coordinate of the point to test
+ * @param y {Number} The Y coordinate of the point to test
+ * @return {Boolean} Whether the x/y coordinates are within this polygon
*/
PIXI.Circle.prototype.contains = function(x, y)
{
diff --git a/src/pixi/core/Ellipse.js b/src/pixi/core/Ellipse.js
index 7a9c2f64..e65313ab 100644
--- a/src/pixi/core/Ellipse.js
+++ b/src/pixi/core/Ellipse.js
@@ -3,12 +3,12 @@
*/
/**
- * The Ellipse object can be used to specify a hit area for displayobjects
+ * The Ellipse object can be used to specify a hit area for displayObjects
*
* @class Ellipse
* @constructor
- * @param x {Number} The X coord of the upper-left corner of the framing rectangle of this ellipse
- * @param y {Number} The Y coord of the upper-left corner of the framing rectangle of this ellipse
+ * @param x {Number} The X coordinate of the upper-left corner of the framing rectangle of this ellipse
+ * @param y {Number} The Y coordinate of the upper-left corner of the framing rectangle of this ellipse
* @param width {Number} The overall width of this ellipse
* @param height {Number} The overall height of this ellipse
*/
@@ -55,12 +55,12 @@ PIXI.Ellipse.prototype.clone = function()
};
/**
- * Checks if the x, and y coords passed to this function are contained within this ellipse
+ * Checks whether the x and y coordinates passed to this function are contained within this ellipse
*
* @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this ellipse
+ * @param x {Number} The X coordinate of the point to test
+ * @param y {Number} The Y coordinate of the point to test
+ * @return {Boolean} Whether the x/y coords are within this ellipse
*/
PIXI.Ellipse.prototype.contains = function(x, y)
{
@@ -78,6 +78,12 @@ PIXI.Ellipse.prototype.contains = function(x, y)
return (normx + normy < 0.25);
};
+/**
+* Returns the framing rectangle of the ellipse as a PIXI.Rectangle object
+*
+* @method getBounds
+* @return {Rectangle} the framing rectangle
+*/
PIXI.Ellipse.prototype.getBounds = function()
{
return new PIXI.Rectangle(this.x, this.y, this.width, this.height);
diff --git a/src/pixi/core/Matrix.js b/src/pixi/core/Matrix.js
index 1f5a67a5..5550bcf5 100644
--- a/src/pixi/core/Matrix.js
+++ b/src/pixi/core/Matrix.js
@@ -1,293 +1,70 @@
-
-
-/*
- * A lighter version of the rad gl-matrix created by Brandon Jones, Colin MacKenzie IV
- * you both rock!
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
*/
-function determineMatrixArrayType() {
- PIXI.Matrix = (typeof Float32Array !== 'undefined') ? Float32Array : Array;
- return PIXI.Matrix;
-}
-
-determineMatrixArrayType();
-
-PIXI.mat3 = {};
-
-PIXI.mat3.create = function()
-{
- 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;
-
- return matrix;
+/*
+* @class Matrix
+* The Matrix class will choose the best type of array to use between
+* a regular javascript Array and a Float32Array if the latter is available
+*
+*/
+PIXI.determineMatrixArrayType = function() {
+ return (typeof Float32Array !== 'undefined') ? Float32Array : Array;
};
+PIXI.Matrix2 = PIXI.determineMatrixArrayType();
-PIXI.mat3.identity = function(matrix)
+PIXI.Matrix = function()
{
- 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;
+ this.a = 1;
+ this.b = 0;
+ this.c = 0;
+ this.d = 1;
+ this.tx = 0;
+ this.ty = 0;
};
-
-PIXI.mat4 = {};
-
-PIXI.mat4.create = function()
+PIXI.Matrix.prototype.fromArray = function(array)
{
- 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;
-
- return matrix;
+ this.a = array[0];
+ this.b = array[1];
+ this.c = array[3];
+ this.d = array[4];
+ this.tx = array[2];
+ this.ty = array[5];
};
-PIXI.mat3.multiply = function (mat, mat2, dest)
+PIXI.Matrix.prototype.toArray = function(transpose)
{
- if (!dest) { dest = mat; }
+ if(!this.array) this.array = new Float32Array(9);
+ var array = this.array;
- // 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];
-
- 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[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;
-};
-
-PIXI.mat3.clone = function(mat)
-{
- 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];
-
- 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 (!dest || mat === dest) {
- var a01 = mat[1], a02 = mat[2],
- a12 = mat[5];
-
- mat[1] = mat[3];
- mat[2] = mat[6];
- mat[3] = a01;
- mat[5] = mat[7];
- mat[6] = a02;
- mat[7] = a12;
- return mat;
- }
-
- dest[0] = mat[0];
- dest[1] = mat[3];
- dest[2] = mat[6];
- dest[3] = mat[1];
- dest[4] = mat[4];
- dest[5] = mat[7];
- dest[6] = mat[2];
- dest[7] = mat[5];
- dest[8] = mat[8];
- return dest;
-};
-
-PIXI.mat3.toMat4 = function (mat, dest)
-{
- if (!dest) { dest = PIXI.mat4.create(); }
-
- 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[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];
-
- return dest;
-};
-
-
-/////
-
-
-PIXI.mat4.create = function()
-{
- 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;
-
- 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)
+ if(transpose)
{
- 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;
+ this.array[0] = this.a;
+ this.array[1] = this.c;
+ this.array[2] = 0;
+ this.array[3] = this.b;
+ this.array[4] = this.d;
+ this.array[5] = 0;
+ this.array[6] = this.tx;
+ this.array[7] = this.ty;
+ this.array[8] = 1;
+ }
+ else
+ {
+ this.array[0] = this.a;
+ this.array[1] = this.b;
+ this.array[2] = this.tx;
+ this.array[3] = this.c;
+ this.array[4] = this.d;
+ this.array[5] = this.ty;
+ this.array[6] = 0;
+ this.array[7] = 0;
+ this.array[8] = 1;
}
- 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;
+ return array;//[this.a, this.b, this.tx, this.c, this.d, this.ty, 0, 0, 1];
};
-PIXI.mat4.multiply = function (mat, mat2, dest)
-{
- 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 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;
- dest[2] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[3] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[4];
- b1 = mat2[5];
- b2 = mat2[6];
- b3 = mat2[7];
- dest[4] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[5] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[6] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[7] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[8];
- b1 = mat2[9];
- b2 = mat2[10];
- b3 = mat2[11];
- dest[8] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[9] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[10] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[11] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- b0 = mat2[12];
- b1 = mat2[13];
- b2 = mat2[14];
- b3 = mat2[15];
- dest[12] = b0*a00 + b1*a10 + b2*a20 + b3*a30;
- dest[13] = b0*a01 + b1*a11 + b2*a21 + b3*a31;
- dest[14] = b0*a02 + b1*a12 + b2*a22 + b3*a32;
- dest[15] = b0*a03 + b1*a13 + b2*a23 + b3*a33;
-
- return dest;
-};
+PIXI.identityMatrix = new PIXI.Matrix();
\ No newline at end of file
diff --git a/src/pixi/core/Point.js b/src/pixi/core/Point.js
index c7e27720..a3c8e5e1 100644
--- a/src/pixi/core/Point.js
+++ b/src/pixi/core/Point.js
@@ -7,8 +7,8 @@
*
* @class Point
* @constructor
- * @param x {Number} position of the point
- * @param y {Number} position of the point
+ * @param x {Number} position of the point on the x axis
+ * @param y {Number} position of the point on the y axis
*/
PIXI.Point = function(x, y)
{
@@ -41,3 +41,9 @@ PIXI.Point.prototype.clone = function()
// constructor
PIXI.Point.prototype.constructor = PIXI.Point;
+PIXI.Point.prototype.set = function(x, y)
+{
+ this.x = x || 0;
+ this.y = y || ( (y !== 0) ? this.x : 0 ) ;
+};
+
diff --git a/src/pixi/core/Polygon.js b/src/pixi/core/Polygon.js
index 4887f6c4..b1188186 100644
--- a/src/pixi/core/Polygon.js
+++ b/src/pixi/core/Polygon.js
@@ -49,12 +49,12 @@ PIXI.Polygon.prototype.clone = function()
};
/**
- * Checks if the x, and y coords passed to this function are contained within this polygon
+ * Checks whether the x and y coordinates passed to this function are contained within this polygon
*
* @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this polygon
+ * @param x {Number} The X coordinate of the point to test
+ * @param y {Number} The Y coordinate of the point to test
+ * @return {Boolean} Whether the x/y coordinates are within this polygon
*/
PIXI.Polygon.prototype.contains = function(x, y)
{
diff --git a/src/pixi/core/Rectangle.js b/src/pixi/core/Rectangle.js
index 70390a16..b8edfcce 100644
--- a/src/pixi/core/Rectangle.js
+++ b/src/pixi/core/Rectangle.js
@@ -55,12 +55,12 @@ PIXI.Rectangle.prototype.clone = function()
};
/**
- * Checks if the x, and y coords passed to this function are contained within this Rectangle
+ * Checks whether the x and y coordinates passed to this function are contained within this Rectangle
*
* @method contains
- * @param x {Number} The X coord of the point to test
- * @param y {Number} The Y coord of the point to test
- * @return {Boolean} if the x/y coords are within this Rectangle
+ * @param x {Number} The X coordinate of the point to test
+ * @param y {Number} The Y coordinate of the point to test
+ * @return {Boolean} Whether the x/y coords are within this Rectangle
*/
PIXI.Rectangle.prototype.contains = function(x, y)
{
@@ -84,3 +84,4 @@ PIXI.Rectangle.prototype.contains = function(x, y)
// constructor
PIXI.Rectangle.prototype.constructor = PIXI.Rectangle;
+PIXI.EmptyRectangle = new PIXI.Rectangle(0,0,0,0);
\ No newline at end of file
diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js
index 53cce04d..09f33cd9 100644
--- a/src/pixi/display/DisplayObject.js
+++ b/src/pixi/display/DisplayObject.js
@@ -104,7 +104,7 @@ PIXI.DisplayObject = function()
this.stage = null;
/**
- * [read-only] The multiplied alpha of the displayobject
+ * [read-only] The multiplied alpha of the displayObject
*
* @property worldAlpha
* @type Number
@@ -122,6 +122,13 @@ PIXI.DisplayObject = function()
*/
this._interactive = false;
+ /**
+ * This is the cursor that will be used when the mouse is over this object. To enable this the element must have interaction = true and buttonMode = true
+ *
+ * @property defaultCursor
+ * @type String
+ *
+ */
this.defaultCursor = 'pointer';
/**
@@ -132,20 +139,10 @@ PIXI.DisplayObject = function()
* @readOnly
* @private
*/
- this.worldTransform = PIXI.mat3.create(); //mat3.identity();
+ this.worldTransform = new PIXI.Matrix();
/**
- * [read-only] Current transform of the object locally
- *
- * @property localTransform
- * @type Mat3
- * @readOnly
- * @private
- */
- this.localTransform = PIXI.mat3.create(); //mat3.identity();
-
- /**
- * [NYI] Unkown
+ * [NYI] Unknown
*
* @property color
* @type Array<>
@@ -162,13 +159,43 @@ PIXI.DisplayObject = function()
*/
this.dynamic = true;
- // chach that puppy!
+ // cached sin rotation and cos rotation
this._sr = 0;
this._cr = 1;
-
+ /**
+ * The area the filter is applied to
+ *
+ * @property filterArea
+ * @type Rectangle
+ */
this.filterArea = new PIXI.Rectangle(0,0,1,1);
+ /**
+ * The original, cached bounds of the object
+ *
+ * @property _bounds
+ * @type Rectangle
+ * @private
+ */
+ this._bounds = new PIXI.Rectangle(0, 0, 1, 1);
+ /**
+ * The most up-to-date bounds of the object
+ *
+ * @property _currentBounds
+ * @type Rectangle
+ * @private
+ */
+ this._currentBounds = null;
+ /**
+ * The original, cached mask of the object
+ *
+ * @property _currentBounds
+ * @type Rectangle
+ * @private
+ */
+ this._mask = null;
+
/*
* MOUSE Callbacks
*/
@@ -224,7 +251,7 @@ PIXI.DisplayObject = function()
*/
/**
- * A callback that is used when the user touch's over the displayObject
+ * A callback that is used when the user touches over the displayObject
* @method touchstart
* @param interactionData {InteractionData}
*/
@@ -279,9 +306,30 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'interactive', {
}
});
+/**
+ * [read-only] Indicates if the sprite is globaly visible.
+ *
+ * @property worldVisible
+ * @type Boolean
+ */
+Object.defineProperty(PIXI.DisplayObject.prototype, 'worldVisible', {
+ get: function() {
+ var item = this;
+
+ do
+ {
+ if(!item.visible)return false;
+ item = item.parent;
+ }
+ while(item);
+
+ return true;
+ }
+});
+
/**
* Sets a mask for the displayObject. A mask is an object that limits the visibility of an object to the shape of the mask applied to it.
- * In PIXI a regular mask must be a PIXI.Ggraphics object. This allows for much faster masking in canvas as it utilises shape clipping.
+ * In PIXI a regular mask must be a PIXI.Graphics object. This allows for much faster masking in canvas as it utilises shape clipping.
* To remove a mask, set this property to null.
*
* @property mask
@@ -293,27 +341,9 @@ Object.defineProperty(PIXI.DisplayObject.prototype, '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;
- }
- }
- else
- {
- this.removeFilter(this._mask);
- this._mask.renderable = true;
- }
-
+ if(this._mask)this._mask.isMask = false;
this._mask = value;
+ if(this._mask)this._mask.isMask = true;
}
});
@@ -332,9 +362,6 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', {
if(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++)
@@ -346,172 +373,14 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', {
}
}
- value.start.filterPasses = passes;
- }
- else
- {
- if(this._filters) {
- this.removeFilter(this._filters);
- }
+ // TODO change this as it is legacy
+ this._filterBlock = {target:this, filterPasses:passes};
}
this._filters = value;
}
});
-/*
- * Adds a filter to this displayObject
- *
- * @method addFilter
- * @param mask {Graphics} the graphics object to use as a filter
- * @private
- */
-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
- */
- 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
- *
- * @method removeFilter
- * @private
- */
-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;
-
- 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
*
@@ -523,48 +392,139 @@ PIXI.DisplayObject.prototype.updateTransform = function()
// TODO OPTIMIZE THIS!! with dirty
if(this.rotation !== this.rotationCache)
{
+ if(isNaN(parseFloat(this.rotation)))
+ throw new Error('DisplayObject rotation values must be numeric.');
+
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;
+ // var localTransform = this.localTransform//.toArray();
+ var parentTransform = this.parent.worldTransform;//.toArray();
+ var worldTransform = this.worldTransform;//.toArray();
//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],
+ var a00 = this._cr * this.scale.x,
+ a01 = -this._sr * this.scale.y,
+ a10 = this._sr * this.scale.x,
+ a11 = this._cr * this.scale.y,
+ a02 = this.position.x + a00 * px - py * a01,
+ a12 = this.position.y + a11 * py - px * a10,
+ b00 = parentTransform.a, b01 = parentTransform.b, b02 = parentTransform.tx,
+ b10 = parentTransform.c, b11 = parentTransform.d, b12 = parentTransform.ty;
- b00 = parentTransform[0], b01 = parentTransform[1], b02 = parentTransform[2],
- b10 = parentTransform[3], b11 = parentTransform[4], b12 = parentTransform[5];
+ worldTransform.a = b00 * a00 + b01 * a10;
+ worldTransform.b = b00 * a01 + b01 * a11;
+ worldTransform.tx = b00 * a02 + b01 * a12 + b02;
- localTransform[2] = a02;
- localTransform[5] = a12;
+ worldTransform.c = b10 * a00 + b11 * a10;
+ worldTransform.d = b10 * a01 + b11 * a11;
+ worldTransform.ty = b10 * a02 + b11 * a12 + b12;
- worldTransform[0] = b00 * a00 + b01 * a10;
- worldTransform[1] = b00 * a01 + b01 * a11;
- worldTransform[2] = b00 * a02 + b01 * a12 + b02;
-
- worldTransform[3] = b10 * a00 + b11 * a10;
- 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;
};
-PIXI.visibleCount = 0;
\ No newline at end of file
+/**
+ * Retrieves the bounds of the displayObject as a rectangle object
+ *
+ * @method getBounds
+ * @return {Rectangle} the rectangular bounding area
+ */
+PIXI.DisplayObject.prototype.getBounds = function()
+{
+ return PIXI.EmptyRectangle;
+};
+
+/**
+ * Retrieves the local bounds of the displayObject as a rectangle object
+ *
+ * @method getLocalBounds
+ * @return {Rectangle} the rectangular bounding area
+ */
+PIXI.DisplayObject.prototype.getLocalBounds = function()
+{
+ var matrixCache = this.worldTransform;
+
+ this.worldTransform = PIXI.identityMatrix;
+
+ this.updateTransform();
+
+ var bounds = this.getBounds();
+
+ this.worldTransform = matrixCache;
+
+ return bounds;
+};
+
+/**
+ * Sets the object's stage reference, the stage this object is connected to
+ *
+ * @method setStageReference
+ * @param stage {Stage} the stage that the object will have as its current stage reference
+ */
+PIXI.DisplayObject.prototype.setStageReference = function(stage)
+{
+ this.stage = stage;
+ if(this._interactive)this.stage.dirty = true;
+};
+
+/**
+* Renders the object using the WebGL renderer
+*
+* @method _renderWebGL
+* @param renderSession {RenderSession}
+* @private
+*/
+PIXI.DisplayObject.prototype._renderWebGL = function(renderSession)
+{
+ // OVERWRITE;
+ // this line is just here to pass jshinting :)
+ renderSession = renderSession;
+};
+
+/**
+* Renders the object using the Canvas renderer
+*
+* @method _renderCanvas
+* @param renderSession {RenderSession}
+* @private
+*/
+PIXI.DisplayObject.prototype._renderCanvas = function(renderSession)
+{
+ // OVERWRITE;
+ // this line is just here to pass jshinting :)
+ renderSession = renderSession;
+};
+
+/**
+ * The position of the displayObject on the x axis relative to the local coordinates of the parent.
+ *
+ * @property x
+ * @type Number
+ */
+Object.defineProperty(PIXI.DisplayObject.prototype, 'x', {
+ get: function() {
+ return this.position.x;
+ },
+ set: function(value) {
+ this.position.x = value;
+ }
+});
+
+/**
+ * The position of the displayObject on the y axis relative to the local coordinates of the parent.
+ *
+ * @property y
+ * @type Number
+ */
+Object.defineProperty(PIXI.DisplayObject.prototype, 'y', {
+ get: function() {
+ return this.position.y;
+ },
+ set: function(value) {
+ this.position.y = value;
+ }
+});
diff --git a/src/pixi/display/DisplayObjectContainer.js b/src/pixi/display/DisplayObjectContainer.js
index 44cbaa19..357dbe8c 100644
--- a/src/pixi/display/DisplayObjectContainer.js
+++ b/src/pixi/display/DisplayObjectContainer.js
@@ -29,6 +29,44 @@ PIXI.DisplayObjectContainer = function()
PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype );
PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer;
+/**
+ * The width of the displayObjectContainer, setting this will actually modify the scale to achieve the value set
+ *
+ * @property width
+ * @type Number
+ */
+
+/*
+Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'width', {
+ get: function() {
+ return this.scale.x * this.getLocalBounds().width;
+ },
+ set: function(value) {
+ this.scale.x = value / (this.getLocalBounds().width/this.scale.x);
+ this._width = value;
+ }
+});
+*/
+
+/**
+ * The height of the displayObjectContainer, setting this will actually modify the scale to achieve the value set
+ *
+ * @property height
+ * @type Number
+ */
+
+ /*
+Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'height', {
+ get: function() {
+ return this.scale.y * this.getLocalBounds().height;
+ },
+ set: function(value) {
+ this.scale.y = value / (this.getLocalBounds().height/this.scale.y);
+ this._height = value;
+ }
+});
+*/
+
/**
* Adds a child to the container.
*
@@ -37,82 +75,7 @@ PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer;
*/
PIXI.DisplayObjectContainer.prototype.addChild = function(child)
{
- 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;
- }
-
- 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);
- }
+ this.addChildAt(child, this.children.length);
};
/**
@@ -126,76 +89,16 @@ PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index)
{
if(index >= 0 && index <= this.children.length)
{
- if(child.parent !== undefined)
+ if(child.parent)
{
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;
-
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);
- }
+ if(this.stage)child.setStageReference(this.stage);
}
else
{
@@ -224,23 +127,13 @@ PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2)
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);
- }
+ this.children[index1] = child2;
+ this.children[index2] = child;
+
};
/**
- * Returns the Child at the specified index
+ * Returns the child at the specified index
*
* @method getChildAt
* @param index {Number} The index to get the child from
@@ -253,7 +146,7 @@ PIXI.DisplayObjectContainer.prototype.getChildAt = function(index)
}
else
{
- throw new Error('Both the supplied DisplayObjects must be a child of the caller ' + this);
+ throw new Error('The supplied DisplayObjects must be a child of the caller ' + this);
}
};
@@ -268,53 +161,8 @@ 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)
- {
- 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);
- }
+ if(this.stage)child.removeStageReference();
child.parent = undefined;
this.children.splice( index, 1 );
@@ -326,13 +174,15 @@ PIXI.DisplayObjectContainer.prototype.removeChild = function(child)
};
/*
- * Updates the container's children's transform for rendering
+ * Updates the container's childrens transform for rendering
*
* @method updateTransform
* @private
*/
PIXI.DisplayObjectContainer.prototype.updateTransform = function()
{
+ //this._currentBounds = null;
+
if(!this.visible)return;
PIXI.DisplayObject.prototype.updateTransform.call( this );
@@ -342,3 +192,181 @@ PIXI.DisplayObjectContainer.prototype.updateTransform = function()
this.children[i].updateTransform();
}
};
+
+/**
+ * Retrieves the bounds of the displayObjectContainer as a rectangle object
+ *
+ * @method getBounds
+ * @return {Rectangle} the rectangular bounding area
+ */
+PIXI.DisplayObjectContainer.prototype.getBounds = function()
+{
+ if(this.children.length === 0)return PIXI.EmptyRectangle;
+
+ // TODO the bounds have already been calculated this render session so return what we have
+
+
+ var minX = Infinity;
+ var minY = Infinity;
+
+ var maxX = -Infinity;
+ var maxY = -Infinity;
+
+ var childBounds;
+ var childMaxX;
+ var childMaxY;
+
+ var childVisible = false;
+
+ for(var i=0,j=this.children.length; i childMaxX ? maxX : childMaxX;
+ maxY = maxY > childMaxY ? maxY : childMaxY;
+ }
+
+ if(!childVisible)
+ return PIXI.EmptyRectangle;
+
+ var bounds = this._bounds;
+
+ bounds.x = minX;
+ bounds.y = minY;
+ bounds.width = maxX - minX;
+ bounds.height = maxY - minY;
+
+ // TODO: store a reference so that if this function gets called again in the render cycle we do not have to recalculate
+ //this._currentBounds = bounds;
+
+ return bounds;
+};
+
+/**
+ * Sets the container's stage reference, the stage this object is connected to
+ *
+ * @method setStageReference
+ * @param stage {Stage} the stage that the container will have as its current stage reference
+ */
+PIXI.DisplayObjectContainer.prototype.setStageReference = function(stage)
+{
+ this.stage = stage;
+ if(this._interactive)this.stage.dirty = true;
+
+ for(var i=0,j=this.children.length; i 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;
+
+ var bounds = this._bounds;
+
+ bounds.x = minX;
+ bounds.width = maxX - minX;
+
+ bounds.y = minY;
+ bounds.height = maxY - minY;
+
+ // store a reference so that if this function gets called again in the render cycle we do not have to recalculate
+ this._currentBounds = bounds;
+
+ return bounds;
+};
+
+/**
+* Renders the object using the WebGL renderer
+*
+* @method _renderWebGL
+* @param renderSession {RenderSession}
+* @private
+*/
+PIXI.Sprite.prototype._renderWebGL = function(renderSession)
+{
+ // if the sprite is not visible or the alpha is 0 then no need to render this element
+ if(!this.visible || this.alpha <= 0)return;
+
+ var i,j;
+
+ // do a quick check to see if this element has a mask or a filter.
+ if(this._mask || this._filters)
+ {
+ var spriteBatch = renderSession.spriteBatch;
+
+ if(this._mask)
+ {
+ spriteBatch.stop();
+ renderSession.maskManager.pushMask(this.mask, renderSession);
+ spriteBatch.start();
+ }
+
+ if(this._filters)
+ {
+ spriteBatch.flush();
+ renderSession.filterManager.pushFilter(this._filterBlock);
+ }
+
+ // add this sprite to the batch
+ spriteBatch.render(this);
+
+ // now loop through the children and make sure they get rendered
+ for(i=0,j=this.children.length; i 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;
+
+ var bounds = this._bounds;
+
+ bounds.x = minX;
+ bounds.width = maxX - minX;
+
+ bounds.y = minY;
+ bounds.height = maxY - minY;
+
+ // store a reference so that if this function gets called again in the render cycle we do not have to recalculate
+ this._currentBounds = bounds;
+
+ return bounds;
+};
+
+
+PIXI.TilingSprite.prototype.generateTilingTexture = function(forcePowerOfTwo)
+{
+ var texture = this.texture;
+
+ if(!texture.baseTexture.hasLoaded)return;
+
+ var baseTexture = texture.baseTexture;
+ var frame = texture.frame;
+
+ var targetWidth, targetHeight;
+
+ // check that the frame is the same size as the base texture.
+
+ var isFrame = frame.width !== baseTexture.width || frame.height !== baseTexture.height;
+
+ this.tilingTexture = texture;
+
+ var newTextureRequired = false;
+
+ if(!forcePowerOfTwo)
+ {
+ if(isFrame)
+ {
+ targetWidth = frame.width;
+ targetHeight = frame.height;
+
+ newTextureRequired = true;
+ }
+ }
+ else
+ {
+ targetWidth = PIXI.getNextPowerOfTwo(texture.frame.width);
+ targetHeight = PIXI.getNextPowerOfTwo(texture.frame.height);
+
+ if(frame.width !== targetWidth && frame.height !== targetHeight)newTextureRequired = true;
+ }
+
+ if(newTextureRequired)
+ {
+ var canvasBuffer = new PIXI.CanvasBuffer(targetWidth, targetHeight);
+
+ canvasBuffer.context.drawImage(texture.baseTexture.source,
+ frame.x,
+ frame.y,
+ frame.width,
+ frame.height,
+ 0,
+ 0,
+ targetWidth,
+ targetHeight);
+
+ this.tilingTexture = PIXI.Texture.fromCanvas(canvasBuffer.canvas);
+
+ this.tileScaleOffset.x = frame.width / targetWidth;
+ this.tileScaleOffset.y = frame.height / targetHeight;
+ }
+
+
+ this.tilingTexture.baseTexture._powerOf2 = true;
+};
\ No newline at end of file
diff --git a/src/pixi/filters/AbstractFilter.js b/src/pixi/filters/AbstractFilter.js
index 43665de4..f9ca0b3c 100644
--- a/src/pixi/filters/AbstractFilter.js
+++ b/src/pixi/filters/AbstractFilter.js
@@ -3,7 +3,7 @@
*/
/**
- * This is the base class for creating a pixi.js filter. Currently only webGL supports filters.
+ * 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
@@ -21,15 +21,26 @@ PIXI.AbstractFilter = function(fragmentSrc, uniforms)
*/
this.passes = [this];
-
+ /**
+ * @property shaders
+ * @type Array an array of shaders
+ * @private
+ */
+ this.shaders = [];
+
this.dirty = true;
this.padding = 0;
/**
- @property uniforms
- @private
+ * @property uniforms
+ * @type object
+ * @private
*/
this.uniforms = uniforms || {};
-
+ /**
+ * @property fragmentSrc
+ * @type Array
+ * @private
+ */
this.fragmentSrc = fragmentSrc || [];
};
diff --git a/src/pixi/filters/AlphaMaskFilter.js b/src/pixi/filters/AlphaMaskFilter.js
new file mode 100644
index 00000000..5d694128
--- /dev/null
+++ b/src/pixi/filters/AlphaMaskFilter.js
@@ -0,0 +1,93 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+/**
+ *
+ * The AlphaMaskFilter class uses the pixel values from the specified texture (called the displacement map) to perform a displacement of an object.
+ * You can use this filter to apply all manor of crazy warping effects
+ * Currently the r property of the texture is used to offset the x and the g propery of the texture is used to offset the y.
+ * @class AlphaMaskFilter
+ * @contructor
+ * @param texture {Texture} The texture used for the displacemtent map * must be power of 2 texture at the moment
+ */
+PIXI.AlphaMaskFilter = function(texture)
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+ texture.baseTexture._powerOf2 = true;
+
+ // set the uniforms
+ //console.log()
+ this.uniforms = {
+ mask: {type: 'sampler2D', value:texture},
+ mapDimensions: {type: '2f', value:{x:1, y:5112}},
+ dimensions: {type: '4fv', value:[0,0,0,0]}
+ };
+
+ if(texture.baseTexture.hasLoaded)
+ {
+ this.uniforms.mask.value.x = texture.width;
+ this.uniforms.mask.value.y = texture.height;
+ }
+ else
+ {
+ this.boundLoadedFunction = this.onTextureLoaded.bind(this);
+
+ texture.baseTexture.on('loaded', this.boundLoadedFunction);
+ }
+
+ this.fragmentSrc = [
+ 'precision mediump float;',
+ 'varying vec2 vTextureCoord;',
+ 'varying vec4 vColor;',
+ 'uniform sampler2D mask;',
+ 'uniform sampler2D uSampler;',
+ 'uniform vec2 offset;',
+ 'uniform vec4 dimensions;',
+ 'uniform vec2 mapDimensions;',
+
+ 'void main(void) {',
+ ' vec2 mapCords = vTextureCoord.xy;',
+ ' mapCords += (dimensions.zw + offset)/ dimensions.xy ;',
+ ' mapCords.y *= -1.0;',
+ ' mapCords.y += 1.0;',
+ ' mapCords *= dimensions.xy / mapDimensions;',
+
+ ' vec4 original = texture2D(uSampler, vTextureCoord);',
+ ' float maskAlpha = texture2D(mask, mapCords).r;',
+ ' original *= maskAlpha;',
+ //' original.rgb *= maskAlpha;',
+ ' gl_FragColor = original;',
+ //' gl_FragColor = gl_FragColor;',
+ '}'
+ ];
+};
+
+PIXI.AlphaMaskFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.AlphaMaskFilter.prototype.constructor = PIXI.AlphaMaskFilter;
+
+PIXI.AlphaMaskFilter.prototype.onTextureLoaded = function()
+{
+ this.uniforms.mapDimensions.value.x = this.uniforms.mask.value.width;
+ this.uniforms.mapDimensions.value.y = this.uniforms.mask.value.height;
+
+ this.uniforms.mask.value.baseTexture.off('loaded', this.boundLoadedFunction);
+};
+
+/**
+ * The texture used for the displacemtent map * must be power of 2 texture at the moment
+ *
+ * @property map
+ * @type Texture
+ */
+Object.defineProperty(PIXI.AlphaMaskFilter.prototype, 'map', {
+ get: function() {
+ return this.uniforms.mask.value;
+ },
+ set: function(value) {
+ this.uniforms.mask.value = value;
+ }
+});
+
diff --git a/src/pixi/filters/BlurFilter.js b/src/pixi/filters/BlurFilter.js
index 5f89bff8..1b5cddb8 100644
--- a/src/pixi/filters/BlurFilter.js
+++ b/src/pixi/filters/BlurFilter.js
@@ -35,7 +35,7 @@ Object.defineProperty(PIXI.BlurFilter.prototype, 'blur', {
});
/**
- * Sets the strength of the blurX property simultaneously
+ * Sets the strength of the blurX property
*
* @property blurX
* @type Number the strength of the blurX
@@ -51,7 +51,7 @@ Object.defineProperty(PIXI.BlurFilter.prototype, 'blurX', {
});
/**
- * Sets the strength of the blurX property simultaneously
+ * Sets the strength of the blurX property
*
* @property blurY
* @type Number the strength of the blurY
diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js
index 6e7be332..35837919 100644
--- a/src/pixi/filters/BlurXFilter.js
+++ b/src/pixi/filters/BlurXFilter.js
@@ -16,7 +16,7 @@ PIXI.BlurXFilter = function()
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform float blur;',
'uniform sampler2D uSampler;',
diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js
index 99829fb7..82a74602 100644
--- a/src/pixi/filters/BlurYFilter.js
+++ b/src/pixi/filters/BlurYFilter.js
@@ -16,7 +16,7 @@ PIXI.BlurYFilter = function()
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform float blur;',
'uniform sampler2D uSampler;',
diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js
index 122b6fbd..8d08eea3 100644
--- a/src/pixi/filters/ColorMatrixFilter.js
+++ b/src/pixi/filters/ColorMatrixFilter.js
@@ -27,14 +27,14 @@ PIXI.ColorMatrixFilter = function()
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform float invert;',
'uniform mat4 matrix;',
'uniform sampler2D uSampler;',
'void main(void) {',
' gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;',
- ' gl_FragColor = gl_FragColor * vColor;',
+ // ' gl_FragColor = gl_FragColor;',
'}'
];
};
diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js
index c83c887b..e8f76505 100644
--- a/src/pixi/filters/ColorStepFilter.js
+++ b/src/pixi/filters/ColorStepFilter.js
@@ -4,7 +4,7 @@
/**
*
- * This turns your displayObjects to black and white.
+ * This lowers the color depth of your image by the given amount, producing an image with a smaller palette.
* @class ColorStepFilter
* @contructor
*/
@@ -22,14 +22,14 @@ PIXI.ColorStepFilter = function()
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform sampler2D uSampler;',
'uniform float step;',
'void main(void) {',
' vec4 color = texture2D(uSampler, vTextureCoord);',
' color = floor(color * step) / step;',
- ' gl_FragColor = color * vColor;',
+ ' gl_FragColor = color;',
'}'
];
};
diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js
index 43f3c261..3426b544 100644
--- a/src/pixi/filters/CrossHatchFilter.js
+++ b/src/pixi/filters/CrossHatchFilter.js
@@ -16,7 +16,7 @@ PIXI.CrossHatchFilter = function()
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform float blur;',
'uniform sampler2D uSampler;',
diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js
index 21853fd5..f36447b3 100644
--- a/src/pixi/filters/DisplacementFilter.js
+++ b/src/pixi/filters/DisplacementFilter.js
@@ -19,6 +19,7 @@ PIXI.DisplacementFilter = function(texture)
texture.baseTexture._powerOf2 = true;
// set the uniforms
+ //console.log()
this.uniforms = {
displacementMap: {type: 'sampler2D', value:texture},
scale: {type: '2f', value:{x:30, y:30}},
@@ -42,7 +43,7 @@ PIXI.DisplacementFilter = function(texture)
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform sampler2D displacementMap;',
'uniform sampler2D uSampler;',
'uniform vec2 scale;',
@@ -66,7 +67,7 @@ PIXI.DisplacementFilter = function(texture)
' vec2 cord = vTextureCoord;',
//' gl_FragColor = texture2D(displacementMap, cord);',
- ' gl_FragColor = gl_FragColor * vColor;',
+ // ' gl_FragColor = gl_FragColor;',
'}'
];
};
diff --git a/src/pixi/filters/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js
index 7a684a13..8c9a49fd 100644
--- a/src/pixi/filters/DotScreenFilter.js
+++ b/src/pixi/filters/DotScreenFilter.js
@@ -5,8 +5,8 @@
/**
*
- * This filter applies a pixlate effect making display objects appear 'blocky'
- * @class PixelateFilter
+ * This filter applies a dotscreen effect making display objects appear to be made out of black and white halftone dots like an old printer
+ * @class DotScreenFilter
* @contructor
*/
PIXI.DotScreenFilter = function()
@@ -25,7 +25,7 @@ PIXI.DotScreenFilter = function()
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform vec4 dimensions;',
'uniform sampler2D uSampler;',
diff --git a/src/pixi/filters/GrayFilter.js b/src/pixi/filters/GrayFilter.js
index 5065834a..34a52b14 100644
--- a/src/pixi/filters/GrayFilter.js
+++ b/src/pixi/filters/GrayFilter.js
@@ -22,14 +22,14 @@ PIXI.GrayFilter = function()
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform sampler2D uSampler;',
'uniform float gray;',
'void main(void) {',
' gl_FragColor = texture2D(uSampler, vTextureCoord);',
' gl_FragColor.rgb = mix(gl_FragColor.rgb, vec3(0.2126*gl_FragColor.r + 0.7152*gl_FragColor.g + 0.0722*gl_FragColor.b), gray);',
- ' gl_FragColor = gl_FragColor * vColor;',
+ // ' gl_FragColor = gl_FragColor;',
'}'
];
};
diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js
index ac4393f9..37780483 100644
--- a/src/pixi/filters/InvertFilter.js
+++ b/src/pixi/filters/InvertFilter.js
@@ -22,7 +22,7 @@ PIXI.InvertFilter = function()
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform float invert;',
'uniform sampler2D uSampler;',
@@ -30,7 +30,7 @@ PIXI.InvertFilter = function()
' gl_FragColor = texture2D(uSampler, vTextureCoord);',
' gl_FragColor.rgb = mix( (vec3(1)-gl_FragColor.rgb) * gl_FragColor.a, gl_FragColor.rgb, 1.0 - invert);',
//' gl_FragColor.rgb = gl_FragColor.rgb * gl_FragColor.a;',
- ' gl_FragColor = gl_FragColor * vColor;',
+ // ' gl_FragColor = gl_FragColor * vColor;',
'}'
];
};
diff --git a/src/pixi/filters/NormalMapFilter.js b/src/pixi/filters/NormalMapFilter.js
new file mode 100644
index 00000000..ca24c244
--- /dev/null
+++ b/src/pixi/filters/NormalMapFilter.js
@@ -0,0 +1,225 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+/**
+ *
+ * The NormalMapFilter class uses the pixel values from the specified texture (called the displacement map) to perform a displacement of an object.
+ * You can use this filter to apply all manor of crazy warping effects
+ * Currently the r property of the texture is used offset the x and the g propery of the texture is used to offset the y.
+ * @class NormalMapFilter
+ * @contructor
+ * @param texture {Texture} The texture used for the displacemtent map * must be power of 2 texture at the moment
+ */
+PIXI.NormalMapFilter = function(texture)
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+ texture.baseTexture._powerOf2 = true;
+
+ // set the uniforms
+ //console.log()
+ this.uniforms = {
+ displacementMap: {type: 'sampler2D', value:texture},
+ scale: {type: '2f', value:{x:15, y:15}},
+ offset: {type: '2f', value:{x:0, y:0}},
+ mapDimensions: {type: '2f', value:{x:1, y:1}},
+ dimensions: {type: '4f', value:[0,0,0,0]},
+ // LightDir: {type: 'f3', value:[0, 1, 0]},
+ LightPos: {type: '3f', value:[0, 1, 0]}
+ };
+
+
+ if(texture.baseTexture.hasLoaded)
+ {
+ this.uniforms.mapDimensions.value.x = texture.width;
+ this.uniforms.mapDimensions.value.y = texture.height;
+ }
+ else
+ {
+ this.boundLoadedFunction = this.onTextureLoaded.bind(this);
+
+ texture.baseTexture.on("loaded", this.boundLoadedFunction);
+ }
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform sampler2D displacementMap;",
+ "uniform sampler2D uSampler;",
+
+ "uniform vec4 dimensions;",
+
+ "const vec2 Resolution = vec2(1.0,1.0);", //resolution of screen
+ "uniform vec3 LightPos;", //light position, normalized
+ "const vec4 LightColor = vec4(1.0, 1.0, 1.0, 1.0);", //light RGBA -- alpha is intensity
+ "const vec4 AmbientColor = vec4(1.0, 1.0, 1.0, 0.5);", //ambient RGBA -- alpha is intensity
+ "const vec3 Falloff = vec3(0.0, 1.0, 0.2);", //attenuation coefficients
+
+ "uniform vec3 LightDir;",//" = vec3(1.0, 0.0, 1.0);",
+
+
+ "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);",
+
+
+ "void main(void) {",
+ "vec2 mapCords = vTextureCoord.xy;",
+
+ "vec4 color = texture2D(uSampler, vTextureCoord.st);",
+ "vec3 nColor = texture2D(displacementMap, vTextureCoord.st).rgb;",
+
+
+ "mapCords *= vec2(dimensions.x/512.0, dimensions.y/512.0);",
+
+ "mapCords.y *= -1.0;",
+ "mapCords.y += 1.0;",
+
+ //RGBA of our diffuse color
+ "vec4 DiffuseColor = texture2D(uSampler, vTextureCoord);",
+
+ //RGB of our normal map
+ "vec3 NormalMap = texture2D(displacementMap, mapCords).rgb;",
+
+ //The delta position of light
+ //"vec3 LightDir = vec3(LightPos.xy - (gl_FragCoord.xy / Resolution.xy), LightPos.z);",
+ "vec3 LightDir = vec3(LightPos.xy - (mapCords.xy), LightPos.z);",
+ //Correct for aspect ratio
+ //"LightDir.x *= Resolution.x / Resolution.y;",
+
+ //Determine distance (used for attenuation) BEFORE we normalize our LightDir
+ "float D = length(LightDir);",
+
+ //normalize our vectors
+ "vec3 N = normalize(NormalMap * 2.0 - 1.0);",
+ "vec3 L = normalize(LightDir);",
+
+ //Pre-multiply light color with intensity
+ //Then perform "N dot L" to determine our diffuse term
+ "vec3 Diffuse = (LightColor.rgb * LightColor.a) * max(dot(N, L), 0.0);",
+
+ //pre-multiply ambient color with intensity
+ "vec3 Ambient = AmbientColor.rgb * AmbientColor.a;",
+
+ //calculate attenuation
+ "float Attenuation = 1.0 / ( Falloff.x + (Falloff.y*D) + (Falloff.z*D*D) );",
+
+ //the calculation which brings it all together
+ "vec3 Intensity = Ambient + Diffuse * Attenuation;",
+ "vec3 FinalColor = DiffuseColor.rgb * Intensity;",
+ "gl_FragColor = vColor * vec4(FinalColor, DiffuseColor.a);",
+ //"gl_FragColor = vec4(1.0, 0.0, 0.0, Attenuation);",//vColor * vec4(FinalColor, DiffuseColor.a);",
+ /*
+ // normalise color
+ "vec3 normal = normalize(nColor * 2.0 - 1.0);",
+
+ "vec3 deltaPos = vec3( (light.xy - gl_FragCoord.xy) / resolution.xy, light.z );",
+
+ "float lambert = clamp(dot(normal, lightDir), 0.0, 1.0);",
+
+ "float d = sqrt(dot(deltaPos, deltaPos));",
+ "float att = 1.0 / ( attenuation.x + (attenuation.y*d) + (attenuation.z*d*d) );",
+
+ "vec3 result = (ambientColor * ambientIntensity) + (lightColor.rgb * lambert) * att;",
+ "result *= color.rgb;",
+
+ "gl_FragColor = vec4(result, 1.0);",*/
+
+
+
+ "}"
+ ];
+
+}
+
+/*
+void main() {
+ //sample color & normals from our textures
+ vec4 color = texture2D(u_texture, v_texCoords.st);
+ vec3 nColor = texture2D(u_normals, v_texCoords.st).rgb;
+
+ //some bump map programs will need the Y value flipped..
+ nColor.g = yInvert ? 1.0 - nColor.g : nColor.g;
+
+ //this is for debugging purposes, allowing us to lower the intensity of our bump map
+ vec3 nBase = vec3(0.5, 0.5, 1.0);
+ nColor = mix(nBase, nColor, strength);
+
+ //normals need to be converted to [-1.0, 1.0] range and normalized
+ vec3 normal = normalize(nColor * 2.0 - 1.0);
+
+ //here we do a simple distance calculation
+ vec3 deltaPos = vec3( (light.xy - gl_FragCoord.xy) / resolution.xy, light.z );
+
+ vec3 lightDir = normalize(deltaPos);
+ float lambert = useNormals ? clamp(dot(normal, lightDir), 0.0, 1.0) : 1.0;
+
+ //now let's get a nice little falloff
+ float d = sqrt(dot(deltaPos, deltaPos));
+ float att = useShadow ? 1.0 / ( attenuation.x + (attenuation.y*d) + (attenuation.z*d*d) ) : 1.0;
+
+ vec3 result = (ambientColor * ambientIntensity) + (lightColor.rgb * lambert) * att;
+ result *= color.rgb;
+
+ gl_FragColor = v_color * vec4(result, color.a);
+}
+*/
+PIXI.NormalMapFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.NormalMapFilter.prototype.constructor = PIXI.NormalMapFilter;
+
+PIXI.NormalMapFilter.prototype.onTextureLoaded = function()
+{
+
+ this.uniforms.mapDimensions.value.x = this.uniforms.displacementMap.value.width;
+ this.uniforms.mapDimensions.value.y = this.uniforms.displacementMap.value.height;
+
+ this.uniforms.displacementMap.value.baseTexture.off("loaded", this.boundLoadedFunction)
+
+}
+
+/**
+ * The texture used for the displacemtent map * must be power of 2 texture at the moment
+ *
+ * @property map
+ * @type Texture
+ */
+Object.defineProperty(PIXI.NormalMapFilter.prototype, 'map', {
+ get: function() {
+ return this.uniforms.displacementMap.value;
+ },
+ set: function(value) {
+ this.uniforms.displacementMap.value = value;
+ }
+});
+
+/**
+ * The multiplier used to scale the displacement result from the map calculation.
+ *
+ * @property scale
+ * @type Point
+ */
+Object.defineProperty(PIXI.NormalMapFilter.prototype, 'scale', {
+ get: function() {
+ return this.uniforms.scale.value;
+ },
+ set: function(value) {
+ this.uniforms.scale.value = value;
+ }
+});
+
+/**
+ * The offset used to move the displacement map.
+ *
+ * @property offset
+ * @type Point
+ */
+Object.defineProperty(PIXI.NormalMapFilter.prototype, 'offset', {
+ get: function() {
+ return this.uniforms.offset.value;
+ },
+ set: function(value) {
+ this.uniforms.offset.value = value;
+ }
+});
\ No newline at end of file
diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js
index e4320ebf..89a146b8 100644
--- a/src/pixi/filters/PixelateFilter.js
+++ b/src/pixi/filters/PixelateFilter.js
@@ -4,7 +4,7 @@
/**
*
- * This filter applies a pixlate effect making display objects appear 'blocky'
+ * This filter applies a pixelate effect making display objects appear 'blocky'
* @class PixelateFilter
* @contructor
*/
@@ -24,7 +24,7 @@ PIXI.PixelateFilter = function()
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform vec2 testDim;',
'uniform vec4 dimensions;',
'uniform vec2 pixelSize;',
diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js
index 81439dd5..fba3bde9 100644
--- a/src/pixi/filters/RGBSplitFilter.js
+++ b/src/pixi/filters/RGBSplitFilter.js
@@ -19,7 +19,7 @@ PIXI.RGBSplitFilter = function()
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform vec2 red;',
'uniform vec2 green;',
'uniform vec2 blue;',
diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js
index f114d761..9aff3054 100644
--- a/src/pixi/filters/SepiaFilter.js
+++ b/src/pixi/filters/SepiaFilter.js
@@ -22,7 +22,7 @@ PIXI.SepiaFilter = function()
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform float sepia;',
'uniform sampler2D uSampler;',
@@ -31,7 +31,7 @@ PIXI.SepiaFilter = function()
'void main(void) {',
' gl_FragColor = texture2D(uSampler, vTextureCoord);',
' gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb * sepiaMatrix, sepia);',
- ' gl_FragColor = gl_FragColor * vColor;',
+ // ' gl_FragColor = gl_FragColor * vColor;',
'}'
];
};
diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js
index c529dd78..01c51690 100644
--- a/src/pixi/filters/TwistFilter.js
+++ b/src/pixi/filters/TwistFilter.js
@@ -4,8 +4,8 @@
/**
*
- * This filter applies a pixlate effect making display objects appear 'blocky'
- * @class PixelateFilter
+ * This filter applies a twist effect making display objects appear twisted in the given direction
+ * @class TwistFilter
* @contructor
*/
PIXI.TwistFilter = function()
@@ -24,7 +24,7 @@ PIXI.TwistFilter = function()
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform vec4 dimensions;',
'uniform sampler2D uSampler;',
diff --git a/src/pixi/loaders/AssetLoader.js b/src/pixi/loaders/AssetLoader.js
index c2e8ef18..0dda7502 100644
--- a/src/pixi/loaders/AssetLoader.js
+++ b/src/pixi/loaders/AssetLoader.js
@@ -70,7 +70,12 @@ PIXI.AssetLoader = function(assetURLs, crossorigin)
// constructor
PIXI.AssetLoader.prototype.constructor = PIXI.AssetLoader;
-
+/**
+ * Given a filename, returns its extension, wil
+ *
+ * @method _getDataType
+ * @param str {String} the name of the asset
+ */
PIXI.AssetLoader.prototype._getDataType = function(str)
{
var test = 'data:';
diff --git a/src/pixi/loaders/AtlasLoader.js b/src/pixi/loaders/AtlasLoader.js
index 68300ebd..98e32c99 100644
--- a/src/pixi/loaders/AtlasLoader.js
+++ b/src/pixi/loaders/AtlasLoader.js
@@ -3,9 +3,9 @@
*/
/**
- * The atlas file loader is used to load in Atlas data and parsing it
+ * The atlas file loader is used to load in Atlas data and parse it
* When loaded this class will dispatch a 'loaded' event
- * If load failed this class will dispatch a 'error' event
+ * If loading fails this class will dispatch an 'error' event
* @class AtlasLoader
* @extends EventTarget
* @constructor
@@ -25,8 +25,11 @@ PIXI.AtlasLoader = function (url, crossorigin) {
// constructor
PIXI.AtlasLoader.constructor = PIXI.AtlasLoader;
-/**
- * This will begin loading the JSON file
+
+ /**
+ * Starts loading the JSON file
+ *
+ * @method load
*/
PIXI.AtlasLoader.prototype.load = function () {
this.ajaxRequest = new PIXI.AjaxRequest();
@@ -39,6 +42,7 @@ PIXI.AtlasLoader.prototype.load = function () {
/**
* Invoke when JSON file is loaded
+ * @method onAtlasLoaded
* @private
*/
PIXI.AtlasLoader.prototype.onAtlasLoaded = function () {
@@ -156,7 +160,8 @@ PIXI.AtlasLoader.prototype.onAtlasLoaded = function () {
};
/**
- * Invoke when json file loaded
+ * Invoke when json file has loaded
+ * @method onLoaded
* @private
*/
PIXI.AtlasLoader.prototype.onLoaded = function () {
@@ -174,6 +179,7 @@ PIXI.AtlasLoader.prototype.onLoaded = function () {
/**
* Invoke when error occured
+ * @method onError
* @private
*/
PIXI.AtlasLoader.prototype.onError = function () {
diff --git a/src/pixi/loaders/BitmapFontLoader.js b/src/pixi/loaders/BitmapFontLoader.js
index 8421f90a..78488d2f 100644
--- a/src/pixi/loaders/BitmapFontLoader.js
+++ b/src/pixi/loaders/BitmapFontLoader.js
@@ -17,7 +17,7 @@
PIXI.BitmapFontLoader = function(url, crossorigin)
{
/*
- * i use texture packer to load the assets..
+ * I use texture packer to load the assets..
* http://www.codeandweb.com/texturepacker
* make sure to set the format as 'JSON'
*/
@@ -67,7 +67,7 @@ PIXI.BitmapFontLoader.prototype.constructor = PIXI.BitmapFontLoader;
*/
PIXI.BitmapFontLoader.prototype.load = function()
{
- this.ajaxRequest = new XMLHttpRequest();
+ this.ajaxRequest = new PIXI.AjaxRequest();
var scope = this;
this.ajaxRequest.onreadystatechange = function()
{
@@ -80,7 +80,7 @@ PIXI.BitmapFontLoader.prototype.load = function()
};
/**
- * Invoked when XML file is loaded, parses the data
+ * Invoked when the XML file is loaded, parses the data
*
* @method onXMLLoaded
* @private
@@ -91,36 +91,48 @@ PIXI.BitmapFontLoader.prototype.onXMLLoaded = function()
{
if (this.ajaxRequest.status === 200 || window.location.protocol.indexOf('http') === -1)
{
- var textureUrl = this.baseUrl + this.ajaxRequest.responseXML.getElementsByTagName('page')[0].attributes.getNamedItem('file').nodeValue;
+ var responseXML = this.ajaxRequest.responseXML;
+ if(!responseXML || /MSIE 9/i.test(navigator.userAgent) || navigator.isCocoonJS) {
+ if(typeof(window.DOMParser) === 'function') {
+ var domparser = new DOMParser();
+ responseXML = domparser.parseFromString(this.ajaxRequest.responseText, 'text/xml');
+ } else {
+ var div = document.createElement('div');
+ div.innerHTML = this.ajaxRequest.responseText;
+ responseXML = div;
+ }
+ }
+
+ var textureUrl = this.baseUrl + responseXML.getElementsByTagName('page')[0].getAttribute('file');
var image = new PIXI.ImageLoader(textureUrl, this.crossorigin);
this.texture = image.texture.baseTexture;
var data = {};
- var info = this.ajaxRequest.responseXML.getElementsByTagName('info')[0];
- var common = this.ajaxRequest.responseXML.getElementsByTagName('common')[0];
- data.font = info.attributes.getNamedItem('face').nodeValue;
- data.size = parseInt(info.attributes.getNamedItem('size').nodeValue, 10);
- data.lineHeight = parseInt(common.attributes.getNamedItem('lineHeight').nodeValue, 10);
+ var info = responseXML.getElementsByTagName('info')[0];
+ var common = responseXML.getElementsByTagName('common')[0];
+ data.font = info.getAttribute('face');
+ data.size = parseInt(info.getAttribute('size'), 10);
+ data.lineHeight = parseInt(common.getAttribute('lineHeight'), 10);
data.chars = {};
//parse letters
- var letters = this.ajaxRequest.responseXML.getElementsByTagName('char');
+ var letters = responseXML.getElementsByTagName('char');
for (var i = 0; i < letters.length; i++)
{
- var charCode = parseInt(letters[i].attributes.getNamedItem('id').nodeValue, 10);
+ var charCode = parseInt(letters[i].getAttribute('id'), 10);
var textureRect = new PIXI.Rectangle(
- parseInt(letters[i].attributes.getNamedItem('x').nodeValue, 10),
- parseInt(letters[i].attributes.getNamedItem('y').nodeValue, 10),
- parseInt(letters[i].attributes.getNamedItem('width').nodeValue, 10),
- parseInt(letters[i].attributes.getNamedItem('height').nodeValue, 10)
+ parseInt(letters[i].getAttribute('x'), 10),
+ parseInt(letters[i].getAttribute('y'), 10),
+ parseInt(letters[i].getAttribute('width'), 10),
+ parseInt(letters[i].getAttribute('height'), 10)
);
data.chars[charCode] = {
- xOffset: parseInt(letters[i].attributes.getNamedItem('xoffset').nodeValue, 10),
- yOffset: parseInt(letters[i].attributes.getNamedItem('yoffset').nodeValue, 10),
- xAdvance: parseInt(letters[i].attributes.getNamedItem('xadvance').nodeValue, 10),
+ xOffset: parseInt(letters[i].getAttribute('xoffset'), 10),
+ yOffset: parseInt(letters[i].getAttribute('yoffset'), 10),
+ xAdvance: parseInt(letters[i].getAttribute('xadvance'), 10),
kerning: {},
texture: PIXI.TextureCache[charCode] = new PIXI.Texture(this.texture, textureRect)
@@ -128,12 +140,12 @@ PIXI.BitmapFontLoader.prototype.onXMLLoaded = function()
}
//parse kernings
- var kernings = this.ajaxRequest.responseXML.getElementsByTagName('kerning');
+ var kernings = responseXML.getElementsByTagName('kerning');
for (i = 0; i < kernings.length; i++)
{
- var first = parseInt(kernings[i].attributes.getNamedItem('first').nodeValue, 10);
- var second = parseInt(kernings[i].attributes.getNamedItem('second').nodeValue, 10);
- var amount = parseInt(kernings[i].attributes.getNamedItem('amount').nodeValue, 10);
+ var first = parseInt(kernings[i].getAttribute('first'), 10);
+ var second = parseInt(kernings[i].getAttribute('second'), 10);
+ var amount = parseInt(kernings[i].getAttribute('amount'), 10);
data.chars[second].kerning[first] = amount;
diff --git a/src/pixi/loaders/ImageLoader.js b/src/pixi/loaders/ImageLoader.js
index c73893f6..9e998b0a 100644
--- a/src/pixi/loaders/ImageLoader.js
+++ b/src/pixi/loaders/ImageLoader.js
@@ -4,7 +4,7 @@
/**
* The image loader class is responsible for loading images file formats ('jpeg', 'jpg', 'png' and 'gif')
- * Once the image has been loaded it is stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFromeId()
+ * Once the image has been loaded it is stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFrameId()
* When loaded this class will dispatch a 'loaded' event
*
* @class ImageLoader
@@ -73,7 +73,7 @@ PIXI.ImageLoader.prototype.onLoaded = function()
*
*
* @method loadFramedSpriteSheet
- * @param frameWidth {Number} with of each frame
+ * @param frameWidth {Number} width of each frame
* @param frameHeight {Number} height of each frame
* @param textureName {String} if given, the frames will be cached in - format
*/
diff --git a/src/pixi/loaders/JsonLoader.js b/src/pixi/loaders/JsonLoader.js
index 127d8cf0..f7d96c3c 100644
--- a/src/pixi/loaders/JsonLoader.js
+++ b/src/pixi/loaders/JsonLoader.js
@@ -3,9 +3,9 @@
*/
/**
- * The json file loader is used to load in JSON data and parsing it
+ * The json file loader is used to load in JSON data and parse it
* When loaded this class will dispatch a 'loaded' event
- * If load failed this class will dispatch a 'error' event
+ * If loading fails this class will dispatch an 'error' event
*
* @class JsonLoader
* @uses EventTarget
@@ -61,7 +61,7 @@ PIXI.JsonLoader.prototype.constructor = PIXI.JsonLoader;
* @method load
*/
PIXI.JsonLoader.prototype.load = function () {
- this.ajaxRequest = new PIXI.AjaxRequest();
+ this.ajaxRequest = new PIXI.AjaxRequest(this.crossorigin);
var scope = this;
this.ajaxRequest.onreadystatechange = function () {
scope.onJSONLoaded();
@@ -105,11 +105,21 @@ PIXI.JsonLoader.prototype.onJSONLoaded = function () {
width: rect.w,
height: rect.h
});
+
+ // check to see ifthe sprite ha been trimmed..
if (frameData[i].trimmed) {
- //var realSize = frameData[i].spriteSourceSize;
- PIXI.TextureCache[i].realSize = frameData[i].spriteSourceSize;
- PIXI.TextureCache[i].trim.x = 0; // (realSize.x / rect.w)
- // calculate the offset!
+
+ var texture = PIXI.TextureCache[i];
+
+ texture.trimmed = true;
+
+ var actualSize = frameData[i].sourceSize;
+ var realSize = frameData[i].spriteSourceSize;
+
+ texture.trim.x = realSize.x;
+ texture.trim.y = realSize.y;
+ texture.trim.realWidth = actualSize.w;
+ texture.trim.realHeight = actualSize.h;
}
}
}
diff --git a/src/pixi/loaders/SpineLoader.js b/src/pixi/loaders/SpineLoader.js
index f0a38ca0..23072f10 100644
--- a/src/pixi/loaders/SpineLoader.js
+++ b/src/pixi/loaders/SpineLoader.js
@@ -9,7 +9,7 @@
/**
* The Spine loader is used to load in JSON spine data
- * To generate the data you need to use http://esotericsoftware.com/ and export the "JSON" format
+ * To generate the data you need to use http://esotericsoftware.com/ and export in the "JSON" format
* Due to a clash of names You will need to change the extension of the spine file from *.json to *.anim for it to load
* See example 12 (http://www.goodboydigital.com/pixijs/examples/12/) to see a working example and check out the source
* You will need to generate a sprite sheet to accompany the spine data
@@ -64,26 +64,11 @@ PIXI.SpineLoader.prototype.load = function () {
var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin);
jsonLoader.addEventListener("loaded", function (event) {
scope.json = event.content.json;
- scope.onJSONLoaded();
+ scope.onLoaded();
});
jsonLoader.load();
};
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @private
- */
-PIXI.SpineLoader.prototype.onJSONLoaded = function () {
- var spineJsonParser = new spine.SkeletonJson();
- var skeletonData = spineJsonParser.readSkeletonData(this.json);
-
- PIXI.AnimCache[this.url] = skeletonData;
-
- this.onLoaded();
-};
-
/**
* Invoke when JSON file is loaded
*
diff --git a/src/pixi/loaders/SpriteSheetLoader.js b/src/pixi/loaders/SpriteSheetLoader.js
index e9844cec..bfb827a7 100644
--- a/src/pixi/loaders/SpriteSheetLoader.js
+++ b/src/pixi/loaders/SpriteSheetLoader.js
@@ -4,11 +4,11 @@
/**
* The sprite sheet loader is used to load in JSON sprite sheet data
- * To generate the data you can use http://www.codeandweb.com/texturepacker and publish the 'JSON' format
+ * To generate the data you can use http://www.codeandweb.com/texturepacker and publish in the 'JSON' format
* There is a free version so thats nice, although the paid version is great value for money.
- * It is highly recommended to use Sprite sheets (also know as texture atlas') as it means sprite's can be batched and drawn together for highly increased rendering speed.
- * Once the data has been loaded the frames are stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFromeId()
- * This loader will also load the image file that the Spritesheet points to as well as the data.
+ * It is highly recommended to use Sprite sheets (also know as a 'texture atlas') as it means sprites can be batched and drawn together for highly increased rendering speed.
+ * Once the data has been loaded the frames are stored in the PIXI texture cache and can be accessed though PIXI.Texture.fromFrameId() and PIXI.Sprite.fromFrameId()
+ * This loader will load the image file that the Spritesheet points to as well as the data.
* When loaded this class will dispatch a 'loaded' event
*
* @class SpriteSheetLoader
@@ -80,47 +80,9 @@ PIXI.SpriteSheetLoader.prototype.load = function () {
var jsonLoader = new PIXI.JsonLoader(this.url, this.crossorigin);
jsonLoader.addEventListener('loaded', function (event) {
scope.json = event.content.json;
- scope.onJSONLoaded();
- });
- jsonLoader.load();
-};
-
-/**
- * Invoke when JSON file is loaded
- *
- * @method onJSONLoaded
- * @private
- */
-PIXI.SpriteSheetLoader.prototype.onJSONLoaded = function () {
- var scope = this;
- var textureUrl = this.baseUrl + this.json.meta.image;
- var image = new PIXI.ImageLoader(textureUrl, this.crossorigin);
- var frameData = this.json.frames;
-
- this.texture = image.texture.baseTexture;
- image.addEventListener('loaded', function () {
scope.onLoaded();
});
-
- for (var i in frameData) {
- var rect = frameData[i].frame;
- if (rect) {
- PIXI.TextureCache[i] = new PIXI.Texture(this.texture, {
- x: rect.x,
- y: rect.y,
- width: rect.w,
- height: rect.h
- });
- if (frameData[i].trimmed) {
- //var realSize = frameData[i].spriteSourceSize;
- PIXI.TextureCache[i].realSize = frameData[i].spriteSourceSize;
- PIXI.TextureCache[i].trim.x = 0; // (realSize.x / rect.w)
- // calculate the offset!
- }
- }
- }
-
- image.load();
+ jsonLoader.load();
};
/**
diff --git a/src/pixi/primitives/Graphics.js b/src/pixi/primitives/Graphics.js
index 92dee1e2..7b84678c 100644
--- a/src/pixi/primitives/Graphics.js
+++ b/src/pixi/primitives/Graphics.js
@@ -5,8 +5,8 @@
/**
* The Graphics class contains a set of methods that you can use to create primitive shapes and lines.
- * It is important to know that with the webGL renderer only simple polys can be filled at this stage
- * Complex polys will not be filled. Heres an example of a complex poly: http://www.goodboydigital.com/wp-content/uploads/2013/06/complexPolygon.png
+ * It is important to know that with the webGL renderer only simple polygons can be filled at this stage
+ * Complex polygons will not be filled. Heres an example of a complex polygon: http://www.goodboydigital.com/wp-content/uploads/2013/06/complexPolygon.png
*
* @class Graphics
* @extends DisplayObjectContainer
@@ -51,6 +51,25 @@ PIXI.Graphics = function()
*/
this.graphicsData = [];
+
+ /**
+ * The tint applied to the graphic shape. This is a hex value
+ *
+ * @property tint
+ * @type Number
+ * @default 0xFFFFFF
+ */
+ this.tint = 0xFFFFFF;// * Math.random();
+
+ /**
+ * The blend mode to be applied to the graphic shape
+ *
+ * @property blendMode
+ * @type Number
+ * @default PIXI.blendModes.NORMAL;
+ */
+ this.blendMode = PIXI.blendModes.NORMAL;
+
/**
* Current path
*
@@ -59,6 +78,39 @@ PIXI.Graphics = function()
* @private
*/
this.currentPath = {points:[]};
+
+ /**
+ * WebGL lines ? TODO-Alvin
+ *
+ * @property _webGL
+ * @type Array
+ * @private
+ */
+ this._webGL = [];
+
+ /**
+ * Whether this shape is used as a mask
+ *
+ * @property isMask
+ * @type isMask
+ */
+ this.isMask = false;
+
+ /**
+ * The bounds of the graphic shape as rectangle object
+ *
+ * @property bounds
+ * @type Rectangle
+ */
+ this.bounds = null;
+
+ /**
+ * the bound padding TODO-Alvin
+ *
+ * @property bounds
+ * @type Number
+ */
+ this.boundsPadding = 10;
};
// constructor
@@ -66,7 +118,39 @@ PIXI.Graphics.prototype = Object.create( PIXI.DisplayObjectContainer.prototype )
PIXI.Graphics.prototype.constructor = PIXI.Graphics;
/**
- * Specifies a line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method.
+ * If cacheAsBitmap is true the graphics object will then be rendered as if it was a sprite.
+ * This is useful if your graphics element does not change often as it will speed up the rendering of the object
+ * It is also usful as the graphics object will always be antialiased because it will be rendered using canvas
+ * Not recommended if you are constanly redrawing the graphics element.
+ *
+ * @property cacheAsBitmap
+ * @default false
+ * @type Boolean
+ * @private
+ */
+Object.defineProperty(PIXI.Graphics.prototype, "cacheAsBitmap", {
+ get: function() {
+ return this._cacheAsBitmap;
+ },
+ set: function(value) {
+ this._cacheAsBitmap = value;
+
+ if(this._cacheAsBitmap)
+ {
+ this._generateCachedSprite();
+ }
+ else
+ {
+ this.destroyCachedSprite();
+ this.dirty = true;
+ }
+
+ }
+});
+
+
+/**
+ * Specifies the line style used for subsequent calls to Graphics methods such as the lineTo() method or the drawCircle() method.
*
* @method lineStyle
* @param lineWidth {Number} width of the line to draw, will update the object's stored style
@@ -91,8 +175,8 @@ PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha)
* Moves the current drawing position to (x, y).
*
* @method moveTo
- * @param x {Number} the X coord to move to
- * @param y {Number} the Y coord to move to
+ * @param x {Number} the X coordinate to move to
+ * @param y {Number} the Y coordinate to move to
*/
PIXI.Graphics.prototype.moveTo = function(x, y)
{
@@ -111,8 +195,8 @@ PIXI.Graphics.prototype.moveTo = function(x, y)
* the current drawing position is then set to (x, y).
*
* @method lineTo
- * @param x {Number} the X coord to draw to
- * @param y {Number} the Y coord to draw to
+ * @param x {Number} the X coordinate to draw to
+ * @param y {Number} the Y coordinate to draw to
*/
PIXI.Graphics.prototype.lineTo = function(x, y)
{
@@ -125,11 +209,12 @@ PIXI.Graphics.prototype.lineTo = function(x, y)
* (such as lineTo() or drawCircle()) use when drawing.
*
* @method beginFill
- * @param color {uint} the color of the fill
- * @param alpha {Number} the alpha
+ * @param color {Number} the color of the fill
+ * @param alpha {Number} the alpha of the fill
*/
PIXI.Graphics.prototype.beginFill = function(color, alpha)
{
+
this.filling = true;
this.fillColor = color || 0;
this.fillAlpha = (arguments.length < 2) ? 1 : alpha;
@@ -171,12 +256,13 @@ PIXI.Graphics.prototype.drawRect = function( x, y, width, height )
* Draws a circle.
*
* @method drawCircle
- * @param x {Number} The X coord of the center of the circle
- * @param y {Number} The Y coord of the center of the circle
+ * @param x {Number} The X coordinate of the center of the circle
+ * @param y {Number} The Y coordinate of the center of the circle
* @param radius {Number} The radius of the circle
*/
PIXI.Graphics.prototype.drawCircle = function( x, y, radius)
{
+
if (!this.currentPath.points.length) this.graphicsData.pop();
this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
@@ -191,13 +277,14 @@ PIXI.Graphics.prototype.drawCircle = function( x, y, radius)
* Draws an ellipse.
*
* @method drawEllipse
- * @param x {Number}
- * @param y {Number}
- * @param width {Number}
- * @param height {Number}
+ * @param x {Number} The X coordinate of the upper-left corner of the framing rectangle of this ellipse
+ * @param y {Number} The Y coordinate of the upper-left corner of the framing rectangle of this ellipse
+ * @param width {Number} The width of the ellipse
+ * @param height {Number} The height of the ellipse
*/
PIXI.Graphics.prototype.drawEllipse = function( x, y, width, height)
{
+
if (!this.currentPath.points.length) this.graphicsData.pop();
this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
@@ -225,74 +312,317 @@ PIXI.Graphics.prototype.clear = function()
this.bounds = null; //new PIXI.Rectangle();
};
-
-PIXI.Graphics.prototype.updateFilterBounds = function()
+/**
+ * Useful function that returns a texture of the graphics object that can then be used to create sprites
+ * This can be quite useful if your geometry is complicated and needs to be reused multiple times.
+ *
+ * @method generateTexture
+ * @return {Texture} a texture of the graphics object
+ */
+PIXI.Graphics.prototype.generateTexture = function()
{
- if(!this.bounds)
+ var bounds = this.getBounds();
+
+ var canvasBuffer = new PIXI.CanvasBuffer(bounds.width, bounds.height);
+ var texture = PIXI.Texture.fromCanvas(canvasBuffer.canvas);
+
+ canvasBuffer.context.translate(-bounds.x,-bounds.y);
+
+ PIXI.CanvasGraphics.renderGraphics(this, canvasBuffer.context);
+
+ return texture;
+};
+
+/**
+* Renders the object using the WebGL renderer
+*
+* @method _renderWebGL
+* @param renderSession {RenderSession}
+* @private
+*/
+PIXI.Graphics.prototype._renderWebGL = function(renderSession)
+{
+ // if the sprite is not visible or the alpha is 0 then no need to render this element
+ if(this.visible === false || this.alpha === 0 || this.isMask === true)return;
+
+ if(this._cacheAsBitmap)
{
- var minX = Infinity;
- var maxX = -Infinity;
-
- var minY = Infinity;
- var maxY = -Infinity;
-
- var points, x, y;
-
- for (var i = 0; i < this.graphicsData.length; i++) {
- var data = this.graphicsData[i];
- var type = data.type;
- var lineWidth = data.lineWidth;
-
- 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;
-
- 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;
-
- 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];
-
- 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;
- }
- }
+
+ if(this.dirty)
+ {
+ this._generateCachedSprite();
+ // we will also need to update the texture on the gpu too!
+ PIXI.updateWebGLTexture(this._cachedSprite.texture.baseTexture, renderSession.gl);
+
+ this.dirty = false;
}
- this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY);
+ PIXI.Sprite.prototype._renderWebGL.call(this._cachedSprite, renderSession);
+
+ return;
+ }
+ else
+ {
+ renderSession.spriteBatch.stop();
+
+ if(this._mask)renderSession.maskManager.pushMask(this.mask, renderSession);
+ if(this._filters)renderSession.filterManager.pushFilter(this._filterBlock);
+
+ // check blend mode
+ if(this.blendMode !== renderSession.spriteBatch.currentBlendMode)
+ {
+ renderSession.spriteBatch.currentBlendMode = this.blendMode;
+ var blendModeWebGL = PIXI.blendModesWebGL[renderSession.spriteBatch.currentBlendMode];
+ renderSession.spriteBatch.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
+ }
+
+ PIXI.WebGLGraphics.renderGraphics(this, renderSession);
+
+ // only render if it has children!
+ if(this.children.length)
+ {
+ renderSession.spriteBatch.start();
+
+ // simple render children!
+ for(var i=0, j=this.children.length; i 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;
+
+ var bounds = this._bounds;
+
+ bounds.x = minX;
+ bounds.width = maxX - minX;
+
+ bounds.y = minY;
+ bounds.height = maxY - minY;
+
+ return bounds;
+};
+
+/**
+ * Update the bounds of the object
+ *
+ * @method updateBounds
+ */
+PIXI.Graphics.prototype.updateBounds = function()
+{
+
+ var minX = Infinity;
+ var maxX = -Infinity;
+
+ var minY = Infinity;
+ var maxY = -Infinity;
+
+ var points, x, y, w, h;
+
+ for (var i = 0; i < this.graphicsData.length; i++) {
+ var data = this.graphicsData[i];
+ var type = data.type;
+ var lineWidth = data.lineWidth;
+
+ points = data.points;
+
+ if(type === PIXI.Graphics.RECT)
+ {
+ x = points[0] - lineWidth/2;
+ y = points[1] - lineWidth/2;
+ w = points[2] + lineWidth;
+ h = points[3] + lineWidth;
+
+ minX = x < minX ? x : minX;
+ maxX = x + w > maxX ? x + w : maxX;
+
+ minY = y < minY ? x : minY;
+ maxY = y + h > maxY ? y + h : maxY;
+ }
+ else if(type === PIXI.Graphics.CIRC || type === PIXI.Graphics.ELIP)
+ {
+ x = points[0];
+ y = points[1];
+ w = points[2] + lineWidth/2;
+ h = points[3] + lineWidth/2;
+
+ minX = x - w < minX ? x - w : minX;
+ maxX = x + w > maxX ? x + w : maxX;
+
+ minY = y - h < minY ? y - h : minY;
+ maxY = y + h > maxY ? y + h : maxY;
+ }
+ else
+ {
+ // POLY
+ for (var j = 0; j < points.length; j+=2)
+ {
+
+ x = points[j];
+ y = points[j+1];
+ 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;
+ }
+ }
+ }
+
+ var padding = this.boundsPadding;
+ this.bounds = new PIXI.Rectangle(minX - padding, minY - padding, (maxX - minX) + padding * 2, (maxY - minY) + padding * 2);
+};
+
+
+/**
+ * Generates the cached sprite that was made using the generate TODO-Alvin
+ *
+ * @method _generateCachedSprite
+ * @private
+ */
+PIXI.Graphics.prototype._generateCachedSprite = function()
+{
+ var bounds = this.getBounds();
+
+ if(!this._cachedSprite)
+ {
+ var canvasBuffer = new PIXI.CanvasBuffer(bounds.width, bounds.height);
+ var texture = PIXI.Texture.fromCanvas(canvasBuffer.canvas);
+
+ this._cachedSprite = new PIXI.Sprite(texture);
+ this._cachedSprite.buffer = canvasBuffer;
+
+ this._cachedSprite.worldTransform = this.worldTransform;
+ }
+ else
+ {
+ this._cachedSprite.buffer.resize(bounds.width, bounds.height);
+ }
+
+ // leverage the anchor to account for the offset of the element
+ this._cachedSprite.anchor.x = -( bounds.x / bounds.width );
+ this._cachedSprite.anchor.y = -( bounds.y / bounds.height );
+
+ // this._cachedSprite.buffer.context.save();
+ this._cachedSprite.buffer.context.translate(-bounds.x,-bounds.y);
+
+ PIXI.CanvasGraphics.renderGraphics(this, this._cachedSprite.buffer.context);
+ // this._cachedSprite.buffer.context.restore();
+};
+
+PIXI.Graphics.prototype.destroyCachedSprite = function()
+{
+ this._cachedSprite.texture.destroy(true);
+
+ // let the gc collect the unused sprite
+ // TODO could be object pooled!
+ this._cachedSprite = null;
+};
+
+
// SOME TYPES:
PIXI.Graphics.POLY = 0;
PIXI.Graphics.RECT = 1;
diff --git a/src/pixi/renderers/canvas/CanvasGraphics.js b/src/pixi/renderers/canvas/CanvasGraphics.js
index a34c4002..cdb4b870 100644
--- a/src/pixi/renderers/canvas/CanvasGraphics.js
+++ b/src/pixi/renderers/canvas/CanvasGraphics.js
@@ -20,8 +20,8 @@ PIXI.CanvasGraphics = function()
* @static
* @private
* @method renderGraphics
- * @param graphics {Graphics}
- * @param context {Context2D}
+ * @param graphics {Graphics} the actual graphics object to render
+ * @param context {Context2D} the 2d drawing method of the canvas
*/
PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
{
@@ -154,8 +154,8 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
* @static
* @private
* @method renderGraphicsMask
- * @param graphics {Graphics}
- * @param context {Context2D}
+ * @param graphics {Graphics} the graphics which will be used as a mask
+ * @param context {Context2D} the context 2d method of the canvas
*/
PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
{
diff --git a/src/pixi/renderers/canvas/CanvasRenderer.js b/src/pixi/renderers/canvas/CanvasRenderer.js
index 8062a6eb..267ad360 100644
--- a/src/pixi/renderers/canvas/CanvasRenderer.js
+++ b/src/pixi/renderers/canvas/CanvasRenderer.js
@@ -8,14 +8,72 @@
*
* @class CanvasRenderer
* @constructor
- * @param width=0 {Number} the width of the canvas view
- * @param height=0 {Number} the height of the canvas view
- * @param view {Canvas} the canvas to use as a view, optional
- * @param transparent=false {Boolean} the transparency of the render view, default false
+ * @param width=800 {Number} the width of the canvas view
+ * @param height=600 {Number} the height of the canvas view
+ * @param [view] {HTMLCanvasElement} the canvas to use as a view, optional
+ * @param [transparent=false] {Boolean} the transparency of the render view, default false
*/
PIXI.CanvasRenderer = function(width, height, view, transparent)
{
- this.transparent = transparent;
+ PIXI.defaultRenderer = PIXI.defaultRenderer || this;
+
+ this.type = PIXI.CANVAS_RENDERER;
+
+
+ /**
+ * Whether the render view is transparent
+ *
+ * @property transparent
+ * @type Boolean
+ */
+ this.transparent = !!transparent;
+
+ if(!PIXI.blendModesCanvas)
+ {
+ PIXI.blendModesCanvas = [];
+
+ if(PIXI.canUseNewCanvasBlendModes())
+ {
+ PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK???
+ PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "multiply";
+ PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "screen";
+ PIXI.blendModesCanvas[PIXI.blendModes.OVERLAY] = "overlay";
+ PIXI.blendModesCanvas[PIXI.blendModes.DARKEN] = "darken";
+ PIXI.blendModesCanvas[PIXI.blendModes.LIGHTEN] = "lighten";
+ PIXI.blendModesCanvas[PIXI.blendModes.COLOR_DODGE] = "color-dodge";
+ PIXI.blendModesCanvas[PIXI.blendModes.COLOR_BURN] = "color-burn";
+ PIXI.blendModesCanvas[PIXI.blendModes.HARD_LIGHT] = "hard-light";
+ PIXI.blendModesCanvas[PIXI.blendModes.SOFT_LIGHT] = "soft-light";
+ PIXI.blendModesCanvas[PIXI.blendModes.DIFFERENCE] = "difference";
+ PIXI.blendModesCanvas[PIXI.blendModes.EXCLUSION] = "exclusion";
+ PIXI.blendModesCanvas[PIXI.blendModes.HUE] = "hue";
+ PIXI.blendModesCanvas[PIXI.blendModes.SATURATION] = "saturation";
+ PIXI.blendModesCanvas[PIXI.blendModes.COLOR] = "color";
+ PIXI.blendModesCanvas[PIXI.blendModes.LUMINOSITY] = "luminosity";
+ }
+ else
+ {
+ // this means that the browser does not support the cool new blend modes in canvas "cough" ie "cough"
+ PIXI.blendModesCanvas[PIXI.blendModes.NORMAL] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.ADD] = "lighter"; //IS THIS OK???
+ PIXI.blendModesCanvas[PIXI.blendModes.MULTIPLY] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.SCREEN] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.OVERLAY] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.DARKEN] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.LIGHTEN] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.COLOR_DODGE] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.COLOR_BURN] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.HARD_LIGHT] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.SOFT_LIGHT] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.DIFFERENCE] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.EXCLUSION] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.HUE] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.SATURATION] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.COLOR] = "source-over";
+ PIXI.blendModesCanvas[PIXI.blendModes.LUMINOSITY] = "source-over";
+ }
+ }
/**
* The width of the canvas view
@@ -36,33 +94,19 @@ PIXI.CanvasRenderer = function(width, height, view, transparent)
this.height = height || 600;
/**
- * The canvas element that the everything is drawn to
+ * The canvas element that everything is drawn to
*
* @property view
- * @type Canvas
+ * @type HTMLCanvasElement
*/
- this.view = view || document.createElement( 'canvas' );
+ this.view = view || document.createElement( "canvas" );
/**
- * The canvas context that the everything is drawn to
+ * The canvas 2d context that everything is drawn with
* @property context
- * @type Canvas 2d Context
+ * @type HTMLCanvasElement 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.context = this.view.getContext( "2d", { alpha: this.transparent } );
this.refresh = true;
// hack to enable some hardware acceleration!
@@ -71,6 +115,34 @@ PIXI.CanvasRenderer = function(width, height, view, transparent)
this.view.width = this.width;
this.view.height = this.height;
this.count = 0;
+
+ /**
+ * Instance of a PIXI.CanvasMaskManager, handles masking when using the canvas renderer
+ * @property CanvasMaskManager
+ * @type CanvasMaskManager
+ */
+ this.maskManager = new PIXI.CanvasMaskManager();
+
+ /**
+ * RenderSession TODO-Alvin
+ * @property renderSession
+ * @type Object
+ */
+ this.renderSession = {
+ context: this.context,
+ maskManager: this.maskManager,
+ scaleMode: null,
+ smoothProperty: null
+ };
+
+ if("imageSmoothingEnabled" in this.context)
+ this.renderSession.smoothProperty = "imageSmoothingEnabled";
+ else if("webkitImageSmoothingEnabled" in this.context)
+ this.renderSession.smoothProperty = "webkitImageSmoothingEnabled";
+ else if("mozImageSmoothingEnabled" in this.context)
+ this.renderSession.smoothProperty = "mozImageSmoothingEnabled";
+ else if("oImageSmoothingEnabled" in this.context)
+ this.renderSession.smoothProperty = "oImageSmoothingEnabled";
};
// constructor
@@ -88,20 +160,34 @@ PIXI.CanvasRenderer.prototype.render = function(stage)
//stage.__childrenRemoved = [];
// update textures if need be
- PIXI.texturesToUpdate = [];
- PIXI.texturesToDestroy = [];
+ PIXI.texturesToUpdate.length = 0;
+ PIXI.texturesToDestroy.length = 0;
- PIXI.visibleCount++;
stage.updateTransform();
// update the background color
- if(this.view.style.backgroundColor !== stage.backgroundColorString && !this.transparent)
- this.view.style.backgroundColor = stage.backgroundColorString;
+ /* 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);
+
+ if(this.view.style.backgroundColor !== stage.backgroundColorString )
+ {
+ if(!this.transparent)
+ {
+ this.context.globalAlpha = 1;
+ this.context.fillStyle = stage.backgroundColorString;
+ this.context.fillRect(0, 0, this.width, this.height);
+ }
+ else
+ {
+ this.context.clearRect(0, 0, this.width, this.height);
+ }
+ }
+
+ //console.log(this.view.style.backgroundColor)
+
this.renderDisplayObject(stage);
- //as
// run interaction!
if(stage.interactive)
@@ -117,12 +203,12 @@ PIXI.CanvasRenderer.prototype.render = function(stage)
// remove frame updates..
if(PIXI.Texture.frameUpdates.length > 0)
{
- PIXI.Texture.frameUpdates = [];
+ PIXI.Texture.frameUpdates.length = 0;
}
};
/**
- * resizes the canvas view to the specified width and height
+ * Resizes the canvas view to the specified width and height
*
* @method resize
* @param width {Number} the new width of the canvas view
@@ -142,119 +228,17 @@ PIXI.CanvasRenderer.prototype.resize = function(width, height)
*
* @method renderDisplayObject
* @param displayObject {DisplayObject} The displayObject to render
+ * @param context {Context2D} the context 2d method of the canvas
* @private
*/
-PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject)
+PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject, context)
{
- // no loger recurrsive!
- var transform;
- var context = this.context;
+ // no longer recursive!
+ //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;
-
- //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);
+ this.renderSession.context = context || this.context;
+ displayObject._renderCanvas(this.renderSession);
};
/**
@@ -286,45 +270,11 @@ PIXI.CanvasRenderer.prototype.renderStripFlat = function(strip)
context.lineTo(x2, y2);
}
- context.fillStyle = '#FF0000';
+ context.fillStyle = "#FF0000";
context.fill();
context.closePath();
};
-/**
- * Renders a tiling sprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tilingsprite to render
- * @private
- */
-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;
-
- // 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.translate(-tilePosition.x, -tilePosition.y);
-
- context.closePath();
-};
-
/**
* Renders a strip
*
@@ -380,3 +330,51 @@ PIXI.CanvasRenderer.prototype.renderStrip = function(strip)
context.restore();
}
};
+
+/**
+ * Creates a Canvas element of the given size
+ *
+ * @method CanvasBuffer
+ * @param width {Number} the width for the newly created canvas
+ * @param height {Number} the height for the newly created canvas
+ * @static
+ * @private
+ */
+PIXI.CanvasBuffer = function(width, height)
+{
+ this.width = width;
+ this.height = height;
+
+ this.canvas = document.createElement( "canvas" );
+ this.context = this.canvas.getContext( "2d" );
+
+ this.canvas.width = width;
+ this.canvas.height = height;
+};
+
+/**
+ * Clears the canvas that was created by the CanvasBuffer class
+ *
+ * @method clear
+ * @private
+ */
+PIXI.CanvasBuffer.prototype.clear = function()
+{
+ this.context.clearRect(0,0, this.width, this.height);
+};
+
+/**
+ * Resizes the canvas that was created by the CanvasBuffer class to the specified width and height
+ *
+ * @method resize
+ * @param width {Number} the new width of the canvas
+ * @param height {Number} the new height of the canvas
+ * @private
+ */
+
+PIXI.CanvasBuffer.prototype.resize = function(width, height)
+{
+ this.width = this.canvas.width = width;
+ this.height = this.canvas.height = height;
+};
+
diff --git a/src/pixi/renderers/canvas/utils/CanvasMaskManager.js b/src/pixi/renderers/canvas/utils/CanvasMaskManager.js
new file mode 100644
index 00000000..e9a9f974
--- /dev/null
+++ b/src/pixi/renderers/canvas/utils/CanvasMaskManager.js
@@ -0,0 +1,51 @@
+/**
+ * @author Mat Groves
+ *
+ *
+ */
+/**
+ * A set of functions used to handle masking
+ *
+ * @class CanvasMaskManager
+ */
+PIXI.CanvasMaskManager = function()
+{
+
+};
+
+/**
+ * TODO-Alvin
+ *
+ * @method pushMask
+ * @param maskData TODO-Alvin
+ * @param context {Context2D} the 2d drawing method of the canvas
+ */
+PIXI.CanvasMaskManager.prototype.pushMask = function(maskData, context)
+{
+ context.save();
+
+ //maskData.visible = false;
+ // maskData.alpha = 0;
+
+ var cacheAlpha = maskData.alpha;
+ var transform = maskData.worldTransform;
+
+ context.setTransform(transform.a, transform.c, transform.b, transform.d, transform.tx, transform.ty);
+
+ PIXI.CanvasGraphics.renderGraphicsMask(maskData, context);
+
+ context.clip();
+
+ maskData.worldAlpha = cacheAlpha;
+};
+
+/**
+ * Restores the current drawing context to the state it was before the mask was applied
+ *
+ * @method popMask
+ * @param context {Context2D} the 2d drawing method of the canvas
+ */
+PIXI.CanvasMaskManager.prototype.popMask = function(context)
+{
+ context.restore();
+};
\ No newline at end of file
diff --git a/src/pixi/renderers/canvas/utils/CanvasTinter.js b/src/pixi/renderers/canvas/utils/CanvasTinter.js
new file mode 100644
index 00000000..5bb4e3ef
--- /dev/null
+++ b/src/pixi/renderers/canvas/utils/CanvasTinter.js
@@ -0,0 +1,243 @@
+
+/**
+ * @author Mat Groves
+ *
+ *
+ */
+
+/**
+ * @class CanvasTinter
+ * @constructor
+ * @static
+ */
+PIXI.CanvasTinter = function()
+{
+ /// this.textureCach
+};
+
+//PIXI.CanvasTinter.cachTint = true;
+
+
+/**
+ * TODO-Alvin
+ * @method getTintedTexture
+ * @param sprite {Sprite} the sprite to tint
+ * @param color {Number} the color to use to tint the sprite with
+ */
+PIXI.CanvasTinter.getTintedTexture = function(sprite, color)
+{
+ //
+ // cache on sprite
+ // cache on texture
+ // no cache
+
+ var texture = sprite.texture;
+
+ color = PIXI.CanvasTinter.roundColor(color);
+
+ var stringColor = "#" + ("00000" + ( color | 0).toString(16)).substr(-6);
+
+ texture.tintCache = texture.tintCache || {};
+
+ if(texture.tintCache[stringColor]) return texture.tintCache[stringColor];
+
+ // clone texture..
+ var canvas = PIXI.CanvasTinter.canvas || document.createElement("canvas");
+
+ //PIXI.CanvasTinter.tintWithPerPixel(texture, stringColor, canvas);
+
+
+ PIXI.CanvasTinter.tintMethod(texture, color, canvas);
+
+ if(PIXI.CanvasTinter.convertTintToImage)
+ {
+ // is this better?
+ var tintImage = new Image();
+ tintImage.src = canvas.toDataURL();
+
+ texture.tintCache[stringColor] = tintImage;
+ }
+ else
+ {
+
+ texture.tintCache[stringColor] = canvas;
+ // if we are not converting the texture to an image then we need to lose the reference to the canvas
+ PIXI.CanvasTinter.canvas = null;
+
+ }
+
+ return canvas;
+};
+
+/**
+ * Tint a texture using the "multiply" operation
+ * @method tintWithMultiply
+ * @param texture {texture} the texture to tint
+ * @param color {Number} the color to use to tint the sprite with
+ * @param canvas {HTMLCanvasElement} the current canvas
+ */
+PIXI.CanvasTinter.tintWithMultiply = function(texture, color, canvas)
+{
+ var context = canvas.getContext( "2d" );
+
+ var frame = texture.frame;
+
+ canvas.width = frame.width;
+ canvas.height = frame.height;
+
+ context.fillStyle = "#" + ("00000" + ( color | 0).toString(16)).substr(-6);
+
+ context.fillRect(0, 0, frame.width, frame.height);
+
+ context.globalCompositeOperation = "multiply";
+
+ context.drawImage(texture.baseTexture.source,
+ frame.x,
+ frame.y,
+ frame.width,
+ frame.height,
+ 0,
+ 0,
+ frame.width,
+ frame.height);
+
+ context.globalCompositeOperation = "destination-atop";
+
+ context.drawImage(texture.baseTexture.source,
+ frame.x,
+ frame.y,
+ frame.width,
+ frame.height,
+ 0,
+ 0,
+ frame.width,
+ frame.height);
+};
+
+/**
+ * Tint a texture using the "overlay" operation
+ * @method tintWithOverlay
+ * @param texture {texture} the texture to tint
+ * @param color {Number} the color to use to tint the sprite with
+ * @param canvas {HTMLCanvasElement} the current canvas
+ */
+PIXI.CanvasTinter.tintWithOverlay = function(texture, color, canvas)
+{
+ var context = canvas.getContext( "2d" );
+
+ var frame = texture.frame;
+
+ canvas.width = frame.width;
+ canvas.height = frame.height;
+
+
+
+ context.globalCompositeOperation = "copy";
+ context.fillStyle = "#" + ("00000" + ( color | 0).toString(16)).substr(-6);
+ context.fillRect(0, 0, frame.width, frame.height);
+
+ context.globalCompositeOperation = "destination-atop";
+ context.drawImage(texture.baseTexture.source,
+ frame.x,
+ frame.y,
+ frame.width,
+ frame.height,
+ 0,
+ 0,
+ frame.width,
+ frame.height);
+
+
+ //context.globalCompositeOperation = "copy";
+
+};
+
+/**
+ * Tint a texture pixel per pixel
+ * @method tintPerPixel
+ * @param texture {texture} the texture to tint
+ * @param color {Number} the color to use to tint the sprite with
+ * @param canvas {HTMLCanvasElement} the current canvas
+ */
+PIXI.CanvasTinter.tintWithPerPixel = function(texture, color, canvas)
+{
+ var context = canvas.getContext( "2d" );
+
+ var frame = texture.frame;
+
+ canvas.width = frame.width;
+ canvas.height = frame.height;
+
+ context.globalCompositeOperation = "copy";
+ context.drawImage(texture.baseTexture.source,
+ frame.x,
+ frame.y,
+ frame.width,
+ frame.height,
+ 0,
+ 0,
+ frame.width,
+ frame.height);
+
+ var rgbValues = PIXI.hex2rgb(color);
+ var r = rgbValues[0], g = rgbValues[1], b = rgbValues[2];
+
+ var pixelData = context.getImageData(0, 0, frame.width, frame.height);
+
+ var pixels = pixelData.data;
+
+ for (var i = 0; i < pixels.length; i += 4)
+ {
+ pixels[i+0] *= r;
+ pixels[i+1] *= g;
+ pixels[i+2] *= b;
+ }
+
+ context.putImageData(pixelData, 0, 0);
+};
+
+/**
+ * Rounds the specified color according to the PIXI.CanvasTinter.cacheStepsPerColorChannel
+ * @method roundColor
+ * @param color {number} the color to round, should be a hex color
+ */
+PIXI.CanvasTinter.roundColor = function(color)
+{
+ var step = PIXI.CanvasTinter.cacheStepsPerColorChannel;
+
+ var rgbValues = PIXI.hex2rgb(color);
+
+ rgbValues[0] = Math.min(255, (rgbValues[0] / step) * step);
+ rgbValues[1] = Math.min(255, (rgbValues[1] / step) * step);
+ rgbValues[2] = Math.min(255, (rgbValues[2] / step) * step);
+
+ return PIXI.rgb2hex(rgbValues);
+};
+
+/**
+ *
+ * Number of steps which will be used as a cap when rounding colors
+ *
+ * @property cacheStepsPerColorChannel
+ * @type Number
+ */
+PIXI.CanvasTinter.cacheStepsPerColorChannel = 8;
+/**
+ *
+ * Number of steps which will be used as a cap when rounding colors
+ *
+ * @property convertTintToImage
+ * @type Boolean
+ */
+PIXI.CanvasTinter.convertTintToImage = false;
+
+/**
+ * Whether or not the Canvas BlendModes are supported, consequently the ability to tint using the multiply method
+ *
+ * @property canUseMultiply
+ * @type Boolean
+ */
+PIXI.CanvasTinter.canUseMultiply = PIXI.canUseNewCanvasBlendModes();
+
+PIXI.CanvasTinter.tintMethod = PIXI.CanvasTinter.canUseMultiply ? PIXI.CanvasTinter.tintWithMultiply : PIXI.CanvasTinter.tintWithPerPixel;
+
diff --git a/src/pixi/renderers/webgl/WebGLBatch.js b/src/pixi/renderers/webgl/WebGLBatch.js
deleted file mode 100644
index ba719b36..00000000
--- a/src/pixi/renderers/webgl/WebGLBatch.js
+++ /dev/null
@@ -1,572 +0,0 @@
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI._batchs = [];
-
-/**
- * @private
- */
-PIXI._getBatch = function(gl)
-{
- 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);
-};
-
-/**
- * @private
- */
-PIXI._restoreBatchs = function(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.
- * if a group of sprites all have the same baseTexture and blendMode then they can be grouped into a batch.
- * All the sprites in a batch can then be drawn in one go by the GPU which is hugely efficient. ALL sprites
- * in the webGL renderer are added to a batch even if the batch only contains one sprite. Batching is handled
- * automatically by the webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @constructor
- * @param gl {WebGLContext} an instance of the webGL context
- */
-PIXI.WebGLBatch = function(gl)
-{
- this.gl = gl;
-
- 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;
-
-/**
- * Cleans the batch so that is can be returned to an object pool and reused
- *
- * @method clean
- */
-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 = null;
- this.tail = null;
-};
-
-/**
- * Recreates the buffers in the event of a context loss
- *
- * @method restoreLostContext
- * @param gl {WebGLContext}
- */
-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();
-};
-
-/**
- * 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
- */
-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;
-
- this.growBatch();
-};
-
-/**
- * inserts a sprite before the specified 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++;
-
- 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;
- }
-};
-
-/**
- * inserts a sprite after the specified sprite
- *
- * @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++;
-
- sprite.batch = this;
- this.dirty = true;
-
- var tempNext = previousSprite.__next;
- previousSprite.__next = sprite;
- sprite.__prev = previousSprite;
-
- 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--;
-
- 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.__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;
-};
-
-/**
- * Splits the batch into two with the specified sprite being the start of the new batch.
- *
- * @method split
- * @param sprite {Sprite} the sprite that indicates where the batch should be split
- * @return {WebGLBatch} the new batch
- */
-PIXI.WebGLBatch.prototype.split = function(sprite)
-{
- this.dirty = true;
-
- 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;
-
- 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"?
-
- // 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;
-
- return batch;
-};
-
-/**
- * Merges two batchs together
- *
- * @method merge
- * @param batch {WebGLBatch} the batch that will be merged
- */
-PIXI.WebGLBatch.prototype.merge = function(batch)
-{
- this.dirty = true;
-
- this.tail.__next = batch.head;
- batch.head.__prev = this.tail;
-
- this.size += batch.size;
-
- this.tail = batch.tail;
-
- 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
- * function is used to increase the size of the batch. It also creates a little extra room so
- * that the batch does not need to be resized every time a sprite is added
- *
- * @method growBatch
- */
-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);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER,this.verticies , gl.DYNAMIC_DRAW);
-
- 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.dirtyUVS = 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.dirtyColors = true;
-
- this.indices = new Uint16Array(this.dynamicSize * 6);
- var length = this.indices.length/6;
-
- 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
- *
- * @method refresh
- */
-PIXI.WebGLBatch.prototype.refresh = function()
-{
- if (this.dynamicSize < this.size)
- {
- this.growBatch();
- }
-
- var indexRun = 0;
- var index, colorIndex;
-
- var displayObject = this.head;
-
- while(displayObject)
- {
- index = indexRun * 8;
-
- var texture = displayObject.texture;
-
- 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 +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 +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
-
- colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
-
- displayObject = displayObject.__next;
-
- indexRun++;
- }
-
- this.dirtyUVS = true;
- this.dirtyColors = true;
-};
-
-/**
- * Updates all the relevant geometry and uploads the data to the GPU
- *
- * @method update
- */
-PIXI.WebGLBatch.prototype.update = function()
-{
- var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index;
-
- var a, b, c, d, tx, ty;
-
- 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;
-
- // 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;
-
- h0 = height * (1-aY);
- h1 = height * -aY;
-
- index = indexRun * 8;
-
- worldTransform = displayObject.worldTransform;
-
- a = worldTransform[0];
- b = worldTransform[3];
- c = worldTransform[1];
- d = worldTransform[4];
- tx = worldTransform[2];
- ty = worldTransform[5];
-
- verticies[index + 0 ] = a * w1 + c * h1 + tx;
- verticies[index + 1 ] = d * h1 + b * w1 + ty;
-
- verticies[index + 2 ] = a * w0 + c * h1 + tx;
- verticies[index + 3 ] = d * h1 + b * w0 + ty;
-
- verticies[index + 4 ] = a * w0 + c * h0 + tx;
- verticies[index + 5 ] = d * h0 + b * w0 + ty;
-
- verticies[index + 6] = a * w1 + c * h0 + tx;
- verticies[index + 7] = d * h0 + b * w1 + ty;
-
- if(displayObject.updateFrame || displayObject.texture.updateFrame)
- {
- this.dirtyUVS = true;
-
- var texture = displayObject.texture;
-
- var frame = texture.frame;
- var tw = texture.baseTexture.width;
- var th = texture.baseTexture.height;
-
- uvs[index + 0] = frame.x / tw;
- uvs[index +1] = frame.y / th;
-
- uvs[index +2] = (frame.x + frame.width) / tw;
- uvs[index +3] = frame.y / th;
-
- uvs[index +4] = (frame.x + frame.width) / tw;
- uvs[index +5] = (frame.y + frame.height) / th;
-
- uvs[index +6] = frame.x / tw;
- uvs[index +7] = (frame.y + frame.height) / th;
-
- displayObject.updateFrame = false;
- }
-
- // TODO this probably could do with some optimisation....
- if(displayObject.cacheAlpha !== displayObject.worldAlpha)
- {
- displayObject.cacheAlpha = displayObject.worldAlpha;
-
- var colorIndex = indexRun * 4;
- colors[colorIndex] = colors[colorIndex + 1] = colors[colorIndex + 2] = colors[colorIndex + 3] = displayObject.worldAlpha;
- this.dirtyColors = true;
- }
- }
- else
- {
- index = indexRun * 8;
-
- 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
- *
- * @method render
- */
-PIXI.WebGLBatch.prototype.render = function(start, end)
-{
- start = start || 0;
-
- if(end === undefined)
- end = this.size;
-
- if(this.dirty)
- {
- this.refresh();
- this.dirty = false;
- }
-
- if (this.size === 0)return;
-
- this.update();
- var gl = this.gl;
-
- //TODO optimize this!
-
- 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)
-
- gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
-
- if(this.dirtyUVS)
- {
- this.dirtyUVS = false;
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs);
- }
-
- gl.vertexAttribPointer(shaderProgram.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture);
-
- // update color!
- gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
-
- if(this.dirtyColors)
- {
- 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!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
-
- var len = end - start;
-
- // DRAW THAT this!
- gl.drawElements(gl.TRIANGLES, len * 6, gl.UNSIGNED_SHORT, start * 2 * 6 );
-};
diff --git a/src/pixi/renderers/webgl/WebGLRenderGroup.js b/src/pixi/renderers/webgl/WebGLRenderGroup.js
deleted file mode 100644
index e3543fe7..00000000
--- a/src/pixi/renderers/webgl/WebGLRenderGroup.js
+++ /dev/null
@@ -1,1028 +0,0 @@
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-/**
- * A WebGLBatch Enables a group of sprites to be drawn using the same settings.
- * if a group of sprites all have the same baseTexture and blendMode then they can be
- * grouped into a batch. All the sprites in a batch can then be drawn in one go by the
- * GPU which is hugely efficient. ALL sprites in the webGL renderer are added to a batch
- * even if the batch only contains one sprite. Batching is handled automatically by the
- * webGL renderer. A good tip is: the smaller the number of batchs there are, the faster
- * the webGL renderer will run.
- *
- * @class WebGLBatch
- * @contructor
- * @param gl {WebGLContext} An instance of the webGL context
- */
-PIXI.WebGLRenderGroup = function(gl, transparent)
-{
- this.gl = gl;
- this.root;
-
- this.backgroundColor;
- this.transparent = transparent == undefined ? true : transparent;
-
- this.batchs = [];
- this.toRemove = [];
- // console.log(this.transparent)
- this.filterManager = new PIXI.WebGLFilterManager(this.transparent);
-}
-
-// constructor
-PIXI.WebGLRenderGroup.prototype.constructor = PIXI.WebGLRenderGroup;
-
-/**
- * Add a display object to the webgl renderer
- *
- * @method setRenderable
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.setRenderable = function(displayObject)
-{
- // has this changed??
- if(this.root)this.removeDisplayObjectAndChildren(this.root);
-
- displayObject.worldVisible = displayObject.visible;
-
- // soooooo //
- // to check if any batchs exist already??
-
- // TODO what if its already has an object? should remove it
- this.root = displayObject;
- this.addDisplayObjectAndChildren(displayObject);
-}
-
-/**
- * Renders the stage to its webgl view
- *
- * @method render
- * @param projection {Object}
- */
-PIXI.WebGLRenderGroup.prototype.render = function(projection, buffer)
-{
- PIXI.WebGLRenderer.updateTextures();
-
- var gl = this.gl;
- gl.uniform2f(PIXI.defaultShader.projectionVector, projection.x, projection.y);
-
- this.filterManager.begin(projection, buffer);
-
-
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- // will render all the elements in the group
- var renderable;
-
- for (var i=0; i < this.batchs.length; i++)
- {
-
- renderable = this.batchs[i];
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- continue;
- }
-
- // render special
- this.renderSpecial(renderable, projection);
- }
-
-}
-
-/**
- * Renders a specific displayObject
- *
- * @method renderSpecific
- * @param displayObject {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection, buffer)
-{
- PIXI.WebGLRenderer.updateTextures();
- var gl = this.gl;
-
- gl.uniform2f(PIXI.defaultShader.projectionVector, projection.x, projection.y);
-
- this.filterManager.begin(projection, buffer);
-
- // to do!
- // render part of the scene...
-
- var startIndex;
- var startBatchIndex;
-
- var endIndex;
- var endBatchIndex;
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.first;
- while(nextRenderable._iNext)
- {
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- nextRenderable = nextRenderable._iNext;
- }
- var startBatch = nextRenderable.batch;
- //console.log(nextRenderable);
-
- //console.log(renderable)
- if(nextRenderable instanceof PIXI.Sprite)
- {
- startBatch = nextRenderable.batch;
-
- var head = startBatch.head;
- var next = head;
-
- // ok now we have the batch.. need to find the start index!
- if(head == nextRenderable)
- {
- startIndex = 0;
- }
- else
- {
- startIndex = 1;
-
- while(head.__next != nextRenderable)
- {
- startIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- startBatch = nextRenderable;
- }
-
- // Get the LAST renderable object
- var lastRenderable = displayObject.last;
- while(lastRenderable._iPrev)
- {
- if(lastRenderable.renderable && lastRenderable.__renderGroup)break;
- lastRenderable = lastRenderable._iNext;
- }
-
- if(lastRenderable instanceof PIXI.Sprite)
- {
- endBatch = lastRenderable.batch;
-
- var head = endBatch.head;
-
- if(head == lastRenderable)
- {
- endIndex = 0;
- }
- else
- {
- endIndex = 1;
-
- while(head.__next != lastRenderable)
- {
- endIndex++;
- head = head.__next;
- }
- }
- }
- else
- {
- endBatch = lastRenderable;
- }
-
- if(startBatch == endBatch)
- {
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex, endIndex+1);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
- return;
- }
-
- // now we have first and last!
- startBatchIndex = this.batchs.indexOf(startBatch);
- endBatchIndex = this.batchs.indexOf(endBatch);
-
- // DO the first batch
- if(startBatch instanceof PIXI.WebGLBatch)
- {
- startBatch.render(startIndex);
- }
- else
- {
- this.renderSpecial(startBatch, projection);
- }
-
- // DO the middle batchs..
- for (var i=startBatchIndex+1; i < endBatchIndex; i++)
- {
- renderable = this.batchs[i];
-
- if(renderable instanceof PIXI.WebGLBatch)
- {
- this.batchs[i].render();
- }
- else
- {
- this.renderSpecial(renderable, projection);
- }
- }
-
- // DO the last batch..
- if(endBatch instanceof PIXI.WebGLBatch)
- {
- endBatch.render(0, endIndex+1);
- }
- else
- {
- this.renderSpecial(endBatch, projection);
- }
-}
-
-/**
- * Renders a specific renderable
- *
- * @method renderSpecial
- * @param renderable {DisplayObject}
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
-{
-
- var worldVisible = renderable.vcount === PIXI.visibleCount
-
-
- if(renderable instanceof PIXI.TilingSprite)
- {
- if(worldVisible)this.renderTilingSprite(renderable, projection);
- }
- else if(renderable instanceof PIXI.Strip)
- {
- if(worldVisible)this.renderStrip(renderable, projection);
- }
- else if(renderable instanceof PIXI.CustomRenderable)
- {
- if(worldVisible) renderable.renderWebGL(this, projection);
- }
- else if(renderable instanceof PIXI.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- this.handleFilterBlock(renderable, projection);
- }
-}
-
-flip = false;
-var maskStack = [];
-var maskPosition = 0;
-
-//var usedMaskStack = [];
-
-PIXI.WebGLRenderGroup.prototype.handleFilterBlock = function(filterBlock, projection)
-{
- /*
- * for now only masks are supported..
- */
- var gl = PIXI.gl;
-
- if(filterBlock.open)
- {
- if(filterBlock.data instanceof Array)
- {
- this.filterManager.pushFilter(filterBlock);
- // ok so..
-
- }
- else
- {
- maskPosition++;
-
- maskStack.push(filterBlock)
-
- gl.enable(gl.STENCIL_TEST);
-
- gl.colorMask(false, false, false, false);
-
- gl.stencilFunc(gl.ALWAYS,1,1);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR);
-
- PIXI.WebGLGraphics.renderGraphics(filterBlock.data, projection);
-
- gl.colorMask(true, true, true, true);
- gl.stencilFunc(gl.NOTEQUAL,0,maskStack.length);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
- }
- }
- else
- {
- if(filterBlock.data instanceof Array)
- {
- this.filterManager.popFilter();
- }
- else
- {
- var maskData = maskStack.pop(filterBlock)
-
-
- if(maskData)
- {
- gl.colorMask(false, false, false, false);
-
- gl.stencilFunc(gl.ALWAYS,1,1);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR);
-
- PIXI.WebGLGraphics.renderGraphics(maskData.data, projection);
-
- gl.colorMask(true, true, true, true);
- gl.stencilFunc(gl.NOTEQUAL,0,maskStack.length);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
- };
-
- gl.disable(gl.STENCIL_TEST);
- }
- }
-}
-
-/**
- * Updates a webgl texture
- *
- * @method updateTexture
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.updateTexture = function(displayObject)
-{
-
- // TODO definitely can optimse this function..
-
- this.removeObject(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- this.insertObject(displayObject, previousRenderable, nextRenderable);
-}
-
-/**
- * Adds filter blocks
- *
- * @method addFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end)
-{
- start.__renderGroup = this;
- end.__renderGroup = this;
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
- var previousRenderable = start;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
- this.insertAfter(start, previousRenderable);
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var previousRenderable2 = end;
- while(previousRenderable2 != this.root.first)
- {
- previousRenderable2 = previousRenderable2._iPrev;
- if(previousRenderable2.renderable && previousRenderable2.__renderGroup)break;
- }
- this.insertAfter(end, previousRenderable2);
-}
-
-/**
- * Remove filter blocks
- *
- * @method removeFilterBlocks
- * @param start {FilterBlock}
- * @param end {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeFilterBlocks = function(start, end)
-{
- this.removeObject(start);
- this.removeObject(end);
-}
-
-/**
- * Adds a display object and children to the webgl context
- *
- * @method addDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.addDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup)displayObject.__renderGroup.removeDisplayObjectAndChildren(displayObject);
-
- /*
- * LOOK FOR THE PREVIOUS RENDERABLE
- * This part looks for the closest previous sprite that can go into a batch
- * It keeps going back until it finds a sprite or the stage
- */
-
- var previousRenderable = displayObject.first;
- while(previousRenderable != this.root.first)
- {
- previousRenderable = previousRenderable._iPrev;
- if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
- }
-
- /*
- * LOOK FOR THE NEXT SPRITE
- * This part looks for the closest next sprite that can go into a batch
- * it keeps looking until it finds a sprite or gets to the end of the display
- * scene graph
- */
- var nextRenderable = displayObject.last;
- while(nextRenderable._iNext)
- {
- nextRenderable = nextRenderable._iNext;
- if(nextRenderable.renderable && nextRenderable.__renderGroup)break;
- }
-
- // one the display object hits this. we can break the loop
-
- var tempObject = displayObject.first;
- var testObject = displayObject.last._iNext;
- do
- {
- tempObject.__renderGroup = this;
-
- if(tempObject.renderable)
- {
-
- this.insertObject(tempObject, previousRenderable, nextRenderable);
- previousRenderable = tempObject;
- }
-
- tempObject = tempObject._iNext;
- }
- while(tempObject != testObject)
-}
-
-/**
- * Removes a display object and children to the webgl context
- *
- * @method removeDisplayObjectAndChildren
- * @param displayObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeDisplayObjectAndChildren = function(displayObject)
-{
- if(displayObject.__renderGroup != this)return;
-
-// var displayObject = displayObject.first;
- var lastObject = displayObject.last;
- do
- {
- displayObject.__renderGroup = null;
- if(displayObject.renderable)this.removeObject(displayObject);
- displayObject = displayObject._iNext;
- }
- while(displayObject)
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertObject
- * @param displayObject {DisplayObject}
- * @param previousObject {DisplayObject}
- * @param nextObject {DisplayObject}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertObject = function(displayObject, previousObject, nextObject)
-{
- // while looping below THE OBJECT MAY NOT HAVE BEEN ADDED
- var previousSprite = previousObject;
- var nextSprite = nextObject;
-
- /*
- * so now we have the next renderable and the previous renderable
- *
- */
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch
- var nextBatch
-
- if(previousSprite instanceof PIXI.Sprite)
- {
- previousBatch = previousSprite.batch;
- if(previousBatch)
- {
- if(previousBatch.texture == displayObject.texture.baseTexture && previousBatch.blendMode == displayObject.blendMode)
- {
- previousBatch.insertAfter(displayObject, previousSprite);
- return;
- }
- }
- }
- else
- {
- // TODO reword!
- previousBatch = previousSprite;
- }
-
- if(nextSprite)
- {
- if(nextSprite instanceof PIXI.Sprite)
- {
- nextBatch = nextSprite.batch;
-
- //batch may not exist if item was added to the display list but not to the webGL
- if(nextBatch)
- {
- if(nextBatch.texture == displayObject.texture.baseTexture && nextBatch.blendMode == displayObject.blendMode)
- {
- nextBatch.insertBefore(displayObject, nextSprite);
- return;
- }
- else
- {
- if(nextBatch == previousBatch)
- {
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(nextSprite);
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var batch = PIXI.WebGLRenderer.getBatch();
-
- var index = this.batchs.indexOf( previousBatch );
- batch.init(displayObject);
- this.batchs.splice(index+1, 0, batch, splitBatch);
-
- return;
- }
- }
- }
- }
- else
- {
- // TODO re-word!
-
- nextBatch = nextSprite;
- }
- }
-
- /*
- * looks like it does not belong to any batch!
- * but is also not intersecting one..
- * time to create anew one!
- */
-
- var batch = PIXI.WebGLRenderer.getBatch();
- batch.init(displayObject);
-
- if(previousBatch) // if this is invalid it means
- {
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, batch);
- }
- else
- {
- this.batchs.push(batch);
- }
-
- return;
- }
- else if(displayObject instanceof PIXI.TilingSprite)
- {
-
- // add to a batch!!
- this.initTilingSprite(displayObject);
- // this.batchs.push(displayObject);
-
- }
- else if(displayObject instanceof PIXI.Strip)
- {
- // add to a batch!!
- this.initStrip(displayObject);
- // this.batchs.push(displayObject);
- }
- else if(displayObject)// instanceof PIXI.Graphics)
- {
- //displayObject.initWebGL(this);
-
- // add to a batch!!
- //this.initStrip(displayObject);
- //this.batchs.push(displayObject);
- }
-
- this.insertAfter(displayObject, previousSprite);
-
- // insert and SPLIT!
-
-}
-
-/**
- * Inserts a displayObject into the linked list
- *
- * @method insertAfter
- * @param item {DisplayObject}
- * @param displayObject {DisplayObject} The object to insert
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.insertAfter = function(item, displayObject)
-{
- if(displayObject instanceof PIXI.Sprite)
- {
- var previousBatch = displayObject.batch;
-
- if(previousBatch)
- {
- // so this object is in a batch!
-
- // is it not? need to split the batch
- if(previousBatch.tail == displayObject)
- {
- // is it tail? insert in to batchs
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item);
- }
- else
- {
- // TODO MODIFY ADD / REMOVE CHILD TO ACCOUNT FOR FILTERS (also get prev and next) //
-
- // THERE IS A SPLIT IN THIS BATCH! //
- var splitBatch = previousBatch.split(displayObject.__next);
-
- // COOL!
- // add it back into the array
- /*
- * OOPS!
- * seems the new sprite is in the middle of a batch
- * lets split it..
- */
- var index = this.batchs.indexOf( previousBatch );
- this.batchs.splice(index+1, 0, item, splitBatch);
- }
- }
- else
- {
- this.batchs.push(item);
- }
- }
- else
- {
- var index = this.batchs.indexOf( displayObject );
- this.batchs.splice(index+1, 0, item);
- }
-}
-
-/**
- * Removes a displayObject from the linked list
- *
- * @method removeObject
- * @param displayObject {DisplayObject} The object to remove
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.removeObject = function(displayObject)
-{
- // loop through children..
- // display object //
-
- // add a child from the render group..
- // remove it and all its children!
- //displayObject.cacheVisible = false;//displayObject.visible;
-
- /*
- * removing is a lot quicker..
- *
- */
- var batchToRemove;
-
- if(displayObject instanceof PIXI.Sprite)
- {
- // should always have a batch!
- var batch = displayObject.batch;
- if(!batch)return; // this means the display list has been altered befre rendering
-
- batch.remove(displayObject);
-
- if(batch.size==0)
- {
- batchToRemove = batch;
- }
- }
- else
- {
- batchToRemove = displayObject;
- }
-
- /*
- * Looks like there is somthing that needs removing!
- */
- if(batchToRemove)
- {
- var index = this.batchs.indexOf( batchToRemove );
- if(index == -1)return;// this means it was added then removed before rendered
-
- // ok so.. check to see if you adjacent batchs should be joined.
- // TODO may optimise?
- if(index == 0 || index == this.batchs.length-1)
- {
- // wha - eva! just get of the empty batch!
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
-
- return;
- }
-
- if(this.batchs[index-1] instanceof PIXI.WebGLBatch && this.batchs[index+1] instanceof PIXI.WebGLBatch)
- {
- if(this.batchs[index-1].texture == this.batchs[index+1].texture && this.batchs[index-1].blendMode == this.batchs[index+1].blendMode)
- {
- //console.log("MERGE")
- this.batchs[index-1].merge(this.batchs[index+1]);
-
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- PIXI.WebGLRenderer.returnBatch(this.batchs[index+1]);
- this.batchs.splice(index, 2);
- return;
- }
- }
-
- this.batchs.splice(index, 1);
- if(batchToRemove instanceof PIXI.WebGLBatch)PIXI.WebGLRenderer.returnBatch(batchToRemove);
- }
-}
-
-
-/**
- * Initializes a tiling sprite
- *
- * @method initTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initTilingSprite = function(sprite)
-{
- var gl = this.gl;
-
- // make the texture tilable..
-
- sprite.verticies = new Float32Array([0, 0,
- sprite.width, 0,
- sprite.width, sprite.height,
- 0, sprite.height]);
-
- sprite.uvs = new Float32Array([0, 0,
- 1, 0,
- 1, 1,
- 0, 1]);
-
- sprite.colors = new Float32Array([1,1,1,1]);
-
- sprite.indices = new Uint16Array([0, 1, 3,2])//, 2]);
-
- sprite._vertexBuffer = gl.createBuffer();
- sprite._indexBuffer = gl.createBuffer();
- sprite._uvBuffer = gl.createBuffer();
- sprite._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.verticies, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.uvs, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, sprite.colors, gl.STATIC_DRAW);
-
- 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) );
-
- if(sprite.texture.baseTexture._glTexture)
- {
- gl.bindTexture(gl.TEXTURE_2D, sprite.texture.baseTexture._glTexture);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, gl.REPEAT);
- gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, gl.REPEAT);
- sprite.texture.baseTexture._powerOf2 = true;
- }
- else
- {
- sprite.texture.baseTexture._powerOf2 = true;
- }
-}
-
-/**
- * Renders a Strip
- *
- * @method renderStrip
- * @param strip {Strip} The strip to render
- * @param projection {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
-{
- var gl = this.gl;
-
- PIXI.activateStripShader();
-
- var shader = PIXI.stripShader;
-
- var program = shader.program;
-
- var m = PIXI.mat3.clone(strip.worldTransform);
-
- PIXI.mat3.transpose(m);
-
-// console.log(projection)
- // set the matrix transform for the
- gl.uniformMatrix3fv(shader.translationMatrix, false, m);
- gl.uniform2f(shader.projectionVector, projection.x, projection.y);
- gl.uniform2f(shader.offsetVector, -PIXI.offset.x, -PIXI.offset.y);
-
- gl.uniform1f(shader.alpha, strip.worldAlpha);
-
- /*
- if(strip.blendMode == PIXI.blendModes.NORMAL)
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- }
- else
- {
- gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_COLOR);
- }
- */
-
- //console.log("!!")
- if(!strip.dirty)
- {
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, strip.verticies)
- gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.vertexAttribPointer(shader.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- }
- else
- {
- strip.dirty = false;
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
-
- // update the uvs
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
-
- gl.activeTexture(gl.TEXTURE0);
- gl.bindTexture(gl.TEXTURE_2D, strip.texture.baseTexture._glTexture);
- // console.log(strip.texture.baseTexture._glTexture)
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shader.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
- // dont need to upload!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-
- }
-
- gl.drawElements(gl.TRIANGLE_STRIP, strip.indices.length, gl.UNSIGNED_SHORT, 0);
-
- PIXI.deactivateStripShader();
- //gl.useProgram(PIXI.currentProgram);
-}
-
-/**
- * Renders a TilingSprite
- *
- * @method renderTilingSprite
- * @param sprite {TilingSprite} The tiling sprite to render
- * @param projectionMatrix {Object}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.renderTilingSprite = function(sprite, projectionMatrix)
-{
- var gl = this.gl;
-
-
- var shaderProgram = PIXI.shaderProgram;
-
- var tilePosition = sprite.tilePosition;
- var tileScale = sprite.tileScale;
-
- var offsetX = tilePosition.x/sprite.texture.baseTexture.width;
- var offsetY = tilePosition.y/sprite.texture.baseTexture.height;
-
- var scaleX = (sprite.width / sprite.texture.baseTexture.width) / tileScale.x;
- var scaleY = (sprite.height / sprite.texture.baseTexture.height) / tileScale.y;
-
- sprite.uvs[0] = 0 - offsetX;
- sprite.uvs[1] = 0 - offsetY;
-
- sprite.uvs[2] = (1 * scaleX) -offsetX;
- sprite.uvs[3] = 0 - offsetY;
-
- sprite.uvs[4] = (1 *scaleX) - offsetX;
- sprite.uvs[5] = (1 *scaleY) - offsetY;
-
- sprite.uvs[6] = 0 - offsetX;
- sprite.uvs[7] = (1 *scaleY) - offsetY;
-
- gl.bindBuffer(gl.ARRAY_BUFFER, sprite._uvBuffer);
- gl.bufferSubData(gl.ARRAY_BUFFER, 0, sprite.uvs)
-
- this.renderStrip(sprite, projectionMatrix);
-}
-
-/**
- * Initializes a strip to be rendered
- *
- * @method initStrip
- * @param strip {Strip} The strip to initialize
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.initStrip = function(strip)
-{
- // build the strip!
- var gl = this.gl;
- var shaderProgram = this.shaderProgram;
-
- strip._vertexBuffer = gl.createBuffer();
- strip._indexBuffer = gl.createBuffer();
- strip._uvBuffer = gl.createBuffer();
- strip._colorBuffer = gl.createBuffer();
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.DYNAMIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.uvs, gl.STATIC_DRAW);
-
- gl.bindBuffer(gl.ARRAY_BUFFER, strip._colorBuffer);
- gl.bufferData(gl.ARRAY_BUFFER, strip.colors, gl.STATIC_DRAW);
-
-
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, strip.indices, gl.STATIC_DRAW);
-}
-
diff --git a/src/pixi/renderers/webgl/WebGLRenderer.js b/src/pixi/renderers/webgl/WebGLRenderer.js
index 4d83833b..3edbd33a 100644
--- a/src/pixi/renderers/webgl/WebGLRenderer.js
+++ b/src/pixi/renderers/webgl/WebGLRenderer.js
@@ -2,15 +2,11 @@
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
-PIXI._defaultFrame = new PIXI.Rectangle(0,0,1,1);
-
-// an instance of the gl context..
-// only one at the moment :/
-PIXI.gl = null;
+PIXI.glContexts = []; // this is where we store the webGL contexts for easy access.
/**
- * the WebGLRenderer is draws the stage and all its content onto a webGL enabled canvas. This renderer
- * should be used for browsers support webGL. This Render works by automatically managing webGLBatchs.
+ * the WebGLRenderer draws the stage and all its content onto a webGL enabled canvas. This renderer
+ * should be used for browsers that support webGL. This Render works by automatically managing webGLBatch's.
* So no need for Sprite Batch's or Sprite Cloud's
* Dont forget to add the view to your DOM or you will not see anything :)
*
@@ -18,123 +14,150 @@ PIXI.gl = null;
* @constructor
* @param width=0 {Number} the width of the canvas view
* @param height=0 {Number} the height of the canvas view
- * @param view {Canvas} the canvas to use as a view, optional
- * @param transparent=false {Boolean} the transparency of the render view, default false
+ * @param view {HTMLCanvasElement} the canvas to use as a view, optional
+ * @param transparent=false {Boolean} If the render view is transparent, 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..
+ if(!PIXI.defaultRenderer)PIXI.defaultRenderer = this;
+ this.type = PIXI.WEBGL_RENDERER;
+
+ // do a catch.. only 1 webGL renderer..
+ /**
+ * Whether the render view is transparent
+ *
+ * @property transparent
+ * @type Boolean
+ */
this.transparent = !!transparent;
+ /**
+ * 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 canvas element that everything is drawn to
+ *
+ * @property view
+ * @type HTMLCanvasElement
+ */
this.view = view || document.createElement( 'canvas' );
this.view.width = this.width;
this.view.height = this.height;
// 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);
+ // TODO-Alvin
+ this.contextLost = this.handleContextLost.bind(this);
+ this.contextRestoredLost = this.handleContextRestored.bind(this);
+ // console.log(this.handleContextRestored)
+ this.view.addEventListener('webglcontextlost', this.contextLost, false);
+ this.view.addEventListener('webglcontextrestored', this.contextRestoredLost, false);
- this.batchs = [];
-
- var options = {
+ this.options = {
alpha: this.transparent,
antialias:!!antialias, // SPEED UP??
- premultipliedAlpha:false,
+ premultipliedAlpha:!!transparent,
stencil:true
};
//try 'experimental-webgl'
try {
- PIXI.gl = this.gl = this.view.getContext('experimental-webgl', options);
+ this.gl = this.view.getContext('experimental-webgl', this.options);
} catch (e) {
//try 'webgl'
try {
- PIXI.gl = this.gl = this.view.getContext('webgl', options);
+ this.gl = this.view.getContext('webgl', this.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;
+ this.glContextId = gl.id = PIXI.WebGLRenderer.glContextId ++;
- gl.useProgram(PIXI.defaultShader.program);
+ PIXI.glContexts[this.glContextId] = gl;
+
+ if(!PIXI.blendModesWebGL)
+ {
+ PIXI.blendModesWebGL = [];
+
+ PIXI.blendModesWebGL[PIXI.blendModes.NORMAL] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.ADD] = [gl.SRC_ALPHA, gl.DST_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.MULTIPLY] = [gl.DST_COLOR, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.SCREEN] = [gl.SRC_ALPHA, gl.ONE];
+ PIXI.blendModesWebGL[PIXI.blendModes.OVERLAY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.DARKEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.LIGHTEN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.COLOR_DODGE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.COLOR_BURN] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.HARD_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.SOFT_LIGHT] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.DIFFERENCE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.EXCLUSION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.HUE] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.SATURATION] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.COLOR] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ PIXI.blendModesWebGL[PIXI.blendModes.LUMINOSITY] = [gl.ONE, gl.ONE_MINUS_SRC_ALPHA];
+ }
- PIXI.WebGLRenderer.gl = gl;
- this.batch = new PIXI.WebGLBatch(gl);
+
+ this.projection = new PIXI.Point();
+ this.projection.x = this.width/2;
+ this.projection.y = -this.height/2;
+
+ this.offset = new PIXI.Point(0, 0);
+
+ this.resize(this.width, this.height);
+ this.contextLost = false;
+
+ // time to create the render managers! each one focuses on managine a state in webGL
+ this.shaderManager = new PIXI.WebGLShaderManager(gl); // deals with managing the shader programs and their attribs
+ this.spriteBatch = new PIXI.WebGLSpriteBatch(gl); // manages the rendering of sprites
+ this.maskManager = new PIXI.WebGLMaskManager(gl); // manages the masks using the stencil buffer
+ this.filterManager = new PIXI.WebGLFilterManager(gl, this.transparent); // manages the filters
+
+ //
+ this.renderSession = {};
+ this.renderSession.gl = this.gl;
+ this.renderSession.drawCount = 0;
+ this.renderSession.shaderManager = this.shaderManager;
+ this.renderSession.maskManager = this.maskManager;
+ this.renderSession.filterManager = this.filterManager;
+ this.renderSession.spriteBatch = this.spriteBatch;
+
+
+ gl.useProgram(this.shaderManager.defaultShader.program);
+
gl.disable(gl.DEPTH_TEST);
gl.disable(gl.CULL_FACE);
gl.enable(gl.BLEND);
gl.colorMask(true, true, true, this.transparent);
-
- PIXI.projection = new PIXI.Point(400, 300);
- PIXI.offset = new PIXI.Point(0, 0);
-
- // TODO remove thease globals..
-
- this.resize(this.width, this.height);
- this.contextLost = false;
-
- //PIXI.pushShader(PIXI.defaultShader);
-
- this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl, this.transparent);
- // this.stageRenderGroup. = this.transparent
};
// constructor
PIXI.WebGLRenderer.prototype.constructor = PIXI.WebGLRenderer;
-/**
- * Gets a new WebGLBatch from the pool
- *
- * @static
- * @method getBatch
- * @return {WebGLBatch}
- * @private
- */
-PIXI.WebGLRenderer.getBatch = function()
-{
- if(PIXI._batchs.length === 0)
- {
- return new PIXI.WebGLBatch(PIXI.WebGLRenderer.gl);
- }
- else
- {
- return PIXI._batchs.pop();
- }
-};
-
-/**
- * Puts a batch back into the pool
- *
- * @static
- * @method returnBatch
- * @param batch {WebGLBatch} The batch to return
- * @private
- */
-PIXI.WebGLRenderer.returnBatch = function(batch)
-{
- batch.clean();
- PIXI._batchs.push(batch);
-};
-
/**
* Renders the stage to its webGL view
*
@@ -146,44 +169,49 @@ PIXI.WebGLRenderer.prototype.render = function(stage)
if(this.contextLost)return;
- // if rendering a new stage clear the batchs..
+ // if rendering a new stage clear the batches..
if(this.__stage !== stage)
{
+ if(stage.interactive)stage.interactionManager.removeEvents();
+
// TODO make this work
// dont think this is needed any more?
this.__stage = stage;
- this.stageRenderGroup.setRenderable(stage);
}
- // update any textures
+ // update any textures this includes uvs and uploading them to the gpu
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.colorMask(true, true, true, this.transparent);
gl.viewport(0, 0, this.width, this.height);
+ // make sure we are bound to the main frame buffer
gl.bindFramebuffer(gl.FRAMEBUFFER, null);
- gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], !this.transparent);
+ if(this.transparent)
+ {
+ gl.clearColor(0, 0, 0, 0);
+ }
+ else
+ {
+ gl.clearColor(stage.backgroundColorSplit[0],stage.backgroundColorSplit[1],stage.backgroundColorSplit[2], 1);
+ }
+
+
gl.clear(gl.COLOR_BUFFER_BIT);
- // HACK TO TEST
+ // this.projection.x = this.width/2;
+ //this.projection.y = -this.height/2;
- this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit;
-
- PIXI.projection.x = this.width/2;
- PIXI.projection.y = -this.height/2;
-
- this.stageRenderGroup.render(PIXI.projection);
+ this.renderDisplayObject( stage, this.projection );
// interaction
- // run interaction!
if(stage.interactive)
{
//need to add some events!
@@ -193,17 +221,65 @@ PIXI.WebGLRenderer.prototype.render = function(stage)
stage.interactionManager.setTarget(this);
}
}
-
- // after rendering lets confirm all frames that have been uodated..
- if(PIXI.Texture.frameUpdates.length > 0)
+ else
{
- for (var i=0; i < PIXI.Texture.frameUpdates.length; i++)
+ if(stage._interactiveEventsAdded)
{
- PIXI.Texture.frameUpdates[i].updateFrame = false;
+ stage._interactiveEventsAdded = false;
+ stage.interactionManager.setTarget(this);
}
-
- PIXI.Texture.frameUpdates = [];
}
+
+ /*
+ //can simulate context loss in Chrome like so:
+ this.view.onmousedown = function(ev) {
+ console.dir(this.gl.getSupportedExtensions());
+ var ext = (
+ gl.getExtension("WEBGL_scompressed_texture_s3tc")
+ // gl.getExtension("WEBGL_compressed_texture_s3tc") ||
+ // gl.getExtension("MOZ_WEBGL_compressed_texture_s3tc") ||
+ // gl.getExtension("WEBKIT_WEBGL_compressed_texture_s3tc")
+ );
+ console.dir(ext);
+ var loseCtx = this.gl.getExtension("WEBGL_lose_context");
+ console.log("killing context");
+ loseCtx.loseContext();
+ setTimeout(function() {
+ console.log("restoring context...");
+ loseCtx.restoreContext();
+ }.bind(this), 1000);
+ }.bind(this);
+ */
+};
+
+/**
+ * Renders a display Object
+ *
+ * @method renderDIsplayObject
+ * @param displayObject {DisplayObject} The DisplayObject to render
+ * @param projection {Point}
+ * @param buffer {Array} buffer TODO-Alvin
+ */
+PIXI.WebGLRenderer.prototype.renderDisplayObject = function(displayObject, projection, buffer)
+{
+ // reset the render session data..
+ this.renderSession.drawCount = 0;
+ this.renderSession.currentBlendMode = 9999;
+
+ this.renderSession.projection = projection;
+ this.renderSession.offset = this.offset;
+
+ // start the sprite batch
+ this.spriteBatch.begin(this.renderSession);
+
+ // start the filter manager
+ this.filterManager.begin(this.renderSession, buffer);
+
+ // render the scene!
+ displayObject._renderWebGL(this.renderSession);
+
+ // finish the sprite batch
+ this.spriteBatch.end();
};
/**
@@ -218,58 +294,19 @@ PIXI.WebGLRenderer.updateTextures = function()
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.texturesToUpdate.length; i++)
+ // PIXI.WebGLRenderer.updateTexture(PIXI.texturesToUpdate[i]);
+
+
+ for (i=0; i < PIXI.Texture.frameUpdates.length; i++)
+ PIXI.WebGLRenderer.updateTextureFrame(PIXI.Texture.frameUpdates[i]);
for (i = 0; i < PIXI.texturesToDestroy.length; i++)
PIXI.WebGLRenderer.destroyTexture(PIXI.texturesToDestroy[i]);
- PIXI.texturesToUpdate = [];
- PIXI.texturesToDestroy = [];
-};
-
-/**
- * Updates a loaded webgl texture
- *
- * @static
- * @method updateTexture
- * @param texture {Texture} The texture to update
- * @private
- */
-PIXI.WebGLRenderer.updateTexture = function(texture)
-{
- //TODO break this out into a texture manager...
- var gl = PIXI.gl;
-
- if(!texture._glTexture)
- {
- texture._glTexture = gl.createTexture();
- }
-
- if(texture.hasLoaded)
- {
- gl.bindTexture(gl.TEXTURE_2D, texture._glTexture);
- gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
-
- 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);
-
- // reguler...
-
- 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);
- }
+ PIXI.texturesToUpdate.length = 0;
+ PIXI.texturesToDestroy.length = 0;
+ PIXI.Texture.frameUpdates.length = 0;
};
/**
@@ -282,13 +319,35 @@ PIXI.WebGLRenderer.updateTexture = function(texture)
PIXI.WebGLRenderer.destroyTexture = function(texture)
{
//TODO break this out into a texture manager...
- var gl = PIXI.gl;
- if(texture._glTexture)
+ for (var i = texture._glTextures.length - 1; i >= 0; i--)
{
- texture._glTexture = gl.createTexture();
- gl.deleteTexture(gl.TEXTURE_2D, texture._glTexture);
+ var glTexture = texture._glTextures[i];
+ var gl = PIXI.glContexts[i];
+
+ if(gl && glTexture)
+ {
+ gl.deleteTexture(glTexture);
+ }
}
+
+ texture._glTextures.length = 0;
+};
+
+/**
+ * TODO-Alvin
+ *
+ * @method updateTextureFrame
+ * @param texture {Texture} The texture to update the frame from
+ * @private
+ */
+PIXI.WebGLRenderer.updateTextureFrame = function(texture)
+{
+ texture.updateFrame = false;
+
+ // now set the uvs. Figured that the uv data sits with a texture rather than a sprite.
+ // so uv data is stored on the texture itself
+ texture._updateWebGLuvs();
};
/**
@@ -308,18 +367,87 @@ PIXI.WebGLRenderer.prototype.resize = function(width, height)
this.gl.viewport(0, 0, this.width, this.height);
- //var projectionMatrix = this.projectionMatrix;
+ this.projection.x = this.width/2;
+ this.projection.y = -this.height/2;
+};
- PIXI.projection.x = this.width/2;
- PIXI.projection.y = -this.height/2;
+/**
+ * Creates a WebGL texture
+ *
+ * @method createWebGLTexture
+ * @param texture {Texture} the texture to render
+ * @param gl {webglContext} the WebGL context
+ * @static
+ */
+PIXI.createWebGLTexture = function(texture, gl)
+{
- //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;
+ if(texture.hasLoaded)
+ {
+ texture._glTextures[gl.id] = gl.createTexture();
+
+ gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]);
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
+
+ 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.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
+
+ // reguler...
+
+ 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);
+ }
+
+ return texture._glTextures[gl.id];
+};
+
+/**
+ * Updates a WebGL texture
+ *
+ * @method updateWebGLTexture
+ * @param texture {Texture} the texture to update
+ * @param gl {webglContext} the WebGL context
+ * @private
+ */
+PIXI.updateWebGLTexture = function(texture, gl)
+{
+ if( texture._glTextures[gl.id] )
+ {
+ gl.bindTexture(gl.TEXTURE_2D, texture._glTextures[gl.id]);
+ gl.pixelStorei(gl.UNPACK_PREMULTIPLY_ALPHA_WEBGL, true);
+
+ 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.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, texture.scaleMode === PIXI.scaleModes.LINEAR ? gl.LINEAR : gl.NEAREST);
+
+ // reguler...
+
+ 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);
+ }
+
};
/**
@@ -344,26 +472,91 @@ PIXI.WebGLRenderer.prototype.handleContextLost = function(event)
*/
PIXI.WebGLRenderer.prototype.handleContextRestored = function()
{
- this.gl = this.view.getContext('experimental-webgl', {
- alpha: true
- });
- this.initShaders();
+ //try 'experimental-webgl'
+ try {
+ this.gl = this.view.getContext('experimental-webgl', this.options);
+ } catch (e) {
+ //try 'webgl'
+ try {
+ this.gl = this.view.getContext('webgl', this.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);
+ }
+ }
+
+ var gl = this.gl;
+ gl.id = PIXI.WebGLRenderer.glContextId ++;
+
+
+
+ // need to set the context...
+ this.shaderManager.setContext(gl);
+ this.spriteBatch.setContext(gl);
+ this.maskManager.setContext(gl);
+ this.filterManager.setContext(gl);
+
+
+ this.renderSession.gl = this.gl;
+
+ gl.disable(gl.DEPTH_TEST);
+ gl.disable(gl.CULL_FACE);
+
+ gl.enable(gl.BLEND);
+ gl.colorMask(true, true, true, this.transparent);
+
+ this.gl.viewport(0, 0, this.width, this.height);
for(var key in PIXI.TextureCache)
{
var texture = PIXI.TextureCache[key].baseTexture;
- texture._glTexture = null;
- PIXI.WebGLRenderer.updateTexture(texture);
+ texture._glTextures = [];
}
- for (var i=0; i < this.batchs.length; i++)
- {
- this.batchs[i].restoreLostContext(this.gl);
- this.batchs[i].dirty = true;
- }
-
- PIXI._restoreBatchs(this.gl);
-
+ /**
+ * Whether the context was lost
+ * @property contextLost
+ * @type Boolean
+ */
this.contextLost = false;
+
};
+
+/**
+ * Destroy TODO-Alvin
+ *
+ * @method destroy
+ */
+PIXI.WebGLRenderer.prototype.destroy = function()
+{
+
+ // deal with losing context..
+
+ // remove listeners
+ this.view.removeEventListener('webglcontextlost', this.contextLost);
+ this.view.removeEventListener('webglcontextrestored', this.contextRestoredLost);
+
+ PIXI.glContexts[this.glContextId] = null;
+
+ this.projection = null;
+ this.offset = null;
+
+ // time to create the render managers! each one focuses on managine a state in webGL
+ this.shaderManager.destroy();
+ this.spriteBatch.destroy();
+ this.maskManager.destroy();
+ this.filterManager.destroy();
+
+ this.shaderManager = null;
+ this.spriteBatch = null;
+ this.maskManager = null;
+ this.filterManager = null;
+
+ this.gl = null;
+ //
+ this.renderSession = null;
+};
+
+
+PIXI.WebGLRenderer.glContextId = 0;
diff --git a/src/pixi/renderers/webgl/WebGLShaders.js b/src/pixi/renderers/webgl/WebGLShaders.js
deleted file mode 100644
index b6b66b7e..00000000
--- a/src/pixi/renderers/webgl/WebGLShaders.js
+++ /dev/null
@@ -1,117 +0,0 @@
-/**
- * @author Mat Groves http://matgroves.com/ @Doormat23
- */
-
-PIXI.initDefaultShaders = function()
-{
- PIXI.primitiveShader = new PIXI.PrimitiveShader();
- PIXI.primitiveShader.init();
-
- PIXI.stripShader = new PIXI.StripShader();
- PIXI.stripShader.init();
-
- PIXI.defaultShader = new PIXI.PixiShader();
- PIXI.defaultShader.init();
-
- 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);
-};
-
-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);
-
- gl.enableVertexAttribArray(PIXI.primitiveShader.aVertexPosition);
- gl.enableVertexAttribArray(PIXI.primitiveShader.colorAttribute);
-};
-
-PIXI.deactivatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.defaultShader.program);
-
- 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);
- // gl.disableVertexAttribArray(PIXI.defaultShader.aTextureCoord);
-};
-
-PIXI.deactivateStripShader = function()
-{
- var gl = PIXI.gl;
-
- gl.useProgram(PIXI.defaultShader.program);
- //gl.enableVertexAttribArray(PIXI.defaultShader.aTextureCoord);
-};
-
-/*
-
-SHADER COMPILER HELPERS
-*/
-
-PIXI.CompileVertexShader = function(gl, shaderSrc)
-{
- return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER);
-};
-
-PIXI.CompileFragmentShader = function(gl, shaderSrc)
-{
- 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);
-
- 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();
-
- gl.attachShader(shaderProgram, vertexShader);
- gl.attachShader(shaderProgram, fragmentShader);
- gl.linkProgram(shaderProgram);
-
- if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- window.console.log("Could not initialise shaders");
- }
-
- return shaderProgram;
-};
diff --git a/src/pixi/renderers/webgl/shaders/PixiFastShader.js b/src/pixi/renderers/webgl/shaders/PixiFastShader.js
new file mode 100644
index 00000000..94a4adeb
--- /dev/null
+++ b/src/pixi/renderers/webgl/shaders/PixiFastShader.js
@@ -0,0 +1,146 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ * @author Richard Davey http://www.photonstorm.com @photonstorm
+ */
+
+/**
+* @class PIXI.PixiFastShader
+* @constructor
+* @param gl {WebGLContext} the current WebGL drawing context
+*/
+PIXI.PixiFastShader = function(gl)
+{
+
+ /**
+ * @property gl
+ * @type WebGLContext
+ */
+ this.gl = gl;
+
+ /**
+ * @property {any} program - The WebGL 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 ;',
+ '}'
+ ];
+
+ /**
+ * @property {array} vertexSrc - The vertex shader
+ */
+ this.vertexSrc = [
+ 'attribute vec2 aVertexPosition;',
+ 'attribute vec2 aPositionCoord;',
+ 'attribute vec2 aScale;',
+ 'attribute float aRotation;',
+ 'attribute vec2 aTextureCoord;',
+ 'attribute float aColor;',
+
+ 'uniform vec2 projectionVector;',
+ 'uniform vec2 offsetVector;',
+ 'uniform mat3 uMatrix;',
+
+ 'varying vec2 vTextureCoord;',
+ 'varying float vColor;',
+
+ 'const vec2 center = vec2(-1.0, 1.0);',
+
+ 'void main(void) {',
+ ' vec2 v;',
+ ' vec2 sv = aVertexPosition * aScale;',
+ ' v.x = (sv.x) * cos(aRotation) - (sv.y) * sin(aRotation);',
+ ' v.y = (sv.x) * sin(aRotation) + (sv.y) * cos(aRotation);',
+ ' v = ( uMatrix * vec3(v + aPositionCoord , 1.0) ).xy ;',
+ ' gl_Position = vec4( ( v / projectionVector) + center , 0.0, 1.0);',
+ ' vTextureCoord = aTextureCoord;',
+ // ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;',
+ ' vColor = aColor;',
+ '}'
+ ];
+
+
+ /**
+ * @property {number} textureCount - A local texture counter for multi-texture shaders.
+ */
+ this.textureCount = 0;
+
+
+ this.init();
+};
+
+/**
+* Initialises the shader
+* @method init
+*
+*/
+PIXI.PixiFastShader.prototype.init = function()
+{
+
+ var gl = this.gl;
+
+ var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc);
+
+ 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.uMatrix = gl.getUniformLocation(program, 'uMatrix');
+
+ // get and store the attributes
+ this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
+ this.aPositionCoord = gl.getAttribLocation(program, 'aPositionCoord');
+
+ this.aScale = gl.getAttribLocation(program, 'aScale');
+ this.aRotation = gl.getAttribLocation(program, 'aRotation');
+
+ this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
+ this.colorAttribute = gl.getAttribLocation(program, 'aColor');
+
+
+
+ // Begin worst hack eva //
+
+ // WHY??? ONLY on my chrome pixel the line above returns -1 when using filters?
+ // maybe its somthing to do with the current state of the gl context.
+ // Im convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel
+ // If theres any webGL people that know why could happen please help :)
+ if(this.colorAttribute === -1)
+ {
+ this.colorAttribute = 2;
+ }
+
+ this.attributes = [this.aVertexPosition, this.aPositionCoord, this.aScale, this.aRotation, this.aTextureCoord, this.colorAttribute];
+
+ // End worst hack eva //
+
+
+ this.program = program;
+};
+
+/**
+* Destroys the shader
+* @method destroy
+*
+*/
+PIXI.PixiFastShader.prototype.destroy = function()
+{
+ this.gl.deleteProgram( this.program );
+ this.uniforms = null;
+ this.gl = null;
+
+ this.attributes = null;
+};
diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/shaders/PixiShader.js
similarity index 61%
rename from src/pixi/renderers/webgl/PixiShader.js
rename to src/pixi/renderers/webgl/shaders/PixiShader.js
index 01721c07..08ecd48d 100644
--- a/src/pixi/renderers/webgl/PixiShader.js
+++ b/src/pixi/renderers/webgl/shaders/PixiShader.js
@@ -7,8 +7,14 @@
* @class PIXI.PixiShader
* @constructor
*/
-PIXI.PixiShader = function()
+PIXI.PixiShader = function(gl)
{
+ /**
+ * @property gl
+ * @type WebGLContext
+ */
+ this.gl = gl;
+
/**
* @property {any} program - The WebGL program.
*/
@@ -20,28 +26,36 @@ PIXI.PixiShader = function()
this.fragmentSrc = [
'precision lowp float;',
'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec4 vColor;',
'uniform sampler2D uSampler;',
'void main(void) {',
- ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;',
+ ' gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor ;',
'}'
];
+
/**
* @property {number} textureCount - A local texture counter for multi-texture shaders.
*/
this.textureCount = 0;
+
+ this.attributes = [];
+
+ this.init();
};
/**
-* @method PIXI.PixiShader#init
+* Initialises the shader
+* @method init
+*
*/
PIXI.PixiShader.prototype.init = function()
{
- var program = PIXI.compileProgram(this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc);
- var gl = PIXI.gl;
+ var gl = this.gl;
+ var program = PIXI.compileProgram(gl, this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc);
+
gl.useProgram(program);
// get and store the uniforms for the shader
@@ -52,8 +66,24 @@ PIXI.PixiShader.prototype.init = function()
// get and store the attributes
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
- this.colorAttribute = gl.getAttribLocation(program, 'aColor');
this.aTextureCoord = gl.getAttribLocation(program, 'aTextureCoord');
+ this.colorAttribute = gl.getAttribLocation(program, 'aColor');
+
+
+ // Begin worst hack eva //
+
+ // WHY??? ONLY on my chrome pixel the line above returns -1 when using filters?
+ // maybe its something to do with the current state of the gl context.
+ // Im convinced this is a bug in the chrome browser as there is NO reason why this should be returning -1 especially as it only manifests on my chrome pixel
+ // If theres any webGL people that know why could happen please help :)
+ if(this.colorAttribute === -1)
+ {
+ this.colorAttribute = 2;
+ }
+
+ this.attributes = [this.aVertexPosition, this.aTextureCoord, this.colorAttribute];
+
+ // End worst hack eva //
// add those custom shaders!
for (var key in this.uniforms)
@@ -72,12 +102,12 @@ PIXI.PixiShader.prototype.init = function()
* Uniforms are specified in the GLSL_ES Specification: http://www.khronos.org/registry/webgl/specs/latest/1.0/
* http://www.khronos.org/registry/gles/specs/2.0/GLSL_ES_Specification_1.0.17.pdf
*
-* @method PIXI.PixiShader#initUniforms
+* @method initUniforms
*/
PIXI.PixiShader.prototype.initUniforms = function()
{
this.textureCount = 1;
-
+ var gl = this.gl;
var uniform;
for (var key in this.uniforms)
@@ -103,21 +133,21 @@ PIXI.PixiShader.prototype.initUniforms = function()
if (type === 'mat2')
{
- uniform.glFunc = PIXI.gl.uniformMatrix2fv;
+ uniform.glFunc = gl.uniformMatrix2fv;
}
else if (type === 'mat3')
{
- uniform.glFunc = PIXI.gl.uniformMatrix3fv;
+ uniform.glFunc = gl.uniformMatrix3fv;
}
else if (type === 'mat4')
{
- uniform.glFunc = PIXI.gl.uniformMatrix4fv;
+ uniform.glFunc = gl.uniformMatrix4fv;
}
}
else
{
// GL function reference
- uniform.glFunc = PIXI.gl['uniform' + type];
+ uniform.glFunc = gl['uniform' + type];
if (type === '2f' || type === '2i')
{
@@ -141,9 +171,9 @@ PIXI.PixiShader.prototype.initUniforms = function()
};
/**
-* Initialises a Sampler2D uniform (which may only be available later on after initUniforms once the texture is has loaded)
+* Initialises a Sampler2D uniform (which may only be available later on after initUniforms once the texture has loaded)
*
-* @method PIXI.PixiShader#initSampler2D
+* @method initSampler2D
*/
PIXI.PixiShader.prototype.initSampler2D = function(uniform)
{
@@ -152,8 +182,10 @@ PIXI.PixiShader.prototype.initSampler2D = function(uniform)
return;
}
- PIXI.gl.activeTexture(PIXI.gl['TEXTURE' + this.textureCount]);
- PIXI.gl.bindTexture(PIXI.gl.TEXTURE_2D, uniform.value.baseTexture._glTexture);
+ var gl = this.gl;
+
+ gl.activeTexture(gl['TEXTURE' + this.textureCount]);
+ gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTexture);
// Extended texture data
if (uniform.textureData)
@@ -170,19 +202,19 @@ PIXI.PixiShader.prototype.initSampler2D = function(uniform)
// magFilter can be: gl.LINEAR, gl.LINEAR_MIPMAP_LINEAR or gl.NEAREST
// wrapS/T can be: gl.CLAMP_TO_EDGE or gl.REPEAT
- var magFilter = (data.magFilter) ? data.magFilter : PIXI.gl.LINEAR;
- var minFilter = (data.minFilter) ? data.minFilter : PIXI.gl.LINEAR;
- var wrapS = (data.wrapS) ? data.wrapS : PIXI.gl.CLAMP_TO_EDGE;
- var wrapT = (data.wrapT) ? data.wrapT : PIXI.gl.CLAMP_TO_EDGE;
- var format = (data.luminance) ? PIXI.gl.LUMINANCE : PIXI.gl.RGBA;
+ var magFilter = (data.magFilter) ? data.magFilter : gl.LINEAR;
+ var minFilter = (data.minFilter) ? data.minFilter : gl.LINEAR;
+ var wrapS = (data.wrapS) ? data.wrapS : gl.CLAMP_TO_EDGE;
+ var wrapT = (data.wrapT) ? data.wrapT : gl.CLAMP_TO_EDGE;
+ var format = (data.luminance) ? gl.LUMINANCE : gl.RGBA;
if (data.repeat)
{
- wrapS = PIXI.gl.REPEAT;
- wrapT = PIXI.gl.REPEAT;
+ wrapS = gl.REPEAT;
+ wrapT = gl.REPEAT;
}
- PIXI.gl.pixelStorei(PIXI.gl.UNPACK_FLIP_Y_WEBGL, false);
+ gl.pixelStorei(gl.UNPACK_FLIP_Y_WEBGL, !!data.flipY);
if (data.width)
{
@@ -191,21 +223,21 @@ PIXI.PixiShader.prototype.initSampler2D = function(uniform)
var border = (data.border) ? data.border : 0;
// void texImage2D(GLenum target, GLint level, GLenum internalformat, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, ArrayBufferView? pixels);
- PIXI.gl.texImage2D(PIXI.gl.TEXTURE_2D, 0, format, width, height, border, format, PIXI.gl.UNSIGNED_BYTE, null);
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, width, height, border, format, gl.UNSIGNED_BYTE, null);
}
else
{
// void texImage2D(GLenum target, GLint level, GLenum internalformat, GLenum format, GLenum type, ImageData? pixels);
- PIXI.gl.texImage2D(PIXI.gl.TEXTURE_2D, 0, format, PIXI.gl.RGBA, PIXI.gl.UNSIGNED_BYTE, uniform.value.baseTexture.source);
+ gl.texImage2D(gl.TEXTURE_2D, 0, format, gl.RGBA, gl.UNSIGNED_BYTE, uniform.value.baseTexture.source);
}
- PIXI.gl.texParameteri(PIXI.gl.TEXTURE_2D, PIXI.gl.TEXTURE_MAG_FILTER, magFilter);
- PIXI.gl.texParameteri(PIXI.gl.TEXTURE_2D, PIXI.gl.TEXTURE_MIN_FILTER, minFilter);
- PIXI.gl.texParameteri(PIXI.gl.TEXTURE_2D, PIXI.gl.TEXTURE_WRAP_S, wrapS);
- PIXI.gl.texParameteri(PIXI.gl.TEXTURE_2D, PIXI.gl.TEXTURE_WRAP_T, wrapT);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MAG_FILTER, magFilter);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_MIN_FILTER, minFilter);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_S, wrapS);
+ gl.texParameteri(gl.TEXTURE_2D, gl.TEXTURE_WRAP_T, wrapT);
}
- PIXI.gl.uniform1i(uniform.uniformLocation, this.textureCount);
+ gl.uniform1i(uniform.uniformLocation, this.textureCount);
uniform._init = true;
@@ -216,12 +248,13 @@ PIXI.PixiShader.prototype.initSampler2D = function(uniform)
/**
* Updates the shader uniform values.
*
-* @method PIXI.PixiShader#syncUniforms
+* @method syncUniforms
*/
PIXI.PixiShader.prototype.syncUniforms = function()
{
this.textureCount = 1;
var uniform;
+ var gl = this.gl;
// This would probably be faster in an array and it would guarantee key order
for (var key in this.uniforms)
@@ -233,32 +266,32 @@ PIXI.PixiShader.prototype.syncUniforms = function()
{
if (uniform.glMatrix === true)
{
- uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.transpose, uniform.value);
+ uniform.glFunc.call(gl, uniform.uniformLocation, uniform.transpose, uniform.value);
}
else
{
- uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value);
+ uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value);
}
}
else if (uniform.glValueLength === 2)
{
- uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value.x, uniform.value.y);
+ uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y);
}
else if (uniform.glValueLength === 3)
{
- uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z);
+ uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z);
}
else if (uniform.glValueLength === 4)
{
- uniform.glFunc.call(PIXI.gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z, uniform.value.w);
+ uniform.glFunc.call(gl, uniform.uniformLocation, uniform.value.x, uniform.value.y, uniform.value.z, uniform.value.w);
}
else if (uniform.type === 'sampler2D')
{
if (uniform._init)
{
- PIXI.gl.activeTexture(PIXI.gl['TEXTURE' + this.textureCount]);
- PIXI.gl.bindTexture(PIXI.gl.TEXTURE_2D, uniform.value.baseTexture._glTexture);
- PIXI.gl.uniform1i(uniform.uniformLocation, this.textureCount);
+ gl.activeTexture(gl['TEXTURE' + this.textureCount]);
+ gl.bindTexture(gl.TEXTURE_2D, uniform.value.baseTexture._glTextures[gl.id] || PIXI.createWebGLTexture( uniform.value.baseTexture, gl));
+ gl.uniform1i(uniform.uniformLocation, this.textureCount);
this.textureCount++;
}
else
@@ -270,22 +303,46 @@ PIXI.PixiShader.prototype.syncUniforms = function()
};
+/**
+* Destroys the shader
+* @method destroy
+*
+*/
+PIXI.PixiShader.prototype.destroy = function()
+{
+ this.gl.deleteProgram( this.program );
+ this.uniforms = null;
+ this.gl = null;
+
+ this.attributes = null;
+};
+
+/**
+*
+* @property defaultVertexSrc
+* @type String
+*/
PIXI.PixiShader.defaultVertexSrc = [
'attribute vec2 aVertexPosition;',
'attribute vec2 aTextureCoord;',
- 'attribute float aColor;',
+ 'attribute vec2 aColor;',
'uniform vec2 projectionVector;',
'uniform vec2 offsetVector;',
- 'varying vec2 vTextureCoord;',
- 'varying float vColor;',
+ 'varying vec2 vTextureCoord;',
+ 'varying vec4 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;',
+ ' vec3 color = mod(vec3(aColor.y/65536.0, aColor.y/256.0, aColor.y), 256.0) / 256.0;',
+ ' vColor = vec4(color * aColor.x, aColor.x);',
'}'
];
+
+
+
+
diff --git a/src/pixi/renderers/webgl/PrimitiveShader.js b/src/pixi/renderers/webgl/shaders/PrimitiveShader.js
similarity index 58%
rename from src/pixi/renderers/webgl/PrimitiveShader.js
rename to src/pixi/renderers/webgl/shaders/PrimitiveShader.js
index b206e79a..c05109f3 100644
--- a/src/pixi/renderers/webgl/PrimitiveShader.js
+++ b/src/pixi/renderers/webgl/shaders/PrimitiveShader.js
@@ -2,12 +2,28 @@
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
-
-PIXI.PrimitiveShader = function()
+/**
+* @class PrimitiveShader
+* @constructor
+* @param gl {WebGLContext} the current WebGL drawing context
+*/
+PIXI.PrimitiveShader = function(gl)
{
- // the webGL program..
+ /**
+ * @property gl
+ * @type WebGLContext
+ */
+ this.gl = gl;
+
+ /**
+ * @property {any} program - The WebGL program.
+ */
this.program = null;
+ /**
+ * @property fragmentSrc
+ * @type Array
+ */
this.fragmentSrc = [
'precision mediump float;',
'varying vec4 vColor;',
@@ -17,6 +33,10 @@ PIXI.PrimitiveShader = function()
'}'
];
+ /**
+ * @property vertexSrc
+ * @type Array
+ */
this.vertexSrc = [
'attribute vec2 aVertexPosition;',
'attribute vec4 aColor;',
@@ -24,35 +44,61 @@ PIXI.PrimitiveShader = function()
'uniform vec2 projectionVector;',
'uniform vec2 offsetVector;',
'uniform float alpha;',
+ 'uniform vec3 tint;',
'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;',
+ ' vColor = aColor * vec4(tint * alpha, alpha);',
'}'
];
+
+ this.init();
};
+/**
+* Initialises the shader
+* @method init
+*
+*/
PIXI.PrimitiveShader.prototype.init = function()
{
- var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc);
- var gl = PIXI.gl;
+ var gl = this.gl;
+ var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc);
gl.useProgram(program);
// get and store the uniforms for the shader
this.projectionVector = gl.getUniformLocation(program, 'projectionVector');
this.offsetVector = gl.getUniformLocation(program, 'offsetVector');
+ this.tintColor = gl.getUniformLocation(program, 'tint');
+
// get and store the attributes
this.aVertexPosition = gl.getAttribLocation(program, 'aVertexPosition');
this.colorAttribute = gl.getAttribLocation(program, 'aColor');
+ this.attributes = [this.aVertexPosition, this.colorAttribute];
+
this.translationMatrix = gl.getUniformLocation(program, 'translationMatrix');
this.alpha = gl.getUniformLocation(program, 'alpha');
this.program = program;
};
+
+/**
+* Destroys the shader
+* @method destroy
+*
+*/
+PIXI.PrimitiveShader.prototype.destroy = function()
+{
+ this.gl.deleteProgram( this.program );
+ this.uniforms = null;
+ this.gl = null;
+
+ this.attribute = null;
+};
diff --git a/src/pixi/renderers/webgl/StripShader.js b/src/pixi/renderers/webgl/shaders/StripShader.js
similarity index 85%
rename from src/pixi/renderers/webgl/StripShader.js
rename to src/pixi/renderers/webgl/shaders/StripShader.js
index 55817b8b..ae654708 100644
--- a/src/pixi/renderers/webgl/StripShader.js
+++ b/src/pixi/renderers/webgl/shaders/StripShader.js
@@ -5,9 +5,14 @@
PIXI.StripShader = function()
{
- // the webGL program..
+ /**
+ * @property {any} program - The WebGL program.
+ */
this.program = null;
+ /**
+ * @property {array} fragmentSrc - The fragment shader.
+ */
this.fragmentSrc = [
'precision mediump float;',
'varying vec2 vTextureCoord;',
@@ -21,14 +26,17 @@ PIXI.StripShader = function()
'}'
];
+ /**
+ * @property {array} fragmentSrc - The fragment shader.
+ */
this.vertexSrc = [
'attribute vec2 aVertexPosition;',
'attribute vec2 aTextureCoord;',
'attribute float aColor;',
'uniform mat3 translationMatrix;',
'uniform vec2 projectionVector;',
- 'uniform vec2 offsetVector;',
'varying vec2 vTextureCoord;',
+ 'uniform vec2 offsetVector;',
'varying float vColor;',
'void main(void) {',
@@ -41,12 +49,17 @@ PIXI.StripShader = function()
];
};
+/**
+* Initialises the shader
+* @method init
+*
+*/
PIXI.StripShader.prototype.init = function()
{
- var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc);
var gl = PIXI.gl;
+ var program = PIXI.compileProgram(gl, this.vertexSrc, this.fragmentSrc);
gl.useProgram(program);
// get and store the uniforms for the shader
diff --git a/src/pixi/renderers/webgl/utils/FilterTexture.js b/src/pixi/renderers/webgl/utils/FilterTexture.js
new file mode 100644
index 00000000..00b3c8a3
--- /dev/null
+++ b/src/pixi/renderers/webgl/utils/FilterTexture.js
@@ -0,0 +1,84 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+/**
+* @class FilterTexture
+* @constructor
+* @param gl {WebGLContext} the current WebGL drawing context
+* @param width {Number} the horizontal range of the filter
+* @param height {Number} the vertical range of the filter
+* @private
+*/
+PIXI.FilterTexture = function(gl, width, height)
+{
+ /**
+ * @property gl
+ * @type WebGLContext
+ */
+ this.gl = gl;
+
+ // next time to create a frame buffer and texture
+ 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);
+};
+
+
+/**
+* Clears the filter texture
+* @method clear
+*/
+PIXI.FilterTexture.prototype.clear = function()
+{
+ var gl = this.gl;
+
+ gl.clearColor(0,0,0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+};
+
+/**
+ * Resizes the texture to the specified width and height
+ *
+ * @method resize
+ * @param width {Number} the new width of the texture
+ * @param height {Number} the new height of the texture
+ */
+PIXI.FilterTexture.prototype.resize = function(width, height)
+{
+ if(this.width === width && this.height === height) return;
+
+ this.width = width;
+ this.height = height;
+
+ var gl = this.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);
+
+};
+
+/**
+* Destroys the filter texture
+* @method destroy
+*/
+PIXI.FilterTexture.prototype.destroy = function()
+{
+ var gl = this.gl;
+ gl.deleteFramebuffer( this.frameBuffer );
+ gl.deleteTexture( this.texture );
+
+ this.frameBuffer = null;
+ this.texture = null;
+};
diff --git a/src/pixi/renderers/webgl/utils/WebGLFastSpriteBatch.js b/src/pixi/renderers/webgl/utils/WebGLFastSpriteBatch.js
new file mode 100644
index 00000000..f5a2e058
--- /dev/null
+++ b/src/pixi/renderers/webgl/utils/WebGLFastSpriteBatch.js
@@ -0,0 +1,351 @@
+/**
+ * @author Mat Groves
+ *
+ * Big thanks to the very clever Matt DesLauriers https://github.com/mattdesl/
+ * for creating the original pixi version!
+ *
+ * Heavily inspired by LibGDX's WebGLSpriteBatch:
+ * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/WebGLSpriteBatch.java
+ */
+
+PIXI.WebGLFastSpriteBatch = function(gl)
+{
+
+
+ this.vertSize = 10;
+ this.maxSize = 6000;//Math.pow(2, 16) / this.vertSize;
+ this.size = this.maxSize;
+
+ // console.log(this.size);
+ //the total number of floats in our batch
+ var numVerts = this.size * 4 * this.vertSize;
+ //the total number of indices in our batch
+ var numIndices = this.maxSize * 6;
+
+ //vertex data
+ this.vertices = new Float32Array(numVerts);
+ //index data
+ this.indices = new Uint16Array(numIndices);
+
+ this.vertexBuffer = null;
+ this.indexBuffer = null;
+
+ this.lastIndexCount = 0;
+
+ for (var i=0, j=0; i < numIndices; i += 6, j += 4)
+ {
+ this.indices[i + 0] = j + 0;
+ this.indices[i + 1] = j + 1;
+ this.indices[i + 2] = j + 2;
+ this.indices[i + 3] = j + 0;
+ this.indices[i + 4] = j + 2;
+ this.indices[i + 5] = j + 3;
+ }
+
+ this.drawing = false;
+ this.currentBatchSize = 0;
+ this.currentBaseTexture = null;
+
+ this.currentBlendMode = 0;
+ this.renderSession = null;
+
+
+ this.shader = null;
+
+ this.matrix = null;
+
+ this.setContext(gl);
+};
+
+PIXI.WebGLFastSpriteBatch.prototype.setContext = function(gl)
+{
+ this.gl = gl;
+
+ // create a couple of buffers
+ this.vertexBuffer = gl.createBuffer();
+ this.indexBuffer = gl.createBuffer();
+
+ // 65535 is max index, so 65535 / 6 = 10922.
+
+
+ //upload the index data
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);
+
+ this.currentBlendMode = 99999;
+};
+
+PIXI.WebGLFastSpriteBatch.prototype.begin = function(spriteBatch, renderSession)
+{
+ this.renderSession = renderSession;
+ this.shader = this.renderSession.shaderManager.fastShader;
+
+ this.matrix = spriteBatch.worldTransform.toArray(true);
+
+ // console.log(this.tempMatrix)
+ this.start();
+};
+
+PIXI.WebGLFastSpriteBatch.prototype.end = function()
+{
+ this.flush();
+};
+
+
+PIXI.WebGLFastSpriteBatch.prototype.render = function(spriteBatch)
+{
+
+ var children = spriteBatch.children;
+ var sprite = children[0];
+
+ // if the uvs have not updated then no point rendering just yet!
+
+ // check texture.
+ if(!sprite.texture._uvs)return;
+
+ this.currentBaseTexture = sprite.texture.baseTexture;
+ // check blend mode
+ if(sprite.blendMode !== this.currentBlendMode)
+ {
+ this.setBlendMode(sprite.blendMode);
+ }
+
+ for(var i=0,j= children.length; i= this.size)
+ {
+ this.flush();
+ }
+};
+
+PIXI.WebGLFastSpriteBatch.prototype.flush = function()
+{
+
+ // If the batch is length 0 then return as there is nothing to draw
+ if (this.currentBatchSize===0)return;
+
+ var gl = this.gl;
+
+ // bind the current texture
+
+ if(!this.currentBaseTexture._glTextures[gl.id])PIXI.createWebGLTexture(this.currentBaseTexture, gl);
+
+ gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture._glTextures[gl.id]);// || PIXI.createWebGLTexture(this.currentBaseTexture, gl));
+
+ // upload the verts to the buffer
+
+
+ if(this.currentBatchSize > ( this.size * 0.5 ) )
+ {
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);
+ }
+ else
+ {
+ var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize);
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, view);
+ }
+
+
+ // now draw those suckas!
+ gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0);
+
+ // then reset the batch!
+ this.currentBatchSize = 0;
+
+ // increment the draw count
+ this.renderSession.drawCount++;
+};
+
+
+PIXI.WebGLFastSpriteBatch.prototype.stop = function()
+{
+ this.flush();
+};
+
+PIXI.WebGLFastSpriteBatch.prototype.start = function()
+{
+ var gl = this.gl;
+
+ // bind the main texture
+ gl.activeTexture(gl.TEXTURE0);
+
+ // bind the buffers
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
+
+ // set the projection
+ var projection = this.renderSession.projection;
+ gl.uniform2f(this.shader.projectionVector, projection.x, projection.y);
+
+ // set the matrix
+ gl.uniformMatrix3fv(this.shader.uMatrix, false, this.matrix);
+
+ // set the pointers
+ var stride = this.vertSize * 4;
+
+ gl.vertexAttribPointer(this.shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0);
+ gl.vertexAttribPointer(this.shader.aPositionCoord, 2, gl.FLOAT, false, stride, 2 * 4);
+ gl.vertexAttribPointer(this.shader.aScale, 2, gl.FLOAT, false, stride, 4 * 4);
+ gl.vertexAttribPointer(this.shader.aRotation, 1, gl.FLOAT, false, stride, 6 * 4);
+ gl.vertexAttribPointer(this.shader.aTextureCoord, 2, gl.FLOAT, false, stride, 7 * 4);
+ gl.vertexAttribPointer(this.shader.colorAttribute, 1, gl.FLOAT, false, stride, 9 * 4);
+
+ // set the blend mode..
+ if(this.currentBlendMode !== PIXI.blendModes.NORMAL)
+ {
+ this.setBlendMode(PIXI.blendModes.NORMAL);
+ }
+};
+
+PIXI.WebGLFastSpriteBatch.prototype.setBlendMode = function(blendMode)
+{
+ this.flush();
+
+ this.currentBlendMode = blendMode;
+
+ var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode];
+ this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
+};
+
+
diff --git a/src/pixi/renderers/webgl/WebGLFilterManager.js b/src/pixi/renderers/webgl/utils/WebGLFilterManager.js
similarity index 62%
rename from src/pixi/renderers/webgl/WebGLFilterManager.js
rename to src/pixi/renderers/webgl/utils/WebGLFilterManager.js
index 873b56c6..dd1303f4 100644
--- a/src/pixi/renderers/webgl/WebGLFilterManager.js
+++ b/src/pixi/renderers/webgl/utils/WebGLFilterManager.js
@@ -2,32 +2,69 @@
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
-
-PIXI.WebGLFilterManager = function(transparent)
+/**
+* @class WebGLFilterManager
+* @constructor
+* @param gl {WebGLContext} the current WebGL drawing context
+* @param transparent {Boolean} Whether or not the drawing context should be transparent
+* @private
+*/
+PIXI.WebGLFilterManager = function(gl, transparent)
{
this.transparent = transparent;
this.filterStack = [];
- this.texturePool = [];
-
+
this.offsetX = 0;
this.offsetY = 0;
+ this.setContext(gl);
+};
+
+// API
+/**
+* Initialises the context and the properties
+* @method setContext
+* @param gl {WebGLContext} the current WebGL drawing context
+*/
+PIXI.WebGLFilterManager.prototype.setContext = function(gl)
+{
+ this.gl = gl;
+ this.texturePool = [];
+
this.initShaderBuffers();
};
-// API
-
-PIXI.WebGLFilterManager.prototype.begin = function(projection, buffer)
+/**
+*
+* @method begin
+* @param renderSession {RenderSession}
+* @param buffer {ArrayBuffer}
+*/
+PIXI.WebGLFilterManager.prototype.begin = function(renderSession, buffer)
{
+ this.renderSession = renderSession;
+ this.defaultShader = renderSession.shaderManager.defaultShader;
+
+ var projection = this.renderSession.projection;
+
this.width = projection.x * 2;
this.height = -projection.y * 2;
this.buffer = buffer;
};
+/**
+* Applies the filter and adds it to the current filter stack
+* @method pushFilter
+* @param filterBlock {Object} TODO-Alvin
+*/
PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
{
- var gl = PIXI.gl;
+ var gl = this.gl;
+
+ var projection = this.renderSession.projection;
+ var offset = this.renderSession.offset;
+
// filter program
// OPTIMISATION - the first filter is free if its a simple color change?
@@ -41,7 +78,7 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
var texture = this.texturePool.pop();
if(!texture)
{
- texture = new PIXI.FilterTexture(this.width, this.height);
+ texture = new PIXI.FilterTexture(this.gl, this.width, this.height);
}
else
{
@@ -50,7 +87,13 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
gl.bindTexture(gl.TEXTURE_2D, texture.texture);
- this.getBounds(filterBlock.target);
+// this.getBounds(filterBlock.target);
+
+ filterBlock.target.filterArea = filterBlock.target.getBounds();
+ // console.log(filterBlock.target.filterArea)
+ // console.log(filterBlock.target.filterArea);
+ // addpadding?
+ //displayObject.filterArea.x
var filterArea = filterBlock.target.filterArea;
@@ -69,34 +112,45 @@ PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
//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;
+ projection.x = filterArea.width/2;
+ projection.y = -filterArea.height/2;
- PIXI.offset.x = -filterArea.x;
- PIXI.offset.y = -filterArea.y;
+ offset.x = -filterArea.x;
+ offset.y = -filterArea.y;
+ //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);
+ gl.uniform2f(this.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2);
+ gl.uniform2f(this.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);
+ //filter.texture = texture;
filterBlock._glFilterTexture = texture;
+
+ //console.log("PUSH")
};
+/**
+* Removes the last filter from the filter stack and doesn't return it
+* @method popFilter
+*/
PIXI.WebGLFilterManager.prototype.popFilter = function()
{
- var gl = PIXI.gl;
+ var gl = this.gl;
var filterBlock = this.filterStack.pop();
var filterArea = filterBlock.target.filterArea;
var texture = filterBlock._glFilterTexture;
+ var projection = this.renderSession.projection;
+ var offset = this.renderSession.offset;
if(filterBlock.filterPasses.length > 1)
{
@@ -119,7 +173,7 @@ PIXI.WebGLFilterManager.prototype.popFilter = function()
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray);
gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
- // nnow set the uvs..
+ // now set the uvs..
this.uvArray[2] = filterArea.width/this.width;
this.uvArray[5] = filterArea.height/this.height;
this.uvArray[6] = filterArea.width/this.width;
@@ -129,9 +183,9 @@ PIXI.WebGLFilterManager.prototype.popFilter = function()
var inputTexture = texture;
var outputTexture = this.texturePool.pop();
- if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.width, this.height);
+ if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.gl, this.width, this.height);
- // need to clear this FBO as it may have some left over elements from a prvious filter.
+ // need to clear this FBO as it may have some left over elements from a previous filter.
gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer );
gl.clear(gl.COLOR_BUFFER_BIT);
@@ -199,11 +253,11 @@ PIXI.WebGLFilterManager.prototype.popFilter = function()
// TODO need toremove thease global elements..
- PIXI.projection.x = sizeX/2;
- PIXI.projection.y = -sizeY/2;
+ projection.x = sizeX/2;
+ projection.y = -sizeY/2;
- PIXI.offset.x = offsetX;
- PIXI.offset.y = offsetY;
+ offset.x = offsetX;
+ offset.y = offsetY;
filterArea = filterBlock.target.filterArea;
@@ -241,6 +295,9 @@ PIXI.WebGLFilterManager.prototype.popFilter = function()
// bind the buffer
gl.bindFramebuffer(gl.FRAMEBUFFER, buffer );
+ // set the blend mode!
+ //gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA)
+
// set texture
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, texture.texture);
@@ -250,30 +307,39 @@ PIXI.WebGLFilterManager.prototype.popFilter = function()
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.useProgram(this.defaultShader.program);
+ gl.uniform2f(this.defaultShader.projectionVector, sizeX/2, -sizeY/2);
+ gl.uniform2f(this.defaultShader.offsetVector, -offsetX, -offsetY);
// return the texture to the pool
this.texturePool.push(texture);
filterBlock._glFilterTexture = null;
};
+
+/**
+* Applies the filter to the specified area
+* @method applyFilterPass
+* @param filter {AbstractFilter} the filter that needs to be applied
+* @param filterArea {texture} TODO - might need an update
+* @param width {Number} the horizontal range of the filter
+* @param height {Number} the vertical range of the filter
+*/
PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea, width, height)
{
// use program
- var gl = PIXI.gl;
- var shader = filter.shader;
+ var gl = this.gl;
+ var shader = filter.shaders[gl.id];
if(!shader)
{
- shader = new PIXI.PixiShader();
+ shader = new PIXI.PixiShader(gl);
shader.fragmentSrc = filter.fragmentSrc;
shader.uniforms = filter.uniforms;
shader.init();
- filter.shader = shader;
+ filter.shaders[gl.id] = shader;
}
// set the shader
@@ -284,10 +350,12 @@ PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea,
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])
}
shader.syncUniforms();
@@ -298,23 +366,34 @@ PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea,
gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
gl.vertexAttribPointer(shader.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
+ gl.vertexAttribPointer(shader.colorAttribute, 2, gl.FLOAT, false, 0, 0);
+
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
// draw the filter...
gl.drawElements(gl.TRIANGLES, 6, gl.UNSIGNED_SHORT, 0 );
+
+ this.renderSession.drawCount++;
};
+/**
+* Initialises the shader buffers
+* @method initShaderBuffers
+*/
PIXI.WebGLFilterManager.prototype.initShaderBuffers = function()
{
- var gl = PIXI.gl;
+ var gl = this.gl;
// create some buffers
this.vertexBuffer = gl.createBuffer();
this.uvBuffer = gl.createBuffer();
+ this.colorBuffer = gl.createBuffer();
this.indexBuffer = gl.createBuffer();
+
// bind and upload the vertexs..
- // keep a refferance to the vertexFloatData..
+ // keep a reference to the vertexFloatData..
this.vertexArray = new Float32Array([0.0, 0.0,
1.0, 0.0,
0.0, 1.0,
@@ -339,6 +418,17 @@ PIXI.WebGLFilterManager.prototype.initShaderBuffers = function()
this.uvArray,
gl.STATIC_DRAW);
+ this.colorArray = new Float32Array([1.0, 0xFFFFFF,
+ 1.0, 0xFFFFFF,
+ 1.0, 0xFFFFFF,
+ 1.0, 0xFFFFFF]);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.colorBuffer);
+ gl.bufferData(
+ gl.ARRAY_BUFFER,
+ this.colorArray,
+ gl.STATIC_DRAW);
+
// bind and upload the index
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
gl.bufferData(
@@ -347,150 +437,29 @@ PIXI.WebGLFilterManager.prototype.initShaderBuffers = function()
gl.STATIC_DRAW);
};
-PIXI.WebGLFilterManager.prototype.getBounds = function(displayObject)
+/**
+* TODO-Alvin
+* @method destroy
+*/
+PIXI.WebGLFilterManager.prototype.destroy = function()
{
- // 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 gl = this.gl;
- 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;
-
- // TODO trim??
- aX = tempObject.anchor.x;
- aY = tempObject.anchor.y;
- w0 = width * (1-aX);
- w1 = width * -aX;
-
- h0 = height * (1-aY);
- h1 = height * -aY;
-
- doTest = true;
- }
- else if(tempObject instanceof PIXI.Graphics)
- {
- tempObject.updateFilterBounds();
-
- var bounds = tempObject.bounds;
-
- width = bounds.width;
- height = bounds.height;
-
- w0 = bounds.x;
- w1 = bounds.x + bounds.width;
-
- h0 = bounds.y;
- h1 = bounds.y + bounds.height;
-
- doTest = true;
- }
- }
-
- if(doTest)
- {
- worldTransform = tempObject.worldTransform;
-
- a = worldTransform[0];
- b = worldTransform[3];
- c = worldTransform[1];
- d = worldTransform[4];
- tx = worldTransform[2];
- ty = worldTransform[5];
-
- x1 = a * w1 + c * h1 + tx;
- y1 = d * h1 + b * w1 + ty;
-
- x2 = a * w0 + c * h1 + tx;
- y2 = d * h1 + b * w0 + ty;
-
- x3 = a * w0 + c * h0 + tx;
- y3 = d * h0 + b * w0 + ty;
-
- 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;
+ this.filterStack = null;
+
+ this.offsetX = 0;
+ this.offsetY = 0;
+ // destroy textures
+ for (var i = 0; i < this.texturePool.length; i++) {
+ this.texturePool.destroy();
}
- while(tempObject !== testObject);
+
+ this.texturePool = null;
- 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;
-
- // next time to create a frame buffer and texture
- 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);
-};
-
-PIXI.FilterTexture.prototype.resize = function(width, height)
-{
- if(this.width === width && this.height === height) return;
-
- 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);
-
-};
+ //destroy buffers..
+ gl.deleteBuffer(this.vertexBuffer);
+ gl.deleteBuffer(this.uvBuffer);
+ gl.deleteBuffer(this.colorBuffer);
+ gl.deleteBuffer(this.indexBuffer);
+};
\ No newline at end of file
diff --git a/src/pixi/renderers/webgl/WebGLGraphics.js b/src/pixi/renderers/webgl/utils/WebGLGraphics.js
similarity index 77%
rename from src/pixi/renderers/webgl/WebGLGraphics.js
rename to src/pixi/renderers/webgl/utils/WebGLGraphics.js
index bb90529d..06f1be12 100644
--- a/src/pixi/renderers/webgl/WebGLGraphics.js
+++ b/src/pixi/renderers/webgl/utils/WebGLGraphics.js
@@ -5,7 +5,9 @@
/**
* A set of functions used by the webGL renderer to draw the primitive graphics data
*
- * @class CanvasGraphics
+ * @class WebGLGraphics
+ * @private
+ * @static
*/
PIXI.WebGLGraphics = function()
{
@@ -19,16 +21,21 @@ PIXI.WebGLGraphics = function()
* @private
* @method renderGraphics
* @param graphics {Graphics}
- * @param projection {Object}
+ * @param renderSession {Object}
*/
-PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
+PIXI.WebGLGraphics.renderGraphics = function(graphics, renderSession)//projection, offset)
{
- var gl = PIXI.gl;
+ var gl = renderSession.gl;
+ var projection = renderSession.projection,
+ offset = renderSession.offset,
+ shader = renderSession.shaderManager.primitiveShader;
- if(!graphics._webGL)graphics._webGL = {points:[], indices:[], lastIndex:0,
+ if(!graphics._webGL[gl.id])graphics._webGL[gl.id] = {points:[], indices:[], lastIndex:0,
buffer:gl.createBuffer(),
indexBuffer:gl.createBuffer()};
+ var webGL = graphics._webGL[gl.id];
+
if(graphics.dirty)
{
graphics.dirty = false;
@@ -37,43 +44,41 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
{
graphics.clearDirty = false;
- graphics._webGL.lastIndex = 0;
- graphics._webGL.points = [];
- graphics._webGL.indices = [];
+ webGL.lastIndex = 0;
+ webGL.points = [];
+ webGL.indices = [];
}
- PIXI.WebGLGraphics.updateGraphics(graphics);
+ PIXI.WebGLGraphics.updateGraphics(graphics, gl);
}
- PIXI.activatePrimitiveShader();
+ renderSession.shaderManager.activatePrimitiveShader();
- // This could be speeded up fo sure!
- var m = PIXI.mat3.clone(graphics.worldTransform);
+ // This could be speeded up for sure!
- PIXI.mat3.transpose(m);
-
- // set the matrix transform for the
+ // set the matrix transform
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
- gl.uniformMatrix3fv(PIXI.primitiveShader.translationMatrix, false, m);
+ gl.uniformMatrix3fv(shader.translationMatrix, false, graphics.worldTransform.toArray(true));
- gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y);
- gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y);
+ gl.uniform2f(shader.projectionVector, projection.x, -projection.y);
+ gl.uniform2f(shader.offsetVector, -offset.x, -offset.y);
- gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha);
- gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
+ gl.uniform3fv(shader.tintColor, PIXI.hex2rgb(graphics.tint));
- 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);
+ gl.uniform1f(shader.alpha, graphics.worldAlpha);
+ gl.bindBuffer(gl.ARRAY_BUFFER, webGL.buffer);
+
+ gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0);
+ gl.vertexAttribPointer(shader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4);
// set the index buffer!
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGL.indexBuffer);
+ gl.drawElements(gl.TRIANGLE_STRIP, webGL.indices.length, gl.UNSIGNED_SHORT, 0 );
- gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 );
-
- PIXI.deactivatePrimitiveShader();
+ renderSession.shaderManager.deactivatePrimitiveShader();
// return to default shader...
// PIXI.activateShader(PIXI.defaultShader);
@@ -85,11 +90,14 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
* @static
* @private
* @method updateGraphics
- * @param graphics {Graphics}
+ * @param graphicsData {Graphics} The graphics object to update
+ * @param gl {WebGLContext} the current WebGL drawing context
*/
-PIXI.WebGLGraphics.updateGraphics = function(graphics)
+PIXI.WebGLGraphics.updateGraphics = function(graphics, gl)
{
- for (var i = graphics._webGL.lastIndex; i < graphics.graphicsData.length; i++)
+ var webGL = graphics._webGL[gl.id];
+
+ for (var i = webGL.lastIndex; i < graphics.graphicsData.length; i++)
{
var data = graphics.graphicsData[i];
@@ -98,37 +106,37 @@ PIXI.WebGLGraphics.updateGraphics = function(graphics)
if(data.fill)
{
if(data.points.length>3)
- PIXI.WebGLGraphics.buildPoly(data, graphics._webGL);
+ PIXI.WebGLGraphics.buildPoly(data, webGL);
}
if(data.lineWidth > 0)
{
- PIXI.WebGLGraphics.buildLine(data, graphics._webGL);
+ PIXI.WebGLGraphics.buildLine(data, webGL);
}
}
else if(data.type === PIXI.Graphics.RECT)
{
- PIXI.WebGLGraphics.buildRectangle(data, graphics._webGL);
+ PIXI.WebGLGraphics.buildRectangle(data, webGL);
}
else if(data.type === PIXI.Graphics.CIRC || data.type === PIXI.Graphics.ELIP)
{
- PIXI.WebGLGraphics.buildCircle(data, graphics._webGL);
+ PIXI.WebGLGraphics.buildCircle(data, webGL);
}
}
- graphics._webGL.lastIndex = graphics.graphicsData.length;
+ webGL.lastIndex = graphics.graphicsData.length;
- var gl = PIXI.gl;
+
- graphics._webGL.glPoints = new Float32Array(graphics._webGL.points);
+ webGL.glPoints = new Float32Array(webGL.points);
- gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
- gl.bufferData(gl.ARRAY_BUFFER, graphics._webGL.glPoints, gl.STATIC_DRAW);
+ gl.bindBuffer(gl.ARRAY_BUFFER, webGL.buffer);
+ gl.bufferData(gl.ARRAY_BUFFER, webGL.glPoints, gl.STATIC_DRAW);
- graphics._webGL.glIndicies = new Uint16Array(graphics._webGL.indices);
+ webGL.glIndicies = new Uint16Array(webGL.indices);
- gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer);
- gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.glIndicies, gl.STATIC_DRAW);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, webGL.indexBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, webGL.glIndicies, gl.STATIC_DRAW);
};
/**
@@ -137,7 +145,7 @@ PIXI.WebGLGraphics.updateGraphics = function(graphics)
* @static
* @private
* @method buildRectangle
- * @param graphics {Graphics}
+ * @param graphicsData {Graphics} The graphics object to draw TODO-Alvin
* @param webGLData {Object}
*/
PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData)
@@ -185,13 +193,18 @@ PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData)
if(graphicsData.lineWidth)
{
+ var tempPoints = graphicsData.points;
+
graphicsData.points = [x, y,
x + width, y,
x + width, y + height,
x, y + height,
x, y];
+
PIXI.WebGLGraphics.buildLine(graphicsData, webGLData);
+
+ graphicsData.points = tempPoints;
}
};
@@ -201,7 +214,7 @@ PIXI.WebGLGraphics.buildRectangle = function(graphicsData, webGLData)
* @static
* @private
* @method buildCircle
- * @param graphics {Graphics}
+ * @param graphicsData {Graphics} The graphics object to draw
* @param webGLData {Object}
*/
PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData)
@@ -252,6 +265,8 @@ PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData)
if(graphicsData.lineWidth)
{
+ var tempPoints = graphicsData.points;
+
graphicsData.points = [];
for (i = 0; i < totalSegs + 1; i++)
@@ -261,6 +276,8 @@ PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData)
}
PIXI.WebGLGraphics.buildLine(graphicsData, webGLData);
+
+ graphicsData.points = tempPoints;
}
};
@@ -270,7 +287,7 @@ PIXI.WebGLGraphics.buildCircle = function(graphicsData, webGLData)
* @static
* @private
* @method buildLine
- * @param graphics {Graphics}
+ * @param graphicsData {Graphics} The graphics object to draw TODO-Alvin
* @param webGLData {Object}
*/
PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
@@ -293,7 +310,7 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
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 the first point is the last point - gonna have issues :)
if(firstPoint.x === lastPoint.x && firstPoint.y === lastPoint.y)
{
points.pop();
@@ -480,7 +497,7 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
* @static
* @private
* @method buildPoly
- * @param graphics {Graphics}
+ * @param graphicsData {Graphics} The graphics object to draw TODO-Alvin
* @param webGLData {Object}
*/
PIXI.WebGLGraphics.buildPoly = function(graphicsData, webGLData)
diff --git a/src/pixi/renderers/webgl/utils/WebGLMaskManager.js b/src/pixi/renderers/webgl/utils/WebGLMaskManager.js
new file mode 100644
index 00000000..12a78494
--- /dev/null
+++ b/src/pixi/renderers/webgl/utils/WebGLMaskManager.js
@@ -0,0 +1,97 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+/**
+* @class WebGLMaskManager
+* @constructor
+* @param gl {WebGLContext} the current WebGL drawing context
+* @private
+*/
+PIXI.WebGLMaskManager = function(gl)
+{
+ this.maskStack = [];
+ this.maskPosition = 0;
+
+ this.setContext(gl);
+};
+
+/**
+* Sets the drawing context to the one given in parameter
+* @method setContext
+* @param gl {WebGLContext} the current WebGL drawing context
+*/
+PIXI.WebGLMaskManager.prototype.setContext = function(gl)
+{
+ this.gl = gl;
+};
+
+/**
+* Applies the Mask and adds it to the current filter stack
+* @method pushMask
+* @param maskData {Array}
+* @param renderSession {RenderSession}
+*/
+PIXI.WebGLMaskManager.prototype.pushMask = function(maskData, renderSession)
+{
+ var gl = this.gl;
+
+ if(this.maskStack.length === 0)
+ {
+ gl.enable(gl.STENCIL_TEST);
+ gl.stencilFunc(gl.ALWAYS,1,1);
+ }
+
+ // maskData.visible = false;
+
+ this.maskStack.push(maskData);
+
+ gl.colorMask(false, false, false, true);
+ gl.stencilOp(gl.KEEP,gl.KEEP,gl.INCR);
+
+ PIXI.WebGLGraphics.renderGraphics(maskData, renderSession);
+
+ gl.colorMask(true, true, true, true);
+ gl.stencilFunc(gl.NOTEQUAL,0, this.maskStack.length);
+ gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
+};
+
+/**
+* Removes the last filter from the filter stack and doesn't return it
+* @method popMask
+*
+* @param renderSession {RenderSession} TODO-Alvin
+*/
+PIXI.WebGLMaskManager.prototype.popMask = function(renderSession)
+{
+ var gl = this.gl;
+
+ var maskData = this.maskStack.pop();
+
+ if(maskData)
+ {
+ gl.colorMask(false, false, false, false);
+
+ //gl.stencilFunc(gl.ALWAYS,1,1);
+ gl.stencilOp(gl.KEEP,gl.KEEP,gl.DECR);
+
+ PIXI.WebGLGraphics.renderGraphics(maskData, renderSession);
+
+ gl.colorMask(true, true, true, true);
+ gl.stencilFunc(gl.NOTEQUAL,0,this.maskStack.length);
+ gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
+ }
+
+ if(this.maskStack.length === 0)gl.disable(gl.STENCIL_TEST);
+};
+
+/**
+* TODO-Alvin
+* @method destroy
+*/
+PIXI.WebGLMaskManager.prototype.destroy = function()
+{
+ this.maskStack = null;
+ this.gl = null;
+};
\ No newline at end of file
diff --git a/src/pixi/renderers/webgl/utils/WebGLShaderManager.js b/src/pixi/renderers/webgl/utils/WebGLShaderManager.js
new file mode 100644
index 00000000..17e5937f
--- /dev/null
+++ b/src/pixi/renderers/webgl/utils/WebGLShaderManager.js
@@ -0,0 +1,161 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+/**
+* @class WebGLShaderManager
+* @constructor
+* @param gl {WebGLContext} the current WebGL drawing context
+* @private
+*/
+PIXI.WebGLShaderManager = function(gl)
+{
+
+ this.maxAttibs = 10;
+ this.attribState = [];
+ this.tempAttribState = [];
+
+ for (var i = 0; i < this.maxAttibs; i++) {
+ this.attribState[i] = false;
+ }
+
+ this.setContext(gl);
+ // the final one is used for the rendering strips
+ //this.stripShader = new PIXI.StripShader(gl);
+};
+
+
+/**
+* Initialises the context and the properties
+* @method setContext
+* @param gl {WebGLContext} the current WebGL drawing context
+* @param transparent {Boolean} Whether or not the drawing context should be transparent
+*/
+PIXI.WebGLShaderManager.prototype.setContext = function(gl)
+{
+ this.gl = gl;
+
+ // the next one is used for rendering primatives
+ this.primitiveShader = new PIXI.PrimitiveShader(gl);
+
+ // this shader is used for the default sprite rendering
+ this.defaultShader = new PIXI.PixiShader(gl);
+
+ // this shader is used for the fast sprite rendering
+ this.fastShader = new PIXI.PixiFastShader(gl);
+
+
+ this.activateShader(this.defaultShader);
+};
+
+
+/**
+* Initialises the context and the properties
+* @method setAttribs
+* @param attribs {Array} TODO-Alvin
+*/
+PIXI.WebGLShaderManager.prototype.setAttribs = function(attribs)
+{
+ // reset temp state
+
+ var i;
+
+ for (i = 0; i < this.tempAttribState.length; i++)
+ {
+ this.tempAttribState[i] = false;
+ }
+
+ // set the new attribs
+ for (i = 0; i < attribs.length; i++)
+ {
+ var attribId = attribs[i];
+ this.tempAttribState[attribId] = true;
+ }
+
+ var gl = this.gl;
+
+ for (i = 0; i < this.attribState.length; i++)
+ {
+
+ if(this.attribState[i] !== this.tempAttribState[i])
+ {
+ this.attribState[i] = this.tempAttribState[i];
+
+ if(this.tempAttribState[i])
+ {
+ gl.enableVertexAttribArray(i);
+ }
+ else
+ {
+ gl.disableVertexAttribArray(i);
+ }
+ }
+ }
+
+ // console.log(this.tempAttribState)
+};
+
+/**
+* TODO-Alvin
+* @method activateShader
+* @param shader {Object} the shader that is going to be activated
+*/
+PIXI.WebGLShaderManager.prototype.activateShader = function(shader)
+{
+ //if(this.currentShader == shader)return;
+
+ this.currentShader = shader;
+ // console.log(shader.program)
+ this.gl.useProgram(shader.program);
+ this.setAttribs(shader.attributes);
+
+ // console.log(shader.attributes)
+
+};
+
+/**
+* Triggers the primitive shader
+* @method activatePrimitiveShader
+*/
+PIXI.WebGLShaderManager.prototype.activatePrimitiveShader = function()
+{
+ var gl = this.gl;
+
+ gl.useProgram(this.primitiveShader.program);
+
+ this.setAttribs(this.primitiveShader.attributes);
+
+};
+
+/**
+* Disable the primitive shader
+* @method deactivatePrimitiveShader
+*/
+PIXI.WebGLShaderManager.prototype.deactivatePrimitiveShader = function()
+{
+ var gl = this.gl;
+
+ gl.useProgram(this.defaultShader.program);
+
+ this.setAttribs(this.defaultShader.attributes);
+};
+
+/**
+* Destroys
+* @method destroy
+*/
+PIXI.WebGLShaderManager.prototype.destroy = function()
+{
+ this.attribState = null;
+
+ this.tempAttribState = null;
+
+ this.primitiveShader.destroy();
+
+ this.defaultShader.destroy();
+
+ this.fastShader.destroy();
+
+ this.gl = null;
+};
+
diff --git a/src/pixi/renderers/webgl/utils/WebGLShaderUtils.js b/src/pixi/renderers/webgl/utils/WebGLShaderUtils.js
new file mode 100644
index 00000000..a9a7f338
--- /dev/null
+++ b/src/pixi/renderers/webgl/utils/WebGLShaderUtils.js
@@ -0,0 +1,55 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+PIXI.initDefaultShaders = function()
+{
+
+ // PIXI.stripShader = new PIXI.StripShader();
+// PIXI.stripShader.init();
+
+};
+
+PIXI.CompileVertexShader = function(gl, shaderSrc)
+{
+ return PIXI._CompileShader(gl, shaderSrc, gl.VERTEX_SHADER);
+};
+
+PIXI.CompileFragmentShader = function(gl, shaderSrc)
+{
+ 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);
+
+ if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
+ window.console.log(gl.getShaderInfoLog(shader));
+ return null;
+ }
+
+ return shader;
+};
+
+PIXI.compileProgram = function(gl, vertexSrc, fragmentSrc)
+{
+ //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)) {
+ window.console.log("Could not initialise shaders");
+ }
+
+ return shaderProgram;
+};
diff --git a/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js b/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js
new file mode 100644
index 00000000..8958a98e
--- /dev/null
+++ b/src/pixi/renderers/webgl/utils/WebGLSpriteBatch.js
@@ -0,0 +1,496 @@
+/**
+ * @author Mat Groves
+ *
+ * Big thanks to the very clever Matt DesLauriers https://github.com/mattdesl/
+ * for creating the original pixi version!
+ *
+ * Heavily inspired by LibGDX's WebGLSpriteBatch:
+ * https://github.com/libgdx/libgdx/blob/master/gdx/src/com/badlogic/gdx/graphics/g2d/WebGLSpriteBatch.java
+ */
+
+ /**
+ *
+ * @class WebGLSpriteBatch
+ * @private
+ * @constructor
+ * @param gl {WebGLContext} the current WebGL drawing context
+ *
+ */
+PIXI.WebGLSpriteBatch = function(gl)
+{
+
+ /**
+ * TODO-Alvin
+ *
+ * @property vertSize
+ * @type Number
+ */
+ this.vertSize = 6;
+
+ /**
+ * TODO-Alvin
+ * @property size
+ * @type Number
+ */
+ this.size = 10000;//Math.pow(2, 16) / this.vertSize;
+
+ // console.log(this.size);
+ //the total number of floats in our batch
+ var numVerts = this.size * 4 * this.vertSize;
+ //the total number of indices in our batch
+ var numIndices = this.size * 6;
+
+ //vertex data
+
+ /**
+ * Holds the vertices
+ *
+ * @property vertices
+ * @type Float32Array
+ */
+ this.vertices = new Float32Array(numVerts);
+
+ //index data
+ /**
+ * Holds the indices
+ *
+ * @property indices
+ * @type Uint16Array
+ */
+ this.indices = new Uint16Array(numIndices);
+
+ this.lastIndexCount = 0;
+
+ for (var i=0, j=0; i < numIndices; i += 6, j += 4)
+ {
+ this.indices[i + 0] = j + 0;
+ this.indices[i + 1] = j + 1;
+ this.indices[i + 2] = j + 2;
+ this.indices[i + 3] = j + 0;
+ this.indices[i + 4] = j + 2;
+ this.indices[i + 5] = j + 3;
+ }
+
+
+ this.drawing = false;
+ this.currentBatchSize = 0;
+ this.currentBaseTexture = null;
+
+ this.setContext(gl);
+};
+
+/**
+*
+* @method setContext
+*
+* @param gl {WebGLContext} the current WebGL drawing context
+*/
+PIXI.WebGLSpriteBatch.prototype.setContext = function(gl)
+{
+ this.gl = gl;
+
+ // create a couple of buffers
+ this.vertexBuffer = gl.createBuffer();
+ this.indexBuffer = gl.createBuffer();
+
+ // 65535 is max index, so 65535 / 6 = 10922.
+
+
+ //upload the index data
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
+ gl.bufferData(gl.ELEMENT_ARRAY_BUFFER, this.indices, gl.STATIC_DRAW);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ gl.bufferData(gl.ARRAY_BUFFER, this.vertices, gl.DYNAMIC_DRAW);
+
+ this.currentBlendMode = 99999;
+};
+
+/**
+*
+* @method begin
+*
+* @param renderSession {RenderSession} the RenderSession
+*/
+PIXI.WebGLSpriteBatch.prototype.begin = function(renderSession)
+{
+ this.renderSession = renderSession;
+ this.shader = this.renderSession.shaderManager.defaultShader;
+
+ this.start();
+};
+
+/**
+*
+* @method end
+*
+*/
+PIXI.WebGLSpriteBatch.prototype.end = function()
+{
+ this.flush();
+};
+
+/**
+*
+* @method render
+*
+* @param sprite {Sprite} the sprite to render TODO-Alvin
+*/
+PIXI.WebGLSpriteBatch.prototype.render = function(sprite)
+{
+ // check texture..
+ if(sprite.texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size)
+ {
+ this.flush();
+ this.currentBaseTexture = sprite.texture.baseTexture;
+ }
+
+
+ // check blend mode
+ if(sprite.blendMode !== this.currentBlendMode)
+ {
+ this.setBlendMode(sprite.blendMode);
+ }
+
+ // get the uvs for the texture
+ var uvs = sprite._uvs || sprite.texture._uvs;
+ // if the uvs have not updated then no point rendering just yet!
+ if(!uvs)return;
+
+ // get the sprites current alpha
+ var alpha = sprite.worldAlpha;
+ var tint = sprite.tint;
+
+ var verticies = this.vertices;
+
+ var width = sprite.texture.frame.width;
+ var height = sprite.texture.frame.height;
+
+ // TODO trim??
+ var aX = sprite.anchor.x;
+ var aY = sprite.anchor.y;
+
+ var w0, w1, h0, h1;
+
+ if (sprite.texture.trimmed)
+ {
+ // if the sprite is trimmed then we need to add the extra space before transforming the sprite coords..
+ var trim = sprite.texture.trim;
+
+ w1 = trim.x - aX * trim.realWidth;
+ w0 = w1 + width;
+
+ h1 = trim.y - aY * trim.realHeight;
+ h0 = h1 + height;
+ }
+ else
+ {
+ w0 = (width ) * (1-aX);
+ w1 = (width ) * -aX;
+
+ h0 = height * (1-aY);
+ h1 = height * -aY;
+ }
+
+ var index = this.currentBatchSize * 4 * this.vertSize;
+
+ var worldTransform = sprite.worldTransform;//.toArray();
+
+ var a = worldTransform.a;//[0];
+ var b = worldTransform.c;//[3];
+ var c = worldTransform.b;//[1];
+ var d = worldTransform.d;//[4];
+ var tx = worldTransform.tx;//[2];
+ var ty = worldTransform.ty;///[5];
+
+ // xy
+ verticies[index++] = a * w1 + c * h1 + tx;
+ verticies[index++] = d * h1 + b * w1 + ty;
+ // uv
+ verticies[index++] = uvs.x0;
+ verticies[index++] = uvs.y0;
+ // color
+ verticies[index++] = alpha;
+ verticies[index++] = tint;
+
+ // xy
+ verticies[index++] = a * w0 + c * h1 + tx;
+ verticies[index++] = d * h1 + b * w0 + ty;
+ // uv
+ verticies[index++] = uvs.x1;
+ verticies[index++] = uvs.y1;
+ // color
+ verticies[index++] = alpha;
+ verticies[index++] = tint;
+
+ // xy
+ verticies[index++] = a * w0 + c * h0 + tx;
+ verticies[index++] = d * h0 + b * w0 + ty;
+ // uv
+ verticies[index++] = uvs.x2;
+ verticies[index++] = uvs.y2;
+ // color
+ verticies[index++] = alpha;
+ verticies[index++] = tint;
+
+ // xy
+ verticies[index++] = a * w1 + c * h0 + tx;
+ verticies[index++] = d * h0 + b * w1 + ty;
+ // uv
+ verticies[index++] = uvs.x3;
+ verticies[index++] = uvs.y3;
+ // color
+ verticies[index++] = alpha;
+ verticies[index++] = tint;
+
+ // increment the batchsize
+ this.currentBatchSize++;
+
+
+};
+
+/**
+*
+* @method renderTilingSprite
+*
+* @param sprite {TilingSprite} the sprite to render TODO-Alvin
+*/
+PIXI.WebGLSpriteBatch.prototype.renderTilingSprite = function(tilingSprite)
+{
+ var texture = tilingSprite.tilingTexture;
+
+ if(texture.baseTexture !== this.currentBaseTexture || this.currentBatchSize >= this.size)
+ {
+ this.flush();
+ this.currentBaseTexture = texture.baseTexture;
+ }
+
+ // check blend mode
+ if(tilingSprite.blendMode !== this.currentBlendMode)
+ {
+ this.setBlendMode(tilingSprite.blendMode);
+ }
+
+ // set the textures uvs temporarily
+ // TODO create a separate texture so that we can tile part of a texture
+
+ if(!tilingSprite._uvs)tilingSprite._uvs = new Float32Array(8);
+
+ var uvs = tilingSprite._uvs;
+
+ tilingSprite.tilePosition.x %= texture.baseTexture.width;
+ tilingSprite.tilePosition.y %= texture.baseTexture.height;
+
+ var offsetX = tilingSprite.tilePosition.x/texture.baseTexture.width;
+ var offsetY = tilingSprite.tilePosition.y/texture.baseTexture.height;
+
+ var scaleX = (tilingSprite.width / texture.baseTexture.width) / (tilingSprite.tileScale.x * tilingSprite.tileScaleOffset.x);
+ var scaleY = (tilingSprite.height / texture.baseTexture.height) / (tilingSprite.tileScale.y * tilingSprite.tileScaleOffset.y);
+
+ uvs.x0 = 0 - offsetX;
+ uvs.y0 = 0 - offsetY;
+
+ uvs.x1 = (1 * scaleX) - offsetX;
+ uvs.y1 = 0 - offsetY;
+
+ uvs.x2 = (1 * scaleX) - offsetX;
+ uvs.y2 = (1 * scaleY) - offsetY;
+
+ uvs.x3 = 0 - offsetX;
+ uvs.y3 = (1 *scaleY) - offsetY;
+
+
+ // get the tilingSprites current alpha
+ var alpha = tilingSprite.worldAlpha;
+ var tint = tilingSprite.tint;
+
+ var verticies = this.vertices;
+
+ var width = tilingSprite.width;
+ var height = tilingSprite.height;
+
+ // TODO trim??
+ var aX = tilingSprite.anchor.x; // - tilingSprite.texture.trim.x
+ var aY = tilingSprite.anchor.y; //- tilingSprite.texture.trim.y
+ var w0 = width * (1-aX);
+ var w1 = width * -aX;
+
+ var h0 = height * (1-aY);
+ var h1 = height * -aY;
+
+ var index = this.currentBatchSize * 4 * this.vertSize;
+
+ var worldTransform = tilingSprite.worldTransform;
+
+ var a = worldTransform.a;//[0];
+ var b = worldTransform.c;//[3];
+ var c = worldTransform.b;//[1];
+ var d = worldTransform.d;//[4];
+ var tx = worldTransform.tx;//[2];
+ var ty = worldTransform.ty;///[5];
+
+ // xy
+ verticies[index++] = a * w1 + c * h1 + tx;
+ verticies[index++] = d * h1 + b * w1 + ty;
+ // uv
+ verticies[index++] = uvs.x0;
+ verticies[index++] = uvs.y0;
+ // color
+ verticies[index++] = alpha;
+ verticies[index++] = tint;
+
+ // xy
+ verticies[index++] = a * w0 + c * h1 + tx;
+ verticies[index++] = d * h1 + b * w0 + ty;
+ // uv
+ verticies[index++] = uvs.x1;
+ verticies[index++] = uvs.y1;
+ // color
+ verticies[index++] = alpha;
+ verticies[index++] = tint;
+
+ // xy
+ verticies[index++] = a * w0 + c * h0 + tx;
+ verticies[index++] = d * h0 + b * w0 + ty;
+ // uv
+ verticies[index++] = uvs.x2;
+ verticies[index++] = uvs.y2;
+ // color
+ verticies[index++] = alpha;
+ verticies[index++] = tint;
+
+ // xy
+ verticies[index++] = a * w1 + c * h0 + tx;
+ verticies[index++] = d * h0 + b * w1 + ty;
+ // uv
+ verticies[index++] = uvs.x3;
+ verticies[index++] = uvs.y3;
+ // color
+ verticies[index++] = alpha;
+ verticies[index++] = tint;
+
+ // increment the batchs
+ this.currentBatchSize++;
+};
+
+
+/**
+*
+*
+* @method flush TODO-Alvin
+*
+*/
+PIXI.WebGLSpriteBatch.prototype.flush = function()
+{
+ // If the batch is length 0 then return as there is nothing to draw
+ if (this.currentBatchSize===0)return;
+
+ var gl = this.gl;
+
+ // bind the current texture
+ gl.bindTexture(gl.TEXTURE_2D, this.currentBaseTexture._glTextures[gl.id] || PIXI.createWebGLTexture(this.currentBaseTexture, gl));
+
+ // upload the verts to the buffer
+
+ if(this.currentBatchSize > ( this.size * 0.5 ) )
+ {
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertices);
+ }
+ else
+ {
+ var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize);
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, view);
+ }
+
+ // var view = this.vertices.subarray(0, this.currentBatchSize * 4 * this.vertSize);
+ //gl.bufferSubData(gl.ARRAY_BUFFER, 0, view);
+
+ // now draw those suckas!
+ gl.drawElements(gl.TRIANGLES, this.currentBatchSize * 6, gl.UNSIGNED_SHORT, 0);
+
+ // then reset the batch!
+ this.currentBatchSize = 0;
+
+ // increment the draw count
+ this.renderSession.drawCount++;
+};
+
+/**
+*
+* @method stop
+*
+*/
+PIXI.WebGLSpriteBatch.prototype.stop = function()
+{
+ this.flush();
+};
+
+/**
+*
+* @method start
+*
+*/
+PIXI.WebGLSpriteBatch.prototype.start = function()
+{
+ var gl = this.gl;
+
+ // bind the main texture
+ gl.activeTexture(gl.TEXTURE0);
+
+ // bind the buffers
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
+
+ // set the projection
+ var projection = this.renderSession.projection;
+ gl.uniform2f(this.shader.projectionVector, projection.x, projection.y);
+
+ // set the pointers
+ var stride = this.vertSize * 4;
+ gl.vertexAttribPointer(this.shader.aVertexPosition, 2, gl.FLOAT, false, stride, 0);
+ gl.vertexAttribPointer(this.shader.aTextureCoord, 2, gl.FLOAT, false, stride, 2 * 4);
+ gl.vertexAttribPointer(this.shader.colorAttribute, 2, gl.FLOAT, false, stride, 4 * 4);
+
+ // set the blend mode..
+ if(this.currentBlendMode !== PIXI.blendModes.NORMAL)
+ {
+ this.setBlendMode(PIXI.blendModes.NORMAL);
+ }
+};
+
+/**
+*
+* @method setBlendMode
+*
+* @param blendMode {Number} the blendMode, should be a Pixi const, such as PIXI.BlendModes.ADD
+* TODO-Alvin
+*/
+PIXI.WebGLSpriteBatch.prototype.setBlendMode = function(blendMode)
+{
+ this.flush();
+
+ this.currentBlendMode = blendMode;
+
+ var blendModeWebGL = PIXI.blendModesWebGL[this.currentBlendMode];
+ this.gl.blendFunc(blendModeWebGL[0], blendModeWebGL[1]);
+};
+
+/**
+* Destroys the SpriteBatch
+* @method destroy
+*/
+PIXI.WebGLSpriteBatch.prototype.destroy = function()
+{
+
+ this.vertices = null;
+ this.indices = null;
+
+ this.gl.deleteBuffer( this.vertexBuffer );
+ this.gl.deleteBuffer( this.indexBuffer );
+
+ this.currentBaseTexture = null;
+
+ this.gl = null;
+};
+
diff --git a/src/pixi/text/BitmapText.js b/src/pixi/text/BitmapText.js
index fb5fb8cc..54136e7a 100644
--- a/src/pixi/text/BitmapText.js
+++ b/src/pixi/text/BitmapText.js
@@ -9,16 +9,18 @@
* http://www.bmglyph.com/ for mac.
*
* @class BitmapText
- * @extends DisplayObjectContainer
+ * @extends SpriteBatch
* @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.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text
*/
PIXI.BitmapText = function(text, style)
{
- PIXI.DisplayObjectContainer.call(this);
+ PIXI.SpriteBatch.call(this);
+
+ this._pool = [];
this.setText(text);
this.setStyle(style);
@@ -27,7 +29,7 @@ PIXI.BitmapText = function(text, style)
};
// constructor
-PIXI.BitmapText.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
+PIXI.BitmapText.prototype = Object.create(PIXI.SpriteBatch.prototype);
PIXI.BitmapText.prototype.constructor = PIXI.BitmapText;
/**
@@ -44,11 +46,11 @@ PIXI.BitmapText.prototype.setText = function(text)
/**
* Set the style of the text
+ * style.font {String} The size (optional) and bitmap font id (required) eq 'Arial' or '20px Arial' (must have loaded previously)
+ * [style.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line 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 {Object} The style parameters, contained as properties of an object
*/
PIXI.BitmapText.prototype.setStyle = function(style)
{
@@ -61,6 +63,7 @@ PIXI.BitmapText.prototype.setStyle = function(style)
this.fontSize = font.length >= 2 ? parseInt(font[font.length - 2], 10) : PIXI.BitmapText.fonts[this.fontName].size;
this.dirty = true;
+ this.tint = style.tint;
};
/**
@@ -79,6 +82,8 @@ PIXI.BitmapText.prototype.updateText = function()
var lineWidths = [];
var line = 0;
var scale = this.fontSize / data.size;
+
+
for(var i = 0; i < this.text.length; i++)
{
var charCode = this.text.charCodeAt(i);
@@ -125,13 +130,30 @@ PIXI.BitmapText.prototype.updateText = function()
lineAlignOffsets.push(alignOffset);
}
- for(i = 0; i < chars.length; i++)
+ var lenChildren = this.children.length;
+ var lenChars = chars.length;
+ var tint = this.tint || 0xFFFFFF;
+ for(i = 0; i < lenChars; i++)
{
- var c = new PIXI.Sprite(chars[i].texture); //PIXI.Sprite.fromFrame(chars[i].charCode);
+ var c = i < lenChildren ? this.children[i] : this._pool.pop(); // get old child if have. if not - take from pool.
+
+ if (c) c.setTexture(chars[i].texture); // check if got one before.
+ else c = new PIXI.Sprite(chars[i].texture); // if no create new one.
+
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);
+ c.tint = tint;
+ if (!c.parent) this.addChild(c);
+ }
+
+ // remove unnecessary children.
+ // and put their into the pool.
+ while(this.children.length > lenChars)
+ {
+ var child = this.getChildAt(this.children.length - 1);
+ this._pool.push(child);
+ this.removeChild(child);
}
this.width = maxLineWidth * scale;
@@ -139,7 +161,7 @@ PIXI.BitmapText.prototype.updateText = function()
};
/**
- * Updates the transfor of this object
+ * Updates the transform of this object
*
* @method updateTransform
* @private
@@ -148,16 +170,11 @@ PIXI.BitmapText.prototype.updateTransform = function()
{
if(this.dirty)
{
- while(this.children.length > 0)
- {
- this.removeChild(this.getChildAt(0));
- }
this.updateText();
-
this.dirty = false;
}
- PIXI.DisplayObjectContainer.prototype.updateTransform.call(this);
+ PIXI.SpriteBatch.prototype.updateTransform.call(this);
};
PIXI.BitmapText.fonts = {};
diff --git a/src/pixi/text/Text.js b/src/pixi/text/Text.js
index 75d50d05..5244ca24 100644
--- a/src/pixi/text/Text.js
+++ b/src/pixi/text/Text.js
@@ -3,7 +3,7 @@
*/
/**
- * 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
@@ -12,7 +12,7 @@
* @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.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text
* @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
@@ -20,8 +20,21 @@
*/
PIXI.Text = function(text, style)
{
+ /**
+ * The canvas element that everything is drawn to
+ *
+ * @property canvas
+ * @type HTMLCanvasElement
+ */
this.canvas = document.createElement('canvas');
+
+ /**
+ * The canvas 2d context that everything is drawn with
+ * @property context
+ * @type HTMLCanvasElement 2d Context
+ */
this.context = this.canvas.getContext('2d');
+
PIXI.Sprite.call(this, PIXI.Texture.fromCanvas(this.canvas));
this.setText(text);
@@ -42,7 +55,7 @@ PIXI.Text.prototype.constructor = PIXI.Text;
* @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.align='left'] {String} Alignment for multiline text ('left', 'center' or 'right'), does not affect single line text
* @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
@@ -72,6 +85,7 @@ PIXI.Text.prototype.setText = function(text)
{
this.text = text.toString() || ' ';
this.dirty = true;
+
};
/**
@@ -108,6 +122,8 @@ PIXI.Text.prototype.updateText = function()
var lineHeight = this.determineFontHeight('font: ' + this.style.font + ';') + this.style.strokeThickness;
this.canvas.height = lineHeight * lines.length;
+ if(navigator.isCocoonJS) this.context.clearRect(0,0,this.canvas.width,this.canvas.height);
+
//set canvas text styles
this.context.fillStyle = this.style.fill;
this.context.font = this.style.font;
@@ -161,11 +177,29 @@ PIXI.Text.prototype.updateTexture = function()
this._width = this.canvas.width;
this._height = this.canvas.height;
- PIXI.texturesToUpdate.push(this.texture.baseTexture);
+ this.requiresUpdate = true;
};
/**
- * Updates the transfor of this object
+* Renders the object using the WebGL renderer
+*
+* @method _renderWebGL
+* @param renderSession {RenderSession}
+* @private
+*/
+PIXI.Text.prototype._renderWebGL = function(renderSession)
+{
+ if(this.requiresUpdate)
+ {
+ this.requiresUpdate = false;
+ PIXI.updateWebGLTexture(this.texture.baseTexture, renderSession.gl);
+ }
+
+ PIXI.Sprite.prototype._renderWebGL.call(this, renderSession);
+};
+
+/**
+ * Updates the transform of this object
*
* @method updateTransform
* @private
@@ -184,6 +218,7 @@ PIXI.Text.prototype.updateTransform = function()
/*
* http://stackoverflow.com/users/34441/ellisbben
* great solution to the problem!
+ * returns the height of the given font
*
* @method determineFontHeight
* @param fontStyle {Object}
diff --git a/src/pixi/textures/BaseTexture.js b/src/pixi/textures/BaseTexture.js
index 1c78656d..ae0b4c71 100644
--- a/src/pixi/textures/BaseTexture.js
+++ b/src/pixi/textures/BaseTexture.js
@@ -6,6 +6,8 @@ PIXI.BaseTextureCache = {};
PIXI.texturesToUpdate = [];
PIXI.texturesToDestroy = [];
+PIXI.BaseTextureCacheIdGenerator = 0;
+
/**
* A texture stores the information that represents an image. All textures have a base texture
*
@@ -13,6 +15,7 @@ PIXI.texturesToDestroy = [];
* @uses EventTarget
* @constructor
* @param source {String} the source object (image or canvas)
+ * @param scaleMode {Number} Should be one of the PIXI.scaleMode consts
*/
PIXI.BaseTexture = function(source, scaleMode)
{
@@ -39,10 +42,10 @@ PIXI.BaseTexture = function(source, scaleMode)
/**
* The scale mode to apply when scaling this texture
* @property scaleMode
- * @type PIXI.BaseTexture.SCALE_MODE
- * @default PIXI.BaseTexture.SCALE_MODE.LINEAR
+ * @type PIXI.scaleModes
+ * @default PIXI.scaleModes.LINEAR
*/
- this.scaleMode = scaleMode || PIXI.BaseTexture.SCALE_MODE.DEFAULT;
+ this.scaleMode = scaleMode || PIXI.scaleModes.DEFAULT;
/**
* [read-only] Describes if the base texture has loaded or not
@@ -63,34 +66,7 @@ PIXI.BaseTexture = function(source, scaleMode)
if(!source)return;
- 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;
-
- PIXI.texturesToUpdate.push(this);
- }
- else
- {
-
- var scope = this;
- this.source.onload = function() {
-
- scope.hasLoaded = true;
- scope.width = scope.source.width;
- scope.height = scope.source.height;
-
- // add it to somewhere...
- PIXI.texturesToUpdate.push(scope);
- scope.dispatchEvent( { type: 'loaded', content: scope } );
- };
- //this.image.src = imageUrl;
- }
- }
- else
+ if(this.source.complete || this.source.getContext)
{
this.hasLoaded = true;
this.width = this.source.width;
@@ -98,9 +74,32 @@ PIXI.BaseTexture = function(source, scaleMode)
PIXI.texturesToUpdate.push(this);
}
+ else
+ {
+
+ var scope = this;
+ this.source.onload = function() {
+
+ scope.hasLoaded = true;
+ scope.width = scope.source.width;
+ scope.height = scope.source.height;
+
+ // add it to somewhere...
+ PIXI.texturesToUpdate.push(scope);
+ scope.dispatchEvent( { type: 'loaded', content: scope } );
+ };
+ //this.image.src = imageUrl;
+ }
this.imageUrl = null;
this._powerOf2 = false;
+
+ //TODO will be used for futer pixi 1.5...
+ this.id = PIXI.BaseTextureCacheIdGenerator++;
+
+ // used for webGL
+ this._glTextures = [];
+
};
PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture;
@@ -112,10 +111,9 @@ PIXI.BaseTexture.prototype.constructor = PIXI.BaseTexture;
*/
PIXI.BaseTexture.prototype.destroy = function()
{
- if(this.source instanceof Image)
+ if(this.imageUrl)
{
- if (this.imageUrl in PIXI.BaseTextureCache)
- delete PIXI.BaseTextureCache[this.imageUrl];
+ delete PIXI.BaseTextureCache[this.imageUrl];
this.imageUrl = null;
this.source.src = null;
}
@@ -138,7 +136,7 @@ PIXI.BaseTexture.prototype.updateSourceImage = function(newSrc)
/**
* Helper function that returns a base texture based on an image url
- * If the image is not in the base texture cache it will be created and loaded
+ * If the image is not in the base texture cache it will be created and loaded
*
* @static
* @method fromImage
@@ -148,6 +146,8 @@ PIXI.BaseTexture.prototype.updateSourceImage = function(newSrc)
PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin, scaleMode)
{
var baseTexture = PIXI.BaseTextureCache[imageUrl];
+ crossorigin = !crossorigin;
+
if(!baseTexture)
{
// new Image() breaks tex loading in some versions of Chrome.
@@ -166,8 +166,22 @@ PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin, scaleMode)
return baseTexture;
};
-PIXI.BaseTexture.SCALE_MODE = {
- DEFAULT: 0, //default to LINEAR
- LINEAR: 0,
- NEAREST: 1
-};
\ No newline at end of file
+PIXI.BaseTexture.fromCanvas = function(canvas, scaleMode)
+{
+ if(!canvas._pixiId)
+ {
+ canvas._pixiId = 'canvas_' + PIXI.TextureCacheIdGenerator++;
+ }
+
+ var baseTexture = PIXI.BaseTextureCache[canvas._pixiId];
+
+ if(!baseTexture)
+ {
+ baseTexture = new PIXI.BaseTexture(canvas, scaleMode);
+ PIXI.BaseTextureCache[canvas._pixiId] = baseTexture;
+ }
+
+ return baseTexture;
+};
+
+
diff --git a/src/pixi/textures/RenderTexture.js b/src/pixi/textures/RenderTexture.js
index fe1df380..602d68e1 100644
--- a/src/pixi/textures/RenderTexture.js
+++ b/src/pixi/textures/RenderTexture.js
@@ -5,7 +5,7 @@
/**
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.
+ __Hint__: All DisplayObjects (exmpl. Sprites) that render 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:
@@ -30,112 +30,73 @@
@param width {Number} The width of the render texture
@param height {Number} The height of the render texture
*/
-PIXI.RenderTexture = function(width, height)
+PIXI.RenderTexture = function(width, height, renderer)
{
PIXI.EventTarget.call( this );
this.width = width || 100;
this.height = height || 100;
- this.indetityMatrix = PIXI.mat3.create();
-
this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
- if(PIXI.gl)
+ this.baseTexture = new PIXI.BaseTexture();
+ this.baseTexture.width = this.width;
+ this.baseTexture.height = this.height;
+ this.baseTexture._glTextures = [];
+
+ this.baseTexture.hasLoaded = true;
+
+ // each render texture can only belong to one renderer at the moment if its webGL
+ this.renderer = renderer || PIXI.defaultRenderer;
+
+ if(this.renderer.type === PIXI.WEBGL_RENDERER)
{
- this.initWebGL();
+ var gl = this.renderer.gl;
+
+ this.textureBuffer = new PIXI.FilterTexture(gl, this.width, this.height);
+ this.baseTexture._glTextures[gl.id] = this.textureBuffer.texture;
+
+ this.render = this.renderWebGL;
+ this.projection = new PIXI.Point(this.width/2 , -this.height/2);
}
else
{
- this.initCanvas();
+ this.render = this.renderCanvas;
+ this.textureBuffer = new PIXI.CanvasBuffer(this.width, this.height);
+ this.baseTexture.source = this.textureBuffer.canvas;
}
+
+ PIXI.Texture.frameUpdates.push(this);
+
+
};
PIXI.RenderTexture.prototype = Object.create( PIXI.Texture.prototype );
PIXI.RenderTexture.prototype.constructor = PIXI.RenderTexture;
-/**
- * Initializes the webgl data for this texture
- *
- * @method initWebGL
- * @private
- */
-PIXI.RenderTexture.prototype.initWebGL = function()
-{
- var gl = PIXI.gl;
- this.glFramebuffer = gl.createFramebuffer();
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- this.glFramebuffer.width = this.width;
- this.glFramebuffer.height = this.height;
-
- this.baseTexture = new PIXI.BaseTexture();
-
- 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.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);
-
- this.baseTexture.isRender = true;
-
- 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);
-
- // 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.frame.width = this.width;
+ this.frame.height = this.height;
+
+ if(this.renderer.type === PIXI.WEBGL_RENDERER)
{
this.projection.x = this.width / 2;
this.projection.y = -this.height / 2;
- var gl = PIXI.gl;
- gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture);
+ var gl = this.gl;
+ gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTextures[gl.id]);
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.textureBuffer.resize(this.width, this.height);
}
-};
-/**
- * Initializes the canvas data for this texture
- *
- * @method initCanvas
- * @private
- */
-PIXI.RenderTexture.prototype.initCanvas = function()
-{
- 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.render = this.renderCanvas;
+ PIXI.Texture.frameUpdates.push(this);
};
/**
@@ -148,64 +109,42 @@ PIXI.RenderTexture.prototype.initCanvas = function()
*/
PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, clear)
{
- var gl = PIXI.gl;
+ var gl = this.renderer.gl;
- // enable the alpha color mask..
gl.colorMask(true, true, true, true);
gl.viewport(0, 0, this.width, this.height);
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.textureBuffer.frameBuffer );
- if(clear)
- {
- gl.clearColor(0,0,0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- }
+ if(clear)this.textureBuffer.clear();
// 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;
+ displayObject.worldTransform = PIXI.RenderTexture.tempMatrix;
// modify to flip...
- displayObject.worldTransform[4] = -1;
- displayObject.worldTransform[5] = this.projection.y * -2;
+ displayObject.worldTransform.d = -1;
+ displayObject.worldTransform.ty = this.projection.y * -2;
if(position)
{
- displayObject.worldTransform[2] = position.x;
- displayObject.worldTransform[5] -= position.y;
+ displayObject.worldTransform.tx = position.x;
+ displayObject.worldTransform.ty -= position.y;
}
- PIXI.visibleCount++;
- displayObject.vcount = PIXI.visibleCount;
-
for(var i=0,j=children.length; i> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255];
};
+/**
+ * Converts a color as an [R, G, B] array to a hex number
+ *
+ * @method rgb2hex
+ * @param rgb {Array}
+ */
+PIXI.rgb2hex = function(rgb) {
+ return ((rgb[0]*255 << 16) + (rgb[1]*255 << 8) + rgb[2]*255);
+};
+
/**
* A polyfill for Function.prototype.bind
*
@@ -86,7 +102,7 @@ if (typeof Function.prototype.bind !== 'function') {
* @class AjaxRequest
* @constructor
*/
-PIXI.AjaxRequest = function AjaxRequest()
+PIXI.AjaxRequest = function()
{
var activexmodes = ['Msxml2.XMLHTTP.6.0', 'Msxml2.XMLHTTP.3.0', 'Microsoft.XMLHTTP']; //activeX versions to check for in IE
@@ -111,34 +127,71 @@ PIXI.AjaxRequest = function AjaxRequest()
return false;
}
};
-
/*
- * DEBUGGING ONLY
- */
-PIXI.runList = function(item)
+PIXI.packColorRGBA = function(r, g, b, a)//r, g, b, a)
{
- window.console.log('>>>>>>>>>');
- window.console.log('_');
- var safe = 0;
- var tmp = item.first;
- window.console.log(tmp);
+ // console.log(r, b, c, d)
+ return (Math.floor((r)*63) << 18) | (Math.floor((g)*63) << 12) | (Math.floor((b)*63) << 6);// | (Math.floor((a)*63))
+ // i = i | (Math.floor((a)*63));
+ // return i;
+ // var r = (i / 262144.0 ) / 64;
+ // var g = (i / 4096.0)%64 / 64;
+ // var b = (i / 64.0)%64 / 64;
+ // var a = (i)%64 / 64;
+
+ // console.log(r, g, b, a);
+ // return i;
- while(tmp._iNext)
- {
- safe++;
- tmp = tmp._iNext;
- window.console.log(tmp);
- // console.log(tmp);
-
- if(safe > 100)
- {
- window.console.log('BREAK');
- break;
- }
- }
+};
+*/
+/*
+PIXI.packColorRGB = function(r, g, b)//r, g, b, a)
+{
+ return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255));
};
+PIXI.unpackColorRGB = function(r, g, b)//r, g, b, a)
+{
+ return (Math.floor((r)*255) << 16) | (Math.floor((g)*255) << 8) | (Math.floor((b)*255));
+};
+*/
+/**
+ * Checks whether the Canvas BlendModes are supported by the current browser
+ *
+ * @method canUseNewCanvasBlendModes
+ * @return {Boolean} whether they are supported
+ */
+PIXI.canUseNewCanvasBlendModes = function()
+{
+ var canvas = document.createElement('canvas');
+ canvas.width = 1;
+ canvas.height = 1;
+ var context = canvas.getContext('2d');
+ context.fillStyle = '#000';
+ context.fillRect(0,0,1,1);
+ context.globalCompositeOperation = 'multiply';
+ context.fillStyle = '#fff';
+ context.fillRect(0,0,1,1);
+ return context.getImageData(0,0,1,1).data[0] === 0;
+};
-
-
+/**
+ * Given a number, this function returns the closest number that is a power of two
+ * this function is taken from Starling Framework as its pretty neat ;)
+ *
+ * @method getNextPowerOfTwo
+ * @param number {Number}
+ * @return {Number} the closest number that is a power of two
+ */
+PIXI.getNextPowerOfTwo = function(number)
+{
+ if (number > 0 && (number & (number - 1)) === 0) // see: http://goo.gl/D9kPj
+ return number;
+ else
+ {
+ var result = 1;
+ while (result < number) result <<= 1;
+ return result;
+ }
+};
From 4cfce8b4d2a0211ecf2a736798f320d006618ff9 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Thu, 6 Feb 2014 02:31:36 +0000
Subject: [PATCH 04/26] Group now extends PIXI.DisplayObjectContainer, rather
than owning a _container property, which makes life a whole lot easier re:
nesting.
---
README.md | 2 +
build/config.php | 89 +-
examples/wip/index.php | 2 +-
examples/wip/{ => misc}/2ball.js | 0
examples/wip/{ => misc}/64x64.png | Bin
examples/wip/{ => misc}/SAT.js | 0
examples/wip/{ => misc}/acceleration.js | 0
examples/wip/{ => misc}/audio loop.js | 0
examples/wip/{ => misc}/blocked.js | 0
examples/wip/{ => misc}/bmd.js | 0
examples/wip/{ => misc}/bmd2.js | 0
examples/wip/{ => misc}/bmd3.js | 0
examples/wip/{ => misc}/body angle.js | 0
examples/wip/{ => misc}/body group.js | 0
examples/wip/{ => misc}/body scale.js | 0
examples/wip/{ => misc}/body test.js | 0
examples/wip/{ => misc}/bunny.js | 0
examples/wip/{ => misc}/button scale.js | 0
examples/wip/{ => misc}/button size.js | 0
examples/wip/{ => misc}/circlebox.js | 0
examples/wip/{ => misc}/commando.js | 0
examples/wip/{ => misc}/create map polygon.js | 0
examples/wip/{ => misc}/crop.js | 0
examples/wip/{ => misc}/cursor.js | 0
examples/wip/{ => misc}/demo worm.js | 0
examples/wip/{ => misc}/dragonfire.js | 0
examples/wip/{ => misc}/fiddle.js | 0
examples/wip/{ => misc}/filterconv.php | 0
examples/wip/{ => misc}/fixdrag.js | 0
examples/wip/{ => misc}/forum.js | 0
examples/wip/{ => misc}/gc1.js | 0
examples/wip/{ => misc}/gravity.js | 0
examples/wip/{ => misc}/group call all.js | 0
examples/wip/{ => misc}/group destroy.js | 0
examples/wip/{ => misc}/group extends.js | 0
examples/wip/{ => misc}/group offset.js | 0
examples/wip/{ => misc}/input active.js | 0
examples/wip/{ => misc}/jitter.js | 0
examples/wip/{ => misc}/land.js | 0
examples/wip/{ => misc}/line intersection.js | 0
examples/wip/{ => misc}/line polygon.js | 0
examples/wip/{ => misc}/mariotogether.js | 0
examples/wip/{ => misc}/mod.js | 0
examples/wip/{ => misc}/mouse scale.js | 0
examples/wip/{ => misc}/moveToPointer.js | 0
examples/wip/{ => misc}/multiball.js | 0
examples/wip/{ => misc}/nested groups.js | 0
examples/wip/{ => misc}/offset.js | 0
examples/wip/{ => misc}/one way collision.js | 0
examples/wip/{ => misc}/pausetime.js | 0
examples/wip/{ => misc}/physics-motion.js | 0
examples/wip/{ => misc}/pivot.js | 0
.../wip/{ => misc}/pixelpick atlas trimmed.js | 0
examples/wip/{ => misc}/platform.js | 0
examples/wip/{ => misc}/prerend.js | 0
examples/wip/{ => misc}/pt.js | 0
examples/wip/{ => misc}/rabbit map.js | 0
examples/wip/{ => misc}/rect test.js | 0
examples/wip/{ => misc}/removeFilter.js | 0
examples/wip/{ => misc}/rendertexture1.js | 0
examples/wip/{ => misc}/sat1.js | 0
examples/wip/{ => misc}/sci-fly2.js | 0
examples/wip/{ => misc}/snake.js | 0
examples/wip/{ => misc}/snake2.js | 0
examples/wip/{ => misc}/sort.js | 0
examples/wip/{ => misc}/sprite vs sprite.js | 0
examples/wip/{ => misc}/struck.js | 0
examples/wip/{ => misc}/supermario.js | 0
examples/wip/{ => misc}/supermario2.js | 0
examples/wip/{ => misc}/swap.js | 0
examples/wip/{ => misc}/text on top.js | 0
examples/wip/{ => misc}/tilemap poly.js | 0
examples/wip/{ => misc}/tilemap.js | 0
examples/wip/{ => misc}/timer simple.js | 0
examples/wip/{ => misc}/tween-limit.js | 0
examples/wip/{ => misc}/tween-relative.js | 0
examples/wip/{ => misc}/wabbits.js | 0
examples/wip/{ => misc}/wip1.js | 0
examples/wip/{ => misc}/wip2.js | 0
examples/wip/{ => misc}/wip3.js | 0
examples/wip/{ => misc}/wip4.js | 0
examples/wip/{ => misc}/world.js | 0
examples/wip/pixi1.js | 45 +
src/Phaser.js | 2 +-
src/core/Group.js | 2429 +++++++----------
src/core/World.js | 87 +-
src/gameobjects/RenderTexture.js | 5 -
src/particles/arcade/Emitter.js | 4 +-
src/physics/arcade/ArcadePhysics.js | 32 +-
89 files changed, 1176 insertions(+), 1521 deletions(-)
rename examples/wip/{ => misc}/2ball.js (100%)
rename examples/wip/{ => misc}/64x64.png (100%)
rename examples/wip/{ => misc}/SAT.js (100%)
rename examples/wip/{ => misc}/acceleration.js (100%)
rename examples/wip/{ => misc}/audio loop.js (100%)
rename examples/wip/{ => misc}/blocked.js (100%)
rename examples/wip/{ => misc}/bmd.js (100%)
rename examples/wip/{ => misc}/bmd2.js (100%)
rename examples/wip/{ => misc}/bmd3.js (100%)
rename examples/wip/{ => misc}/body angle.js (100%)
rename examples/wip/{ => misc}/body group.js (100%)
rename examples/wip/{ => misc}/body scale.js (100%)
rename examples/wip/{ => misc}/body test.js (100%)
rename examples/wip/{ => misc}/bunny.js (100%)
rename examples/wip/{ => misc}/button scale.js (100%)
rename examples/wip/{ => misc}/button size.js (100%)
rename examples/wip/{ => misc}/circlebox.js (100%)
rename examples/wip/{ => misc}/commando.js (100%)
rename examples/wip/{ => misc}/create map polygon.js (100%)
rename examples/wip/{ => misc}/crop.js (100%)
rename examples/wip/{ => misc}/cursor.js (100%)
rename examples/wip/{ => misc}/demo worm.js (100%)
rename examples/wip/{ => misc}/dragonfire.js (100%)
rename examples/wip/{ => misc}/fiddle.js (100%)
rename examples/wip/{ => misc}/filterconv.php (100%)
rename examples/wip/{ => misc}/fixdrag.js (100%)
rename examples/wip/{ => misc}/forum.js (100%)
rename examples/wip/{ => misc}/gc1.js (100%)
rename examples/wip/{ => misc}/gravity.js (100%)
rename examples/wip/{ => misc}/group call all.js (100%)
rename examples/wip/{ => misc}/group destroy.js (100%)
rename examples/wip/{ => misc}/group extends.js (100%)
rename examples/wip/{ => misc}/group offset.js (100%)
rename examples/wip/{ => misc}/input active.js (100%)
rename examples/wip/{ => misc}/jitter.js (100%)
rename examples/wip/{ => misc}/land.js (100%)
rename examples/wip/{ => misc}/line intersection.js (100%)
rename examples/wip/{ => misc}/line polygon.js (100%)
rename examples/wip/{ => misc}/mariotogether.js (100%)
rename examples/wip/{ => misc}/mod.js (100%)
rename examples/wip/{ => misc}/mouse scale.js (100%)
rename examples/wip/{ => misc}/moveToPointer.js (100%)
rename examples/wip/{ => misc}/multiball.js (100%)
rename examples/wip/{ => misc}/nested groups.js (100%)
rename examples/wip/{ => misc}/offset.js (100%)
rename examples/wip/{ => misc}/one way collision.js (100%)
rename examples/wip/{ => misc}/pausetime.js (100%)
rename examples/wip/{ => misc}/physics-motion.js (100%)
rename examples/wip/{ => misc}/pivot.js (100%)
rename examples/wip/{ => misc}/pixelpick atlas trimmed.js (100%)
rename examples/wip/{ => misc}/platform.js (100%)
rename examples/wip/{ => misc}/prerend.js (100%)
rename examples/wip/{ => misc}/pt.js (100%)
rename examples/wip/{ => misc}/rabbit map.js (100%)
rename examples/wip/{ => misc}/rect test.js (100%)
rename examples/wip/{ => misc}/removeFilter.js (100%)
rename examples/wip/{ => misc}/rendertexture1.js (100%)
rename examples/wip/{ => misc}/sat1.js (100%)
rename examples/wip/{ => misc}/sci-fly2.js (100%)
rename examples/wip/{ => misc}/snake.js (100%)
rename examples/wip/{ => misc}/snake2.js (100%)
rename examples/wip/{ => misc}/sort.js (100%)
rename examples/wip/{ => misc}/sprite vs sprite.js (100%)
rename examples/wip/{ => misc}/struck.js (100%)
rename examples/wip/{ => misc}/supermario.js (100%)
rename examples/wip/{ => misc}/supermario2.js (100%)
rename examples/wip/{ => misc}/swap.js (100%)
rename examples/wip/{ => misc}/text on top.js (100%)
rename examples/wip/{ => misc}/tilemap poly.js (100%)
rename examples/wip/{ => misc}/tilemap.js (100%)
rename examples/wip/{ => misc}/timer simple.js (100%)
rename examples/wip/{ => misc}/tween-limit.js (100%)
rename examples/wip/{ => misc}/tween-relative.js (100%)
rename examples/wip/{ => misc}/wabbits.js (100%)
rename examples/wip/{ => misc}/wip1.js (100%)
rename examples/wip/{ => misc}/wip2.js (100%)
rename examples/wip/{ => misc}/wip3.js (100%)
rename examples/wip/{ => misc}/wip4.js (100%)
rename examples/wip/{ => misc}/world.js (100%)
create mode 100644 examples/wip/pixi1.js
diff --git a/README.md b/README.md
index 77600118..a4cc4d20 100644
--- a/README.md
+++ b/README.md
@@ -62,6 +62,8 @@ Version 1.2 - "Shienar" - -in development-
Significant API changes:
* Upgraded to Pixi.js 1.4.4
+* Group now extends PIXI.DisplayObjectContainer, rather than owning a _container property, which makes life a whole lot easier re: nesting.
+
New features:
diff --git a/build/config.php b/build/config.php
index 0881b73f..77ba03a8 100644
--- a/build/config.php
+++ b/build/config.php
@@ -13,47 +13,76 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -145,7 +174,5 @@
-
-
EOL;
?>
diff --git a/examples/wip/index.php b/examples/wip/index.php
index 74826bf3..f72e4b70 100644
--- a/examples/wip/index.php
+++ b/examples/wip/index.php
@@ -32,7 +32,7 @@
function dirToArray($dir) {
- $ignore = array('.', '..', '_site', 'assets', 'states', 'book', 'filters');
+ $ignore = array('.', '..', '_site', 'assets', 'states', 'book', 'filters', 'misc');
$result = array();
$root = scandir($dir);
$dirs = array_diff($root, $ignore);
diff --git a/examples/wip/2ball.js b/examples/wip/misc/2ball.js
similarity index 100%
rename from examples/wip/2ball.js
rename to examples/wip/misc/2ball.js
diff --git a/examples/wip/64x64.png b/examples/wip/misc/64x64.png
similarity index 100%
rename from examples/wip/64x64.png
rename to examples/wip/misc/64x64.png
diff --git a/examples/wip/SAT.js b/examples/wip/misc/SAT.js
similarity index 100%
rename from examples/wip/SAT.js
rename to examples/wip/misc/SAT.js
diff --git a/examples/wip/acceleration.js b/examples/wip/misc/acceleration.js
similarity index 100%
rename from examples/wip/acceleration.js
rename to examples/wip/misc/acceleration.js
diff --git a/examples/wip/audio loop.js b/examples/wip/misc/audio loop.js
similarity index 100%
rename from examples/wip/audio loop.js
rename to examples/wip/misc/audio loop.js
diff --git a/examples/wip/blocked.js b/examples/wip/misc/blocked.js
similarity index 100%
rename from examples/wip/blocked.js
rename to examples/wip/misc/blocked.js
diff --git a/examples/wip/bmd.js b/examples/wip/misc/bmd.js
similarity index 100%
rename from examples/wip/bmd.js
rename to examples/wip/misc/bmd.js
diff --git a/examples/wip/bmd2.js b/examples/wip/misc/bmd2.js
similarity index 100%
rename from examples/wip/bmd2.js
rename to examples/wip/misc/bmd2.js
diff --git a/examples/wip/bmd3.js b/examples/wip/misc/bmd3.js
similarity index 100%
rename from examples/wip/bmd3.js
rename to examples/wip/misc/bmd3.js
diff --git a/examples/wip/body angle.js b/examples/wip/misc/body angle.js
similarity index 100%
rename from examples/wip/body angle.js
rename to examples/wip/misc/body angle.js
diff --git a/examples/wip/body group.js b/examples/wip/misc/body group.js
similarity index 100%
rename from examples/wip/body group.js
rename to examples/wip/misc/body group.js
diff --git a/examples/wip/body scale.js b/examples/wip/misc/body scale.js
similarity index 100%
rename from examples/wip/body scale.js
rename to examples/wip/misc/body scale.js
diff --git a/examples/wip/body test.js b/examples/wip/misc/body test.js
similarity index 100%
rename from examples/wip/body test.js
rename to examples/wip/misc/body test.js
diff --git a/examples/wip/bunny.js b/examples/wip/misc/bunny.js
similarity index 100%
rename from examples/wip/bunny.js
rename to examples/wip/misc/bunny.js
diff --git a/examples/wip/button scale.js b/examples/wip/misc/button scale.js
similarity index 100%
rename from examples/wip/button scale.js
rename to examples/wip/misc/button scale.js
diff --git a/examples/wip/button size.js b/examples/wip/misc/button size.js
similarity index 100%
rename from examples/wip/button size.js
rename to examples/wip/misc/button size.js
diff --git a/examples/wip/circlebox.js b/examples/wip/misc/circlebox.js
similarity index 100%
rename from examples/wip/circlebox.js
rename to examples/wip/misc/circlebox.js
diff --git a/examples/wip/commando.js b/examples/wip/misc/commando.js
similarity index 100%
rename from examples/wip/commando.js
rename to examples/wip/misc/commando.js
diff --git a/examples/wip/create map polygon.js b/examples/wip/misc/create map polygon.js
similarity index 100%
rename from examples/wip/create map polygon.js
rename to examples/wip/misc/create map polygon.js
diff --git a/examples/wip/crop.js b/examples/wip/misc/crop.js
similarity index 100%
rename from examples/wip/crop.js
rename to examples/wip/misc/crop.js
diff --git a/examples/wip/cursor.js b/examples/wip/misc/cursor.js
similarity index 100%
rename from examples/wip/cursor.js
rename to examples/wip/misc/cursor.js
diff --git a/examples/wip/demo worm.js b/examples/wip/misc/demo worm.js
similarity index 100%
rename from examples/wip/demo worm.js
rename to examples/wip/misc/demo worm.js
diff --git a/examples/wip/dragonfire.js b/examples/wip/misc/dragonfire.js
similarity index 100%
rename from examples/wip/dragonfire.js
rename to examples/wip/misc/dragonfire.js
diff --git a/examples/wip/fiddle.js b/examples/wip/misc/fiddle.js
similarity index 100%
rename from examples/wip/fiddle.js
rename to examples/wip/misc/fiddle.js
diff --git a/examples/wip/filterconv.php b/examples/wip/misc/filterconv.php
similarity index 100%
rename from examples/wip/filterconv.php
rename to examples/wip/misc/filterconv.php
diff --git a/examples/wip/fixdrag.js b/examples/wip/misc/fixdrag.js
similarity index 100%
rename from examples/wip/fixdrag.js
rename to examples/wip/misc/fixdrag.js
diff --git a/examples/wip/forum.js b/examples/wip/misc/forum.js
similarity index 100%
rename from examples/wip/forum.js
rename to examples/wip/misc/forum.js
diff --git a/examples/wip/gc1.js b/examples/wip/misc/gc1.js
similarity index 100%
rename from examples/wip/gc1.js
rename to examples/wip/misc/gc1.js
diff --git a/examples/wip/gravity.js b/examples/wip/misc/gravity.js
similarity index 100%
rename from examples/wip/gravity.js
rename to examples/wip/misc/gravity.js
diff --git a/examples/wip/group call all.js b/examples/wip/misc/group call all.js
similarity index 100%
rename from examples/wip/group call all.js
rename to examples/wip/misc/group call all.js
diff --git a/examples/wip/group destroy.js b/examples/wip/misc/group destroy.js
similarity index 100%
rename from examples/wip/group destroy.js
rename to examples/wip/misc/group destroy.js
diff --git a/examples/wip/group extends.js b/examples/wip/misc/group extends.js
similarity index 100%
rename from examples/wip/group extends.js
rename to examples/wip/misc/group extends.js
diff --git a/examples/wip/group offset.js b/examples/wip/misc/group offset.js
similarity index 100%
rename from examples/wip/group offset.js
rename to examples/wip/misc/group offset.js
diff --git a/examples/wip/input active.js b/examples/wip/misc/input active.js
similarity index 100%
rename from examples/wip/input active.js
rename to examples/wip/misc/input active.js
diff --git a/examples/wip/jitter.js b/examples/wip/misc/jitter.js
similarity index 100%
rename from examples/wip/jitter.js
rename to examples/wip/misc/jitter.js
diff --git a/examples/wip/land.js b/examples/wip/misc/land.js
similarity index 100%
rename from examples/wip/land.js
rename to examples/wip/misc/land.js
diff --git a/examples/wip/line intersection.js b/examples/wip/misc/line intersection.js
similarity index 100%
rename from examples/wip/line intersection.js
rename to examples/wip/misc/line intersection.js
diff --git a/examples/wip/line polygon.js b/examples/wip/misc/line polygon.js
similarity index 100%
rename from examples/wip/line polygon.js
rename to examples/wip/misc/line polygon.js
diff --git a/examples/wip/mariotogether.js b/examples/wip/misc/mariotogether.js
similarity index 100%
rename from examples/wip/mariotogether.js
rename to examples/wip/misc/mariotogether.js
diff --git a/examples/wip/mod.js b/examples/wip/misc/mod.js
similarity index 100%
rename from examples/wip/mod.js
rename to examples/wip/misc/mod.js
diff --git a/examples/wip/mouse scale.js b/examples/wip/misc/mouse scale.js
similarity index 100%
rename from examples/wip/mouse scale.js
rename to examples/wip/misc/mouse scale.js
diff --git a/examples/wip/moveToPointer.js b/examples/wip/misc/moveToPointer.js
similarity index 100%
rename from examples/wip/moveToPointer.js
rename to examples/wip/misc/moveToPointer.js
diff --git a/examples/wip/multiball.js b/examples/wip/misc/multiball.js
similarity index 100%
rename from examples/wip/multiball.js
rename to examples/wip/misc/multiball.js
diff --git a/examples/wip/nested groups.js b/examples/wip/misc/nested groups.js
similarity index 100%
rename from examples/wip/nested groups.js
rename to examples/wip/misc/nested groups.js
diff --git a/examples/wip/offset.js b/examples/wip/misc/offset.js
similarity index 100%
rename from examples/wip/offset.js
rename to examples/wip/misc/offset.js
diff --git a/examples/wip/one way collision.js b/examples/wip/misc/one way collision.js
similarity index 100%
rename from examples/wip/one way collision.js
rename to examples/wip/misc/one way collision.js
diff --git a/examples/wip/pausetime.js b/examples/wip/misc/pausetime.js
similarity index 100%
rename from examples/wip/pausetime.js
rename to examples/wip/misc/pausetime.js
diff --git a/examples/wip/physics-motion.js b/examples/wip/misc/physics-motion.js
similarity index 100%
rename from examples/wip/physics-motion.js
rename to examples/wip/misc/physics-motion.js
diff --git a/examples/wip/pivot.js b/examples/wip/misc/pivot.js
similarity index 100%
rename from examples/wip/pivot.js
rename to examples/wip/misc/pivot.js
diff --git a/examples/wip/pixelpick atlas trimmed.js b/examples/wip/misc/pixelpick atlas trimmed.js
similarity index 100%
rename from examples/wip/pixelpick atlas trimmed.js
rename to examples/wip/misc/pixelpick atlas trimmed.js
diff --git a/examples/wip/platform.js b/examples/wip/misc/platform.js
similarity index 100%
rename from examples/wip/platform.js
rename to examples/wip/misc/platform.js
diff --git a/examples/wip/prerend.js b/examples/wip/misc/prerend.js
similarity index 100%
rename from examples/wip/prerend.js
rename to examples/wip/misc/prerend.js
diff --git a/examples/wip/pt.js b/examples/wip/misc/pt.js
similarity index 100%
rename from examples/wip/pt.js
rename to examples/wip/misc/pt.js
diff --git a/examples/wip/rabbit map.js b/examples/wip/misc/rabbit map.js
similarity index 100%
rename from examples/wip/rabbit map.js
rename to examples/wip/misc/rabbit map.js
diff --git a/examples/wip/rect test.js b/examples/wip/misc/rect test.js
similarity index 100%
rename from examples/wip/rect test.js
rename to examples/wip/misc/rect test.js
diff --git a/examples/wip/removeFilter.js b/examples/wip/misc/removeFilter.js
similarity index 100%
rename from examples/wip/removeFilter.js
rename to examples/wip/misc/removeFilter.js
diff --git a/examples/wip/rendertexture1.js b/examples/wip/misc/rendertexture1.js
similarity index 100%
rename from examples/wip/rendertexture1.js
rename to examples/wip/misc/rendertexture1.js
diff --git a/examples/wip/sat1.js b/examples/wip/misc/sat1.js
similarity index 100%
rename from examples/wip/sat1.js
rename to examples/wip/misc/sat1.js
diff --git a/examples/wip/sci-fly2.js b/examples/wip/misc/sci-fly2.js
similarity index 100%
rename from examples/wip/sci-fly2.js
rename to examples/wip/misc/sci-fly2.js
diff --git a/examples/wip/snake.js b/examples/wip/misc/snake.js
similarity index 100%
rename from examples/wip/snake.js
rename to examples/wip/misc/snake.js
diff --git a/examples/wip/snake2.js b/examples/wip/misc/snake2.js
similarity index 100%
rename from examples/wip/snake2.js
rename to examples/wip/misc/snake2.js
diff --git a/examples/wip/sort.js b/examples/wip/misc/sort.js
similarity index 100%
rename from examples/wip/sort.js
rename to examples/wip/misc/sort.js
diff --git a/examples/wip/sprite vs sprite.js b/examples/wip/misc/sprite vs sprite.js
similarity index 100%
rename from examples/wip/sprite vs sprite.js
rename to examples/wip/misc/sprite vs sprite.js
diff --git a/examples/wip/struck.js b/examples/wip/misc/struck.js
similarity index 100%
rename from examples/wip/struck.js
rename to examples/wip/misc/struck.js
diff --git a/examples/wip/supermario.js b/examples/wip/misc/supermario.js
similarity index 100%
rename from examples/wip/supermario.js
rename to examples/wip/misc/supermario.js
diff --git a/examples/wip/supermario2.js b/examples/wip/misc/supermario2.js
similarity index 100%
rename from examples/wip/supermario2.js
rename to examples/wip/misc/supermario2.js
diff --git a/examples/wip/swap.js b/examples/wip/misc/swap.js
similarity index 100%
rename from examples/wip/swap.js
rename to examples/wip/misc/swap.js
diff --git a/examples/wip/text on top.js b/examples/wip/misc/text on top.js
similarity index 100%
rename from examples/wip/text on top.js
rename to examples/wip/misc/text on top.js
diff --git a/examples/wip/tilemap poly.js b/examples/wip/misc/tilemap poly.js
similarity index 100%
rename from examples/wip/tilemap poly.js
rename to examples/wip/misc/tilemap poly.js
diff --git a/examples/wip/tilemap.js b/examples/wip/misc/tilemap.js
similarity index 100%
rename from examples/wip/tilemap.js
rename to examples/wip/misc/tilemap.js
diff --git a/examples/wip/timer simple.js b/examples/wip/misc/timer simple.js
similarity index 100%
rename from examples/wip/timer simple.js
rename to examples/wip/misc/timer simple.js
diff --git a/examples/wip/tween-limit.js b/examples/wip/misc/tween-limit.js
similarity index 100%
rename from examples/wip/tween-limit.js
rename to examples/wip/misc/tween-limit.js
diff --git a/examples/wip/tween-relative.js b/examples/wip/misc/tween-relative.js
similarity index 100%
rename from examples/wip/tween-relative.js
rename to examples/wip/misc/tween-relative.js
diff --git a/examples/wip/wabbits.js b/examples/wip/misc/wabbits.js
similarity index 100%
rename from examples/wip/wabbits.js
rename to examples/wip/misc/wabbits.js
diff --git a/examples/wip/wip1.js b/examples/wip/misc/wip1.js
similarity index 100%
rename from examples/wip/wip1.js
rename to examples/wip/misc/wip1.js
diff --git a/examples/wip/wip2.js b/examples/wip/misc/wip2.js
similarity index 100%
rename from examples/wip/wip2.js
rename to examples/wip/misc/wip2.js
diff --git a/examples/wip/wip3.js b/examples/wip/misc/wip3.js
similarity index 100%
rename from examples/wip/wip3.js
rename to examples/wip/misc/wip3.js
diff --git a/examples/wip/wip4.js b/examples/wip/misc/wip4.js
similarity index 100%
rename from examples/wip/wip4.js
rename to examples/wip/misc/wip4.js
diff --git a/examples/wip/world.js b/examples/wip/misc/world.js
similarity index 100%
rename from examples/wip/world.js
rename to examples/wip/misc/world.js
diff --git a/examples/wip/pixi1.js b/examples/wip/pixi1.js
new file mode 100644
index 00000000..c4b3ebb0
--- /dev/null
+++ b/examples/wip/pixi1.js
@@ -0,0 +1,45 @@
+
+var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('pic', 'assets/pics/backscroll.png');
+
+}
+
+var sprite;
+var sprite2;
+var g;
+
+function create() {
+
+ sprite = game.add.sprite(0, 0, 'pic');
+
+ g = game.add.group();
+
+ g.create(0, 0, 'pic');
+
+ g.y = 200;
+ g.rotation = 0.1;
+
+ // sprite2 = game.add.sprite(0, 300, 'pic');
+
+ game.input.onDown.add(tint, this);
+
+}
+
+function tint() {
+
+ sprite.tint = Math.random() * 0xFFFFFF;
+ // sprite2.tint = Math.random() * 0xFFFFFF;
+
+}
+
+function update() {
+
+
+}
+
+function render() {
+
+}
diff --git a/src/Phaser.js b/src/Phaser.js
index 786bbd48..6cb14044 100644
--- a/src/Phaser.js
+++ b/src/Phaser.js
@@ -10,7 +10,7 @@
var Phaser = Phaser || {
VERSION: '<%= version %>',
- DEV_VERSION: '1.1.5',
+ DEV_VERSION: '1.2',
GAMES: [],
AUTO: 0,
diff --git a/src/core/Group.js b/src/core/Group.js
index 5fa52339..0eb47cec 100644
--- a/src/core/Group.js
+++ b/src/core/Group.js
@@ -10,7 +10,7 @@
* @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. If undefined it will use game.world.
+* @param {*} parent - The parent Group, DisplayObject or DisplayObjectContainer that will hold this group. 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).
*/
@@ -31,6 +31,8 @@ Phaser.Group = function (game, parent, name, useStage) {
*/
this.name = name || 'group';
+ PIXI.DisplayObjectContainer.call(this);
+
if (typeof useStage === 'undefined')
{
useStage = false;
@@ -38,29 +40,26 @@ Phaser.Group = function (game, parent, name, useStage) {
if (useStage)
{
- this._container = this.game.stage._stage;
+ // this._container = this.game.stage._stage;
}
else
{
- this._container = new PIXI.DisplayObjectContainer();
- this._container.name = this.name;
-
if (parent)
{
- if (parent instanceof Phaser.Group)
- {
- parent._container.addChild(this._container);
- }
- else
- {
- parent.addChild(this._container);
- parent.updateTransform();
- }
+ // if (parent instanceof Phaser.Group)
+ // {
+ // parent.addChild(this);
+ // }
+ // else
+ // {
+ parent.addChild(this);
+ // parent.updateTransform();
+ // }
}
else
{
- this.game.stage._stage.addChild(this._container);
- this.game.stage._stage.updateTransform();
+ this.game.stage._stage.addChild(this);
+ // this.game.stage._stage.updateTransform();
}
}
@@ -77,7 +76,7 @@ Phaser.Group = function (game, parent, name, useStage) {
this.alive = true;
/**
- * @property {boolean} exists - If exists is true the the Group is updated, otherwise it is skipped.
+ * @property {boolean} exists - If exists is true the Group is updated, otherwise it is skipped.
* @default
*/
this.exists = true;
@@ -88,17 +87,17 @@ Phaser.Group = function (game, parent, name, useStage) {
this.group = null;
// Replaces the PIXI.Point with a slightly more flexible one.
- this._container.scale = new Phaser.Point(1, 1);
+ // this._container.scale = new Phaser.Point(1, 1);
/**
* @property {Phaser.Point} scale - The scane of the Group container.
*/
- this.scale = this._container.scale;
+ // this.scale = this._container.scale;
/**
* @property {Phaser.Point} pivot - The pivot point of the Group container.
*/
- this.pivot = this._container.pivot;
+ // 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.
@@ -107,8 +106,13 @@ Phaser.Group = function (game, parent, name, useStage) {
*/
this.cursor = null;
+ this._cursorIndex = 0;
+
};
+Phaser.Group.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
+Phaser.Group.prototype.constructor = Phaser.Group;
+
/**
* @constant
* @type {number}
@@ -139,139 +143,159 @@ Phaser.Group.SORT_ASCENDING = -1;
*/
Phaser.Group.SORT_DESCENDING = 1;
-Phaser.Group.prototype = {
+// PIXI.DisplayObjectContainer.prototype.addChildAt = function(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 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.
- *
- * @see Phaser.Group#create
- * @see Phaser.Group#addAt
- * @method Phaser.Group#add
- * @param {*} child - An instance of Phaser.Sprite, Phaser.Button or any other display object..
- * @return {*} The child that was added to the Group.
- */
- add: function (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.
+*
+* @see Phaser.Group#create
+* @see Phaser.Group#addAt
+* @method Phaser.Group#add
+* @param {*} child - An instance of Phaser.Sprite, Phaser.Button or any other display object..
+* @return {*} The child that was added to the Group.
+*/
+Phaser.Group.prototype.add = function (child) {
- if (child.group !== this)
+ if (child.group !== this)
+ {
+ child.group = this;
+
+ this.addChild(child);
+
+ // child.updateTransform();
+
+ if (child.events)
{
- if (child.type && child.type === Phaser.GROUP)
- {
- child.group = this;
-
- this._container.addChild(child._container);
-
- child._container.updateTransform();
- }
- else
- {
- child.group = this;
-
- this._container.addChild(child);
-
- child.updateTransform();
-
- if (child.events)
- {
- child.events.onAddedToGroup.dispatch(child, this);
- }
- }
-
- if (this.cursor === null)
- {
- this.cursor = child;
- }
+ child.events.onAddedToGroup.dispatch(child, this);
}
+ }
- return child;
+ if (this.cursor === null)
+ {
+ this.cursor = child;
+ }
- },
+ return 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 added to the Group at the location specified by the index value, this allows you to control child ordering.
- *
- * @method Phaser.Group#addAt
- * @param {*} child - An instance of Phaser.Sprite, Phaser.Button or any other display object..
- * @param {number} index - The index within the Group to insert the child to.
- * @return {*} The child that was added to the Group.
- */
- addAt: function (child, index) {
+}
- if (child.group !== this)
+/**
+* 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.
+*
+* @method Phaser.Group#addAt
+* @param {*} child - An instance of Phaser.Sprite, Phaser.Button or any other display object..
+* @param {number} index - The index within the Group to insert the child to.
+* @return {*} The child that was added to the Group.
+*/
+Phaser.Group.prototype.addAt = function (child, index) {
+
+ if (child.group !== this)
+ {
+ child.group = this;
+
+ this.addChildAt(child, index);
+
+ // child.updateTransform();
+
+ if (child.events)
{
- if (child.type && child.type === Phaser.GROUP)
- {
- child.group = this;
-
- this._container.addChildAt(child._container, index);
-
- child._container.updateTransform();
- }
- else
- {
- child.group = this;
-
- this._container.addChildAt(child, index);
-
- child.updateTransform();
-
- if (child.events)
- {
- child.events.onAddedToGroup.dispatch(child, this);
- }
- }
-
- if (this.cursor === null)
- {
- this.cursor = child;
- }
+ child.events.onAddedToGroup.dispatch(child, this);
}
+ }
- return child;
+ if (this.cursor === null)
+ {
+ this.cursor = child;
+ }
- },
+ return child;
- /**
- * Returns the child found at the given index within this Group.
- *
- * @method Phaser.Group#getAt
- * @param {number} index - The index to return the child from.
- * @return {*} The child that was found at the given index.
- */
- getAt: function (index) {
+}
- return this._container.getChildAt(index);
+/**
+* Returns the child found at the given index within this Group.
+*
+* @method Phaser.Group#getAt
+* @param {number} index - The index to return the child from.
+* @return {*} The child that was found at the given index.
+*/
+Phaser.Group.prototype.getAt = function (index) {
- },
+ return this.getChildAt(index);
- /**
- * 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.
- *
- * @method Phaser.Group#create
- * @param {number} x - The x coordinate to display the newly created Sprite at. The value is in relation to the Group.x point.
- * @param {number} y - The y coordinate to display the newly created Sprite at. The value is in relation to the Group.y point.
- * @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.
- * @return {Phaser.Sprite} The child that was created.
- */
- create: function (x, y, key, frame, exists) {
+}
- if (typeof exists === 'undefined') { exists = true; }
+/**
+* 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.
+*
+* @method Phaser.Group#create
+* @param {number} x - The x coordinate to display the newly created Sprite at. The value is in relation to the Group.x point.
+* @param {number} y - The y coordinate to display the newly created Sprite at. The value is in relation to the Group.y point.
+* @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.
+* @return {Phaser.Sprite} The child that was created.
+*/
+Phaser.Group.prototype.create = function (x, y, key, frame, exists) {
- var child = new Phaser.Sprite(this.game, x, y, key, frame);
+ if (typeof exists === 'undefined') { exists = true; }
+
+ var child = new Phaser.Sprite(this.game, x, y, key, frame);
+
+ child.group = this;
+ child.exists = exists;
+ child.visible = exists;
+ child.alive = exists;
+
+ this.addChild(child);
+
+ // child.updateTransform();
+
+ if (child.events)
+ {
+ child.events.onAddedToGroup.dispatch(child, this);
+ }
+
+ if (this.cursor === null)
+ {
+ this.cursor = child;
+ }
+
+ return child;
+
+}
+
+/**
+* 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)
+*
+* @method Phaser.Group#createMultiple
+* @param {number} quantity - The number of Sprites to create.
+* @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=false] - The default exists state of the Sprite.
+*/
+Phaser.Group.prototype.createMultiple = function (quantity, key, frame, exists) {
+
+ if (typeof exists === 'undefined') { exists = false; }
+
+ for (var i = 0; i < quantity; i++)
+ {
+ var child = new Phaser.Sprite(this.game, 0, 0, key, frame);
child.group = this;
child.exists = exists;
child.visible = exists;
child.alive = exists;
- this._container.addChild(child);
-
- child.updateTransform();
+ this.addChild(child);
+
+ // child.updateTransform();
if (child.events)
{
@@ -283,1180 +307,878 @@ Phaser.Group.prototype = {
this.cursor = child;
}
- return child;
-
- },
-
- /**
- * 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)
- *
- * @method Phaser.Group#createMultiple
- * @param {number} quantity - The number of Sprites to create.
- * @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=false] - The default exists state of the Sprite.
- */
- createMultiple: function (quantity, key, frame, exists) {
-
- if (typeof exists === 'undefined') { exists = false; }
-
- for (var i = 0; i < quantity; i++)
- {
- var child = new Phaser.Sprite(this.game, 0, 0, key, frame);
-
- child.group = this;
- child.exists = exists;
- child.visible = exists;
- child.alive = exists;
-
- this._container.addChild(child);
-
- child.updateTransform();
-
- if (child.events)
- {
- child.events.onAddedToGroup.dispatch(child, this);
- }
-
- if (this.cursor === null)
- {
- this.cursor = child;
- }
-
- }
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#next
- */
- next: function () {
-
- if (this.cursor)
- {
- // Wrap the cursor?
- if (this.cursor == this._container.last)
- {
- this.cursor = this._container._iNext;
- }
- else
- {
- this.cursor = this.cursor._iNext;
- }
- }
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#previous
- */
- previous: function () {
-
- if (this.cursor)
- {
- // Wrap the cursor?
- if (this.cursor == this._container._iNext)
- {
- this.cursor = this._container.last;
- }
- else
- {
- this.cursor = this.cursor._iPrev;
- }
- }
-
- },
-
- /**
- * Internal test.
- *
- * @method Phaser.Group#childTest
- */
- childTest: function (prefix, child) {
-
- var s = prefix + ' next: ';
-
- if (child._iNext)
- {
- s = s + child._iNext.name;
- }
- else
- {
- s = s + '-null-';
- }
-
- s = s + ' ' + prefix + ' prev: ';
-
- if (child._iPrev)
- {
- s = s + child._iPrev.name;
- }
- else
- {
- s = s + '-null-';
- }
-
- console.log(s);
-
- },
-
- /**
- * Internal test.
- *
- * @method Phaser.Group#swapIndex
- */
- swapIndex: function (index1, index2) {
-
- var child1 = this.getAt(index1);
- var child2 = this.getAt(index2);
-
- this.swap(child1, child2);
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#swap
- * @param {*} child1 - The first child to swap.
- * @param {*} child2 - The second child to swap.
- * @return {boolean} True if the swap was successful, otherwise false.
- */
- swap: function (child1, child2) {
-
- if (child1 === child2 || !child1.parent || !child2.parent || child1.group !== this || child2.group !== this)
- {
- return false;
- }
-
- // Cache the values
- var child1Prev = child1._iPrev;
- var child1Next = child1._iNext;
- var child2Prev = child2._iPrev;
- var child2Next = child2._iNext;
-
- var endNode = this._container.last._iNext;
- var currentNode = this.game.stage._stage;
-
- do
- {
- if (currentNode !== child1 && currentNode !== child2)
- {
- if (currentNode.first === child1)
- {
- currentNode.first = child2;
- }
- else if (currentNode.first === child2)
- {
- currentNode.first = child1;
- }
-
- if (currentNode.last === child1)
- {
- currentNode.last = child2;
- }
- else if (currentNode.last === child2)
- {
- currentNode.last = child1;
- }
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != endNode)
-
- if (child1._iNext == child2)
- {
- // This is a downward (A to B) neighbour swap
- child1._iNext = child2Next;
- child1._iPrev = child2;
- child2._iNext = child1;
- child2._iPrev = child1Prev;
-
- if (child1Prev) { child1Prev._iNext = child2; }
- if (child2Next) { child2Next._iPrev = child1; }
-
- if (child1.__renderGroup)
- {
- child1.__renderGroup.updateTexture(child1);
- }
-
- if (child2.__renderGroup)
- {
- child2.__renderGroup.updateTexture(child2);
- }
-
- return true;
- }
- else if (child2._iNext == child1)
- {
- // This is an upward (B to A) neighbour swap
- child1._iNext = child2;
- child1._iPrev = child2Prev;
- child2._iNext = child1Next;
- child2._iPrev = child1;
-
- if (child2Prev) { child2Prev._iNext = child1; }
- if (child1Next) { child1Next._iPrev = child2; }
-
- if (child1.__renderGroup)
- {
- child1.__renderGroup.updateTexture(child1);
- }
-
- if (child2.__renderGroup)
- {
- child2.__renderGroup.updateTexture(child2);
- }
-
- return true;
- }
- else
- {
- // Children are far apart
- child1._iNext = child2Next;
- child1._iPrev = child2Prev;
- child2._iNext = child1Next;
- child2._iPrev = child1Prev;
-
- if (child1Prev) { child1Prev._iNext = child2; }
- if (child1Next) { child1Next._iPrev = child2; }
- if (child2Prev) { child2Prev._iNext = child1; }
- if (child2Next) { child2Next._iPrev = child1; }
-
- if (child1.__renderGroup)
- {
- child1.__renderGroup.updateTexture(child1);
- }
-
- if (child2.__renderGroup)
- {
- child2.__renderGroup.updateTexture(child2);
- }
-
- return true;
- }
-
- return false;
-
- },
-
- /**
- * Brings the given child to the top of this Group so it renders above all other children.
- *
- * @method Phaser.Group#bringToTop
- * @param {*} child - The child to bring to the top of this Group.
- * @return {*} The child that was moved.
- */
- bringToTop: function (child) {
-
- if (child.group === this)
- {
- this.remove(child);
- this.add(child);
- }
-
- return child;
-
- },
-
- /**
- * Get the index position of the given child in this Group.
- *
- * @method Phaser.Group#getIndex
- * @param {*} child - The child to get the index for.
- * @return {number} The index of the child or -1 if it's not a member of this Group.
- */
- getIndex: function (child) {
-
- return this._container.children.indexOf(child);
-
- },
-
- /**
- * Replaces a child of this Group with the given newChild. The newChild cannot be a member of this Group.
- *
- * @method Phaser.Group#replace
- * @param {*} oldChild - The child in this Group that will be replaced.
- * @param {*} newChild - The child to be inserted into this group.
- */
- replace: function (oldChild, newChild) {
-
- if (!this._container.first._iNext)
- {
- return;
- }
-
- var index = this.getIndex(oldChild);
-
- if (index != -1)
- {
- if (newChild.parent !== undefined)
- {
- newChild.events.onRemovedFromGroup.dispatch(newChild, this);
- newChild.parent.removeChild(newChild);
- }
-
- this._container.removeChild(oldChild);
- this._container.addChildAt(newChild, index);
-
- newChild.events.onAddedToGroup.dispatch(newChild, this);
- newChild.updateTransform();
-
- if (this.cursor == oldChild)
- {
- this.cursor = this._container._iNext;
- }
- }
-
- },
-
- /**
- * Sets the given property to the given value on the child. The operation controls the assignment of the value.
- *
- * @method Phaser.Group#setProperty
- * @param {*} child - The child to set the property value on.
- * @param {array} key - An array of strings that make up the property that will be set.
- * @param {*} value - The value that will be set.
- * @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.
- */
- setProperty: function (child, key, value, operation) {
-
- operation = operation || 0;
-
- // As ugly as this approach looks, and although it's limited to a depth of only 4, it's extremely fast.
- // Much faster than a for loop or object iteration. There are no checks, so if the key isn't valid then it'll fail
- // but as you are likely to call this from inner loops that have to perform well, I'll take that trade off.
-
- // 0 = Equals
- // 1 = Add
- // 2 = Subtract
- // 3 = Multiply
- // 4 = Divide
-
- var len = key.length;
-
- if (len == 1)
- {
- if (operation === 0) { child[key[0]] = value; }
- else if (operation == 1) { child[key[0]] += value; }
- else if (operation == 2) { child[key[0]] -= value; }
- else if (operation == 3) { child[key[0]] *= value; }
- else if (operation == 4) { child[key[0]] /= value; }
- }
- else if (len == 2)
- {
- if (operation === 0) { child[key[0]][key[1]] = value; }
- else if (operation == 1) { child[key[0]][key[1]] += value; }
- else if (operation == 2) { child[key[0]][key[1]] -= value; }
- else if (operation == 3) { child[key[0]][key[1]] *= value; }
- else if (operation == 4) { child[key[0]][key[1]] /= value; }
- }
- else if (len == 3)
- {
- if (operation === 0) { child[key[0]][key[1]][key[2]] = value; }
- else if (operation == 1) { child[key[0]][key[1]][key[2]] += value; }
- else if (operation == 2) { child[key[0]][key[1]][key[2]] -= value; }
- else if (operation == 3) { child[key[0]][key[1]][key[2]] *= value; }
- else if (operation == 4) { child[key[0]][key[1]][key[2]] /= value; }
- }
- else if (len == 4)
- {
- if (operation === 0) { child[key[0]][key[1]][key[2]][key[3]] = value; }
- else if (operation == 1) { child[key[0]][key[1]][key[2]][key[3]] += value; }
- else if (operation == 2) { child[key[0]][key[1]][key[2]][key[3]] -= value; }
- else if (operation == 3) { child[key[0]][key[1]][key[2]][key[3]] *= value; }
- else if (operation == 4) { child[key[0]][key[1]][key[2]][key[3]] /= value; }
- }
-
- // TODO - Deep property scane
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#setAll
- * @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 only children with alive=true will be updated.
- * @param {boolean} [checkVisible=false] - If set then only children with visible=true will be updated.
- * @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.
- */
- setAll: function (key, value, checkAlive, checkVisible, operation) {
-
- key = key.split('.');
-
- if (typeof checkAlive === 'undefined') { checkAlive = false; }
- if (typeof checkVisible === 'undefined') { checkVisible = false; }
-
- operation = operation || 0;
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if ((checkAlive === false || (checkAlive && currentNode.alive)) && (checkVisible === false || (checkVisible && currentNode.visible)))
- {
- this.setProperty(currentNode, key, value, operation);
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext)
- }
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#addAll
- * @param {string} property - The property to increment, for example 'body.velocity.x' or 'angle'.
- * @param {number} amount - The amount to increment the property by. If child.x = 10 then addAll('x', 40) would make child.x = 50.
- * @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
- * @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
- */
- addAll: function (property, amount, checkAlive, checkVisible) {
-
- this.setAll(property, amount, checkAlive, checkVisible, 1);
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#subAll
- * @param {string} property - The property to decrement, for example 'body.velocity.x' or 'angle'.
- * @param {number} amount - The amount to subtract from the property. If child.x = 50 then subAll('x', 40) would make child.x = 10.
- * @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
- * @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
- */
- subAll: function (property, amount, checkAlive, checkVisible) {
-
- this.setAll(property, amount, checkAlive, checkVisible, 2);
-
- },
-
- /**
- * Multiplies the given property by the amount on all children in this Group.
- * Group.multiplyAll('x', 2) will x2 the child.x value.
- *
- * @method Phaser.Group#multiplyAll
- * @param {string} property - The property to multiply, for example 'body.velocity.x' or 'angle'.
- * @param {number} amount - The amount to multiply the property by. If child.x = 10 then multiplyAll('x', 2) would make child.x = 20.
- * @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
- * @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
- */
- multiplyAll: function (property, amount, checkAlive, checkVisible) {
-
- this.setAll(property, amount, checkAlive, checkVisible, 3);
-
- },
-
- /**
- * Divides the given property by the amount on all children in this Group.
- * Group.divideAll('x', 2) will half the child.x value.
- *
- * @method Phaser.Group#divideAll
- * @param {string} property - The property to divide, for example 'body.velocity.x' or 'angle'.
- * @param {number} amount - The amount to divide the property by. If child.x = 100 then divideAll('x', 2) would make child.x = 50.
- * @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
- * @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
- */
- divideAll: function (property, amount, checkAlive, checkVisible) {
-
- this.setAll(property, amount, checkAlive, checkVisible, 4);
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#callAllExists
- * @param {function} callback - The function that exists on the children that will be called.
- * @param {boolean} existsValue - Only children with exists=existsValue will be called.
- * @param {...*} parameter - Additional parameters that will be passed to the callback.
- */
- callAllExists: function (callback, existsValue) {
-
- var args = Array.prototype.splice.call(arguments, 2);
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.exists == existsValue && currentNode[callback])
- {
- currentNode[callback].apply(currentNode, args);
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext)
-
- }
-
- },
-
- /**
- * 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.
- * @param {array} callback - The array of function names.
- * @param {number} length - The size of the array (pre-calculated in callAll).
- * @protected
- */
- callbackFromArray: function (child, callback, length) {
-
- // Kinda looks like a Christmas tree
-
- if (length == 1)
- {
- if (child[callback[0]])
- {
- return child[callback[0]];
- }
- }
- else if (length == 2)
- {
- if (child[callback[0]][callback[1]])
- {
- return child[callback[0]][callback[1]];
- }
- }
- else if (length == 3)
- {
- if (child[callback[0]][callback[1]][callback[2]])
- {
- return child[callback[0]][callback[1]][callback[2]];
- }
- }
- else if (length == 4)
- {
- if (child[callback[0]][callback[1]][callback[2]][callback[3]])
- {
- return child[callback[0]][callback[1]][callback[2]][callback[3]];
- }
- }
- else
- {
- if (child[callback])
- {
- return child[callback];
- }
- }
-
- return false;
-
- },
-
- /**
- * 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.
- *
- * @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=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) {
-
- if (typeof method === 'undefined')
- {
- return;
- }
-
- // Extract the method into an array
- method = method.split('.');
-
- var methodLength = method.length;
-
- if (typeof context === 'undefined')
- {
- context = null;
- }
- else
- {
- // Extract the context into an array
- if (typeof context === 'string')
- {
- context = context.split('.');
- var contextLength = context.length;
- }
- }
-
- var args = Array.prototype.splice.call(arguments, 2);
- var callback = null;
- var callbackContext = null;
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var child = this._container.first._iNext;
-
- do
- {
- callback = this.callbackFromArray(child, method, methodLength);
-
- if (context && callback)
- {
- callbackContext = this.callbackFromArray(child, context, contextLength);
-
- if (callback)
- {
- callback.apply(callbackContext, args);
- }
- }
- else if (callback)
- {
- callback.apply(child, args);
- }
-
- child = child._iNext;
- }
- while (child != this._container.last._iNext)
-
- }
-
- },
-
- /**
- * 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.
- * @param {Object} callbackContext - The context in which the function should be called (usually 'this').
- * @param {boolean} checkExists - If set only children with exists=true will be passed to the callback, otherwise all children will be passed.
- */
- forEach: function (callback, callbackContext, checkExists) {
-
- if (typeof checkExists === 'undefined')
- {
- checkExists = false;
- }
-
- var args = Array.prototype.splice.call(arguments, 3);
- args.unshift(null);
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (checkExists === false || (checkExists && currentNode.exists))
- {
- args[0] = currentNode;
- callback.apply(callbackContext, args);
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
-
- }
-
- },
-
- /**
- * 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)
- *
- * @method Phaser.Group#forEachAlive
- * @param {function} callback - The function that will be called. 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').
- */
- forEachExists: function (callback, callbackContext) {
-
- var args = Array.prototype.splice.call(arguments, 2);
- args.unshift(null);
-
- this.iterate('exists', true, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
-
- },
-
- /**
- * 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)
- *
- * @method Phaser.Group#forEachAlive
- * @param {function} callback - The function that will be called. 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').
- */
- forEachAlive: function (callback, callbackContext) {
-
- var args = Array.prototype.splice.call(arguments, 2);
- args.unshift(null);
-
- this.iterate('alive', true, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
-
- },
-
- /**
- * 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)
- *
- * @method Phaser.Group#forEachDead
- * @param {function} callback - The function that will be called. 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').
- */
- forEachDead: function (callback, callbackContext) {
-
- var args = Array.prototype.splice.call(arguments, 2);
- args.unshift(null);
-
- this.iterate('alive', false, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
-
- },
-
- /**
- * 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()`.
- *
- * @method Phaser.Group#sort
- * @param {string} [index='y'] - The `string` name of the property you want to sort on.
- * @param {number} [order=Phaser.Group.SORT_ASCENDING] - The `Group` constant that defines the sort order. Possible values are Phaser.Group.SORT_ASCENDING and Phaser.Group.SORT_DESCENDING.
- */
- sort: function (index, order) {
-
- if (typeof index === 'undefined') { index = 'y'; }
- if (typeof order === 'undefined') { order = Phaser.Group.SORT_ASCENDING; }
-
- var swapped;
- var temp;
-
- do {
-
- swapped = false;
-
- for (var i = 0, len = this._container.children.length - 1; i < len; i++)
- {
- if (order == Phaser.Group.SORT_ASCENDING)
- {
- if (this._container.children[i][index] > this._container.children[i + 1][index])
- {
- this.swap(this.getAt(i), this.getAt(i + 1));
- temp = this._container.children[i];
- this._container.children[i] = this._container.children[i + 1];
- this._container.children[i + 1] = temp;
- swapped = true;
- }
- }
- else
- {
- if (this._container.children[i][index] < this._container.children[i + 1][index])
- {
- this.swap(this.getAt(i), this.getAt(i + 1));
- temp = this._container.children[i];
- this._container.children[i] = this._container.children[i + 1];
- this._container.children[i + 1] = temp;
- swapped = true;
- }
- }
- }
- } while (swapped);
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#iterate
- * @param {string} key - The child property to check, i.e. 'exists', 'alive', 'health'
- * @param {any} value - If child.key === this value it will be considered a match. Note that a strict comparison is used.
- * @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)
- {
- return 0;
- }
-
- if (typeof callback === 'undefined')
- {
- callback = false;
- }
-
- var total = 0;
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode[key] === value)
- {
- total++;
-
- if (callback)
- {
- args[0] = currentNode;
- callback.apply(callbackContext, args);
- }
-
- if (returnType === Phaser.Group.RETURN_CHILD)
- {
- return currentNode;
- }
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
-
- if (returnType === Phaser.Group.RETURN_TOTAL)
- {
- return total;
- }
- else if (returnType === Phaser.Group.RETURN_CHILD)
- {
- return null;
- }
-
- },
-
- /**
- * Call this function to retrieve the first object with exists == (the given state) in the Group.
- *
- * @method Phaser.Group#getFirstExists
- * @param {boolean} state - True or false.
- * @return {Any} The first child, or null if none found.
- */
- getFirstExists: function (state) {
-
- if (typeof state !== 'boolean')
- {
- state = true;
- }
-
- return this.iterate('exists', state, Phaser.Group.RETURN_CHILD);
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#getFirstAlive
- * @return {Any} The first alive child, or null if none found.
- */
- getFirstAlive: function () {
-
- return this.iterate('alive', true, Phaser.Group.RETURN_CHILD);
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#getFirstDead
- * @return {Any} The first dead child, or null if none found.
- */
- getFirstDead: function () {
-
- return this.iterate('alive', false, Phaser.Group.RETURN_CHILD);
-
- },
-
- /**
- * 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.
- */
- countLiving: function () {
-
- return this.iterate('alive', true, Phaser.Group.RETURN_TOTAL);
-
- },
-
- /**
- * 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.
- */
- countDead: function () {
-
- return this.iterate('alive', false, Phaser.Group.RETURN_TOTAL);
-
- },
-
- /**
- * Returns a member at random from the group.
- *
- * @method Phaser.Group#getRandom
- * @param {number} startIndex - Optional offset off the front of the array. Default value is 0, or the beginning of the array.
- * @param {number} length - Optional restriction on the number of values you want to randomly select from.
- * @return {Any} A random child of this Group.
- */
- getRandom: function (startIndex, length) {
-
- if (this._container.children.length === 0)
- {
- return null;
- }
-
- startIndex = startIndex || 0;
- length = length || this._container.children.length;
-
- return this.game.math.getRandom(this._container.children, startIndex, length);
-
- },
-
- /**
- * Removes the given child from this Group and sets its group property to null.
- *
- * @method Phaser.Group#remove
- * @param {Any} child - The child to remove.
- * @return {boolean} true if the child was removed from this Group, otherwise false.
- */
- remove: function (child) {
-
- if (child.group !== this)
- {
- return false;
- }
-
- if (child.events)
- {
- child.events.onRemovedFromGroup.dispatch(child, this);
- }
-
- // Check it's actually in the container
- if (child.parent === this._container)
- {
- this._container.removeChild(child);
- }
-
- if (this.cursor == child)
- {
- if (this._container._iNext)
- {
- this.cursor = this._container._iNext;
- }
- else
- {
- this.cursor = null;
- }
- }
-
- child.group = null;
-
- return true;
-
- },
-
- /**
- * Removes all children from this Group, setting all group properties to null.
- * The Group container remains on the display list.
- *
- * @method Phaser.Group#removeAll
- */
- removeAll: function () {
-
- if (this._container.children.length === 0)
- {
- return;
- }
-
- do
- {
- if (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;
-
- },
-
- /**
- * Removes all children from this Group whos index falls beteen the given startIndex and endIndex values.
- *
- * @method Phaser.Group#removeBetween
- * @param {number} startIndex - The index to start removing children from.
- * @param {number} endIndex - The index to stop removing children from. Must be higher than startIndex and less than the length of the Group.
- */
- removeBetween: function (startIndex, endIndex) {
-
- if (this._container.children.length === 0)
- {
- return;
- }
-
- if (startIndex > endIndex || startIndex < 0 || endIndex > this._container.children.length)
- {
- return false;
- }
-
- for (var i = startIndex; i < endIndex; i++)
- {
- var child = this._container.children[i];
- child.events.onRemovedFromGroup.dispatch(child, this);
- this._container.removeChild(child);
-
- if (this.cursor == child)
- {
- if (this._container._iNext)
- {
- this.cursor = this._container._iNext;
- }
- else
- {
- this.cursor = null;
- }
- }
- }
-
- },
-
- /**
- * 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 (destroyChildren) {
-
- 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;
-
- this.game = null;
-
- this.exists = false;
-
- this.cursor = null;
-
- },
-
- validate: function () {
-
- var testObject = this.game.stage._stage.last._iNext;
- var displayObject = this.game.stage._stage;
- var nextObject = null;
- var prevObject = null;
- var count = 0;
-
- do
- {
- if (count > 0)
- {
- // check next
- if (displayObject !== nextObject)
- {
- console.log('check next fail');
- return false;
- }
-
- // check previous
- if (displayObject._iPrev !== prevObject)
- {
- console.log('check previous fail');
- return false;
- }
- }
-
- // Set the next object
- nextObject = displayObject._iNext;
- prevObject = displayObject;
-
- displayObject = displayObject._iNext;
-
- count++;
-
- }
- while(displayObject != testObject)
-
- return true;
-
}
-};
+}
-Phaser.Group.prototype.constructor = Phaser.Group;
+/**
+* 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.
+*
+* @method Phaser.Group#next
+*/
+Phaser.Group.prototype.next = function () {
+
+ if (this.cursor)
+ {
+ // Wrap the cursor?
+ if (this._cursorIndex === this.children.length)
+ {
+ this._cursorIndex = 0;
+ }
+ else
+ {
+ this._cursorIndex++;
+ }
+
+ this.cursor = this.children[this._cursorIndex];
+ }
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#previous
+*/
+Phaser.Group.prototype.previous = function () {
+
+ if (this.cursor)
+ {
+ // Wrap the cursor?
+ if (this._cursorIndex === 0)
+ {
+ this._cursorIndex = this.children.length - 1;
+ }
+ else
+ {
+ this._cursorIndex--;
+ }
+
+ this.cursor = this.children[this._cursorIndex];
+ }
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#swap
+* @param {*} child1 - The first child to swap.
+* @param {*} child2 - The second child to swap.
+*/
+Phaser.Group.prototype.swap = function (child1, child2) {
+
+ if (child1 === child2 || !child1.parent || !child2.parent || child1.group !== this || child2.group !== this)
+ {
+ return false;
+ }
+
+ this.swapChildren(child1, child2);
+
+}
+
+/**
+* Brings the given child to the top of this Group so it renders above all other children.
+*
+* @method Phaser.Group#bringToTop
+* @param {*} child - The child to bring to the top of this Group.
+* @return {*} The child that was moved.
+*/
+Phaser.Group.prototype.bringToTop = function (child) {
+
+ if (child.group === this)
+ {
+ this.remove(child);
+ this.add(child);
+ }
+
+ return child;
+
+}
+
+/**
+* Get the index position of the given child in this Group.
+*
+* @method Phaser.Group#getIndex
+* @param {*} child - The child to get the index for.
+* @return {number} The index of the child or -1 if it's not a member of this Group.
+*/
+Phaser.Group.prototype.getIndex = function (child) {
+
+ return this.children.indexOf(child);
+
+}
+
+/**
+* Replaces a child of this Group with the given newChild. The newChild cannot be a member of this Group.
+*
+* @method Phaser.Group#replace
+* @param {*} oldChild - The child in this Group that will be replaced.
+* @param {*} newChild - The child to be inserted into this group.
+*/
+Phaser.Group.prototype.replace = function (oldChild, newChild) {
+
+ var index = this.getIndex(oldChild);
+
+ if (index !== -1)
+ {
+ if (newChild.parent !== undefined)
+ {
+ newChild.events.onRemovedFromGroup.dispatch(newChild, this);
+ newChild.parent.removeChild(newChild);
+ }
+
+ this.removeChild(oldChild);
+ this.addChildAt(newChild, index);
+
+ newChild.events.onAddedToGroup.dispatch(newChild, this);
+ // newChild.updateTransform();
+
+ if (this.cursor === oldChild)
+ {
+ this.cursor = newChild;
+ }
+ }
+
+}
+
+/**
+* Sets the given property to the given value on the child. The operation controls the assignment of the value.
+*
+* @method Phaser.Group#setProperty
+* @param {*} child - The child to set the property value on.
+* @param {array} key - An array of strings that make up the property that will be set.
+* @param {*} value - The value that will be set.
+* @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.
+*/
+Phaser.Group.prototype.setProperty = function (child, key, value, operation) {
+
+ operation = operation || 0;
+
+ // As ugly as this approach looks, and although it's limited to a depth of only 4, it's extremely fast.
+ // Much faster than a for loop or object iteration. There are no checks, so if the key isn't valid then it'll fail
+ // but as you are likely to call this from inner loops that have to perform well, I'll take that trade off.
+
+ // 0 = Equals
+ // 1 = Add
+ // 2 = Subtract
+ // 3 = Multiply
+ // 4 = Divide
+
+ var len = key.length;
+
+ if (len == 1)
+ {
+ if (operation === 0) { child[key[0]] = value; }
+ else if (operation == 1) { child[key[0]] += value; }
+ else if (operation == 2) { child[key[0]] -= value; }
+ else if (operation == 3) { child[key[0]] *= value; }
+ else if (operation == 4) { child[key[0]] /= value; }
+ }
+ else if (len == 2)
+ {
+ if (operation === 0) { child[key[0]][key[1]] = value; }
+ else if (operation == 1) { child[key[0]][key[1]] += value; }
+ else if (operation == 2) { child[key[0]][key[1]] -= value; }
+ else if (operation == 3) { child[key[0]][key[1]] *= value; }
+ else if (operation == 4) { child[key[0]][key[1]] /= value; }
+ }
+ else if (len == 3)
+ {
+ if (operation === 0) { child[key[0]][key[1]][key[2]] = value; }
+ else if (operation == 1) { child[key[0]][key[1]][key[2]] += value; }
+ else if (operation == 2) { child[key[0]][key[1]][key[2]] -= value; }
+ else if (operation == 3) { child[key[0]][key[1]][key[2]] *= value; }
+ else if (operation == 4) { child[key[0]][key[1]][key[2]] /= value; }
+ }
+ else if (len == 4)
+ {
+ if (operation === 0) { child[key[0]][key[1]][key[2]][key[3]] = value; }
+ else if (operation == 1) { child[key[0]][key[1]][key[2]][key[3]] += value; }
+ else if (operation == 2) { child[key[0]][key[1]][key[2]][key[3]] -= value; }
+ else if (operation == 3) { child[key[0]][key[1]][key[2]][key[3]] *= value; }
+ else if (operation == 4) { child[key[0]][key[1]][key[2]][key[3]] /= value; }
+ }
+
+ // TODO - Deep property scane
+
+}
+
+/**
+* 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.
+*/
+Phaser.Group.prototype.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.
+*
+* @method Phaser.Group#setAll
+* @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 only children with alive=true will be updated.
+* @param {boolean} [checkVisible=false] - If set then only children with visible=true will be updated.
+* @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.
+*/
+Phaser.Group.prototype.setAll = function (key, value, checkAlive, checkVisible, operation) {
+
+ key = key.split('.');
+
+ if (typeof checkAlive === 'undefined') { checkAlive = false; }
+ if (typeof checkVisible === 'undefined') { checkVisible = false; }
+
+ operation = operation || 0;
+
+ for (var i = 0, len = this.children.length; i < len; i++)
+ {
+ if ((!checkAlive || (checkAlive && this.children[i].alive)) && (!checkVisible || (checkVisible && this.children[i].visible)))
+ {
+ this.setProperty(this.children[i], key, value, operation);
+ }
+ }
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#addAll
+* @param {string} property - The property to increment, for example 'body.velocity.x' or 'angle'.
+* @param {number} amount - The amount to increment the property by. If child.x = 10 then addAll('x', 40) would make child.x = 50.
+* @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
+* @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
+*/
+Phaser.Group.prototype.addAll = function (property, amount, checkAlive, checkVisible) {
+
+ this.setAll(property, amount, checkAlive, checkVisible, 1);
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#subAll
+* @param {string} property - The property to decrement, for example 'body.velocity.x' or 'angle'.
+* @param {number} amount - The amount to subtract from the property. If child.x = 50 then subAll('x', 40) would make child.x = 10.
+* @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
+* @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
+*/
+Phaser.Group.prototype.subAll = function (property, amount, checkAlive, checkVisible) {
+
+ this.setAll(property, amount, checkAlive, checkVisible, 2);
+
+}
+
+/**
+* Multiplies the given property by the amount on all children in this Group.
+* Group.multiplyAll('x', 2) will x2 the child.x value.
+*
+* @method Phaser.Group#multiplyAll
+* @param {string} property - The property to multiply, for example 'body.velocity.x' or 'angle'.
+* @param {number} amount - The amount to multiply the property by. If child.x = 10 then multiplyAll('x', 2) would make child.x = 20.
+* @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
+* @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
+*/
+Phaser.Group.prototype.multiplyAll = function (property, amount, checkAlive, checkVisible) {
+
+ this.setAll(property, amount, checkAlive, checkVisible, 3);
+
+}
+
+/**
+* Divides the given property by the amount on all children in this Group.
+* Group.divideAll('x', 2) will half the child.x value.
+*
+* @method Phaser.Group#divideAll
+* @param {string} property - The property to divide, for example 'body.velocity.x' or 'angle'.
+* @param {number} amount - The amount to divide the property by. If child.x = 100 then divideAll('x', 2) would make child.x = 50.
+* @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
+* @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
+*/
+Phaser.Group.prototype.divideAll = function (property, amount, checkAlive, checkVisible) {
+
+ this.setAll(property, amount, checkAlive, checkVisible, 4);
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#callAllExists
+* @param {function} callback - The function that exists on the children that will be called.
+* @param {boolean} existsValue - Only children with exists=existsValue will be called.
+* @param {...*} parameter - Additional parameters that will be passed to the callback.
+*/
+Phaser.Group.prototype.callAllExists = function (callback, existsValue) {
+
+ var args = Array.prototype.splice.call(arguments, 2);
+
+ for (var i = 0, len = this.children.length; i < len; i++)
+ {
+ if (this.children[i].exists === existsValue && this.children[i][callback])
+ {
+ this.children[i][callback].apply(this.children[i], args);
+ }
+ }
+
+}
+
+/**
+* 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.
+* @param {array} callback - The array of function names.
+* @param {number} length - The size of the array (pre-calculated in callAll).
+* @protected
+*/
+Phaser.Group.prototype.callbackFromArray = function (child, callback, length) {
+
+ // Kinda looks like a Christmas tree
+
+ if (length == 1)
+ {
+ if (child[callback[0]])
+ {
+ return child[callback[0]];
+ }
+ }
+ else if (length == 2)
+ {
+ if (child[callback[0]][callback[1]])
+ {
+ return child[callback[0]][callback[1]];
+ }
+ }
+ else if (length == 3)
+ {
+ if (child[callback[0]][callback[1]][callback[2]])
+ {
+ return child[callback[0]][callback[1]][callback[2]];
+ }
+ }
+ else if (length == 4)
+ {
+ if (child[callback[0]][callback[1]][callback[2]][callback[3]])
+ {
+ return child[callback[0]][callback[1]][callback[2]][callback[3]];
+ }
+ }
+ else
+ {
+ if (child[callback])
+ {
+ return child[callback];
+ }
+ }
+
+ return false;
+
+}
+
+/**
+* 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.
+*
+* @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=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.
+*/
+Phaser.Group.prototype.callAll = function (method, context) {
+
+ if (typeof method === 'undefined')
+ {
+ return;
+ }
+
+ // Extract the method into an array
+ method = method.split('.');
+
+ var methodLength = method.length;
+
+ if (typeof context === 'undefined')
+ {
+ context = null;
+ }
+ else
+ {
+ // Extract the context into an array
+ if (typeof context === 'string')
+ {
+ context = context.split('.');
+ var contextLength = context.length;
+ }
+ }
+
+ var args = Array.prototype.splice.call(arguments, 2);
+ var callback = null;
+ var callbackContext = null;
+
+ for (var i = 0, len = this.children.length; i < len; i++)
+ {
+ callback = this.callbackFromArray(this.children[i], method, methodLength);
+
+ if (context && callback)
+ {
+ callbackContext = this.callbackFromArray(this.children[i], context, contextLength);
+
+ if (callback)
+ {
+ callback.apply(callbackContext, args);
+ }
+ }
+ else if (callback)
+ {
+ callback.apply(this.children[i], args);
+ }
+ }
+
+}
+
+/**
+* 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.
+* @param {Object} callbackContext - The context in which the function should be called (usually 'this').
+* @param {boolean} checkExists - If set only children with exists=true will be passed to the callback, otherwise all children will be passed.
+*/
+Phaser.Group.prototype.forEach = function (callback, callbackContext, checkExists) {
+
+ if (typeof checkExists === 'undefined')
+ {
+ checkExists = false;
+ }
+
+ var args = Array.prototype.splice.call(arguments, 3);
+ args.unshift(null);
+
+ for (var i = 0, len = this.children.length; i < len; i++)
+ {
+ if (!checkExists || (checkExists && this.children[i].exists))
+ {
+ args[0] = this.children[i];
+ callback.apply(callbackContext, args);
+ }
+ }
+
+}
+
+/**
+* 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)
+*
+* @method Phaser.Group#forEachAlive
+* @param {function} callback - The function that will be called. 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').
+*/
+Phaser.Group.prototype.forEachExists = function (callback, callbackContext) {
+
+ var args = Array.prototype.splice.call(arguments, 2);
+ args.unshift(null);
+
+ this.iterate('exists', true, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
+
+}
+
+/**
+* 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)
+*
+* @method Phaser.Group#forEachAlive
+* @param {function} callback - The function that will be called. 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').
+*/
+Phaser.Group.prototype.forEachAlive = function (callback, callbackContext) {
+
+ var args = Array.prototype.splice.call(arguments, 2);
+ args.unshift(null);
+
+ this.iterate('alive', true, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
+
+}
+
+/**
+* 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)
+*
+* @method Phaser.Group#forEachDead
+* @param {function} callback - The function that will be called. 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').
+*/
+Phaser.Group.prototype.forEachDead = function (callback, callbackContext) {
+
+ var args = Array.prototype.splice.call(arguments, 2);
+ args.unshift(null);
+
+ this.iterate('alive', false, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
+
+}
+
+/**
+* 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()`.
+*
+* @method Phaser.Group#sort
+* @param {string} [index='y'] - The `string` name of the property you want to sort on.
+* @param {number} [order=Phaser.Group.SORT_ASCENDING] - The `Group` constant that defines the sort order. Possible values are Phaser.Group.SORT_ASCENDING and Phaser.Group.SORT_DESCENDING.
+*/
+Phaser.Group.prototype.sort = function (index, order) {
+
+ if (typeof index === 'undefined') { index = 'y'; }
+ if (typeof order === 'undefined') { order = Phaser.Group.SORT_ASCENDING; }
+
+ /*
+ var swapped;
+ var temp;
+
+ do {
+
+ swapped = false;
+
+ for (var i = 0, len = this._container.children.length - 1; i < len; i++)
+ {
+ if (order == Phaser.Group.SORT_ASCENDING)
+ {
+ if (this._container.children[i][index] > this._container.children[i + 1][index])
+ {
+ this.swap(this.getAt(i), this.getAt(i + 1));
+ temp = this._container.children[i];
+ this._container.children[i] = this._container.children[i + 1];
+ this._container.children[i + 1] = temp;
+ swapped = true;
+ }
+ }
+ else
+ {
+ if (this._container.children[i][index] < this._container.children[i + 1][index])
+ {
+ this.swap(this.getAt(i), this.getAt(i + 1));
+ temp = this._container.children[i];
+ this._container.children[i] = this._container.children[i + 1];
+ this._container.children[i + 1] = temp;
+ swapped = true;
+ }
+ }
+ }
+ } while (swapped);
+ */
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#iterate
+* @param {string} key - The child property to check, i.e. 'exists', 'alive', 'health'
+* @param {any} value - If child.key === this value it will be considered a match. Note that a strict comparison is used.
+* @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.
+*/
+Phaser.Group.prototype.iterate = function (key, value, returnType, callback, callbackContext, args) {
+
+ if (returnType === Phaser.Group.RETURN_TOTAL && this.children.length === 0)
+ {
+ return 0;
+ }
+
+ if (typeof callback === 'undefined')
+ {
+ callback = false;
+ }
+
+ var total = 0;
+
+ for (var i = 0, len = this.children.length; i < len; i++)
+ {
+ if (this.children[i][key] === value)
+ {
+ total++;
+
+ if (callback)
+ {
+ args[0] = this.children[i];
+ callback.apply(callbackContext, args);
+ }
+
+ if (returnType === Phaser.Group.RETURN_CHILD)
+ {
+ return this.children[i];
+ }
+ }
+ }
+
+ if (returnType === Phaser.Group.RETURN_TOTAL)
+ {
+ return total;
+ }
+ else if (returnType === Phaser.Group.RETURN_CHILD)
+ {
+ return null;
+ }
+
+}
+
+/**
+* Call this function to retrieve the first object with exists == (the given state) in the Group.
+*
+* @method Phaser.Group#getFirstExists
+* @param {boolean} state - True or false.
+* @return {Any} The first child, or null if none found.
+*/
+Phaser.Group.prototype.getFirstExists = function (state) {
+
+ if (typeof state !== 'boolean')
+ {
+ state = true;
+ }
+
+ return this.iterate('exists', state, Phaser.Group.RETURN_CHILD);
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#getFirstAlive
+* @return {Any} The first alive child, or null if none found.
+*/
+Phaser.Group.prototype.getFirstAlive = function () {
+
+ return this.iterate('alive', true, Phaser.Group.RETURN_CHILD);
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#getFirstDead
+* @return {Any} The first dead child, or null if none found.
+*/
+Phaser.Group.prototype.getFirstDead = function () {
+
+ return this.iterate('alive', false, Phaser.Group.RETURN_CHILD);
+
+}
+
+/**
+* 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.
+*/
+Phaser.Group.prototype.countLiving = function () {
+
+ return this.iterate('alive', true, Phaser.Group.RETURN_TOTAL);
+
+}
+
+/**
+* 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.
+*/
+Phaser.Group.prototype.countDead = function () {
+
+ return this.iterate('alive', false, Phaser.Group.RETURN_TOTAL);
+
+}
+
+/**
+* Returns a member at random from the group.
+*
+* @method Phaser.Group#getRandom
+* @param {number} startIndex - Optional offset off the front of the array. Default value is 0, or the beginning of the array.
+* @param {number} length - Optional restriction on the number of values you want to randomly select from.
+* @return {Any} A random child of this Group.
+*/
+Phaser.Group.prototype.getRandom = function (startIndex, length) {
+
+ if (this.children.length === 0)
+ {
+ return null;
+ }
+
+ startIndex = startIndex || 0;
+ length = length || this.children.length;
+
+ return this.game.math.getRandom(this.children, startIndex, length);
+
+}
+
+/**
+* Removes the given child from this Group and sets its group property to null.
+*
+* @method Phaser.Group#remove
+* @param {Any} child - The child to remove.
+* @return {boolean} true if the child was removed from this Group, otherwise false.
+*/
+Phaser.Group.prototype.remove = function (child) {
+
+ if (child.group !== this)
+ {
+ return false;
+ }
+
+ if (child.events)
+ {
+ child.events.onRemovedFromGroup.dispatch(child, this);
+ }
+
+ // Check it's actually in the container
+ if (child.parent === this)
+ {
+ this.removeChild(child);
+ }
+
+ if (this.cursor === child)
+ {
+ this.next();
+ }
+
+ child.group = null;
+
+ return true;
+
+}
+
+/**
+* Removes all children from this Group, setting all group properties to null.
+* The Group container remains on the display list.
+*
+* @method Phaser.Group#removeAll
+*/
+Phaser.Group.prototype.removeAll = function () {
+
+ if (this.children.length === 0)
+ {
+ return;
+ }
+
+ do
+ {
+ if (this.children[0].events)
+ {
+ this.children[0].events.onRemovedFromGroup.dispatch(this.children[0], this);
+ }
+ this.removeChild(this.children[0]);
+ }
+ while (this.children.length > 0);
+
+ this.cursor = null;
+
+}
+
+/**
+* Removes all children from this Group whos index falls beteen the given startIndex and endIndex values.
+*
+* @method Phaser.Group#removeBetween
+* @param {number} startIndex - The index to start removing children from.
+* @param {number} endIndex - The index to stop removing children from. Must be higher than startIndex and less than the length of the Group.
+*/
+Phaser.Group.prototype.removeBetween = function (startIndex, endIndex) {
+
+ if (this.children.length === 0)
+ {
+ return;
+ }
+
+ if (startIndex > endIndex || startIndex < 0 || endIndex > this.children.length)
+ {
+ return false;
+ }
+
+ for (var i = startIndex; i < endIndex; i++)
+ {
+ var child = this.children[i];
+ child.events.onRemovedFromGroup.dispatch(child, this);
+ this.removeChild(child);
+
+ if (this.cursor === child)
+ {
+ this.cursor = null;
+ }
+ }
+
+}
+
+/**
+* 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?
+*/
+Phaser.Group.prototype.destroy = function (destroyChildren) {
+
+ if (typeof destroyChildren === 'undefined') { destroyChildren = false; }
+
+ if (destroyChildren)
+ {
+ if (this.children.length > 0)
+ {
+ do
+ {
+ if (this.children[0].group)
+ {
+ this.children[0].destroy();
+ }
+ }
+ while (this.children.length > 0);
+ }
+ }
+ else
+ {
+ this.removeAll();
+ }
+
+ this.parent.removeChild(this);
+
+ this.game = null;
+
+ this.exists = false;
+
+ this.cursor = null;
+
+}
/**
* @name Phaser.Group#total
@@ -1467,14 +1189,7 @@ Object.defineProperty(Phaser.Group.prototype, "total", {
get: function () {
- if (this._container)
- {
- return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
- }
- else
- {
- return 0;
- }
+ return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
}
@@ -1489,55 +1204,12 @@ Object.defineProperty(Phaser.Group.prototype, "length", {
get: function () {
- if (this._container)
- {
- return this._container.children.length;
- }
- else
- {
- return 0;
- }
+ return this.children.length;
}
});
-/**
-* 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.
-* @name Phaser.Group#x
-* @property {number} x - The x coordinate of the Group container.
-*/
-Object.defineProperty(Phaser.Group.prototype, "x", {
-
- get: function () {
- return this._container.position.x;
- },
-
- set: function (value) {
- this._container.position.x = value;
- }
-
-});
-
-/**
-* 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.
-* @name Phaser.Group#y
-* @property {number} y - The y coordinate of the Group container.
-*/
-Object.defineProperty(Phaser.Group.prototype, "y", {
-
- get: function () {
- return this._container.position.y;
- },
-
- set: function (value) {
- this._container.position.y = value;
- }
-
-});
-
/**
* 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.
@@ -1547,61 +1219,44 @@ Object.defineProperty(Phaser.Group.prototype, "y", {
Object.defineProperty(Phaser.Group.prototype, "angle", {
get: function() {
- return Phaser.Math.radToDeg(this._container.rotation);
+ return Phaser.Math.radToDeg(this.rotation);
},
set: function(value) {
- this._container.rotation = Phaser.Math.degToRad(value);
+ this.rotation = Phaser.Math.degToRad(value);
}
});
+// Documentation stubs
+
+/**
+* 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.
+* @name Phaser.Group#x
+* @property {number} x - The x coordinate of the Group container.
+*/
+
+/**
+* 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.
+* @name Phaser.Group#y
+* @property {number} y - The y coordinate of the Group container.
+*/
+
/**
* 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.
* @name Phaser.Group#rotation
* @property {number} rotation - The angle of rotation given in radians.
*/
-Object.defineProperty(Phaser.Group.prototype, "rotation", {
-
- get: function () {
- return this._container.rotation;
- },
-
- set: function (value) {
- this._container.rotation = value;
- }
-
-});
/**
* @name Phaser.Group#visible
* @property {boolean} visible - The visible state of the Group. Non-visible Groups and all of their children are not rendered.
*/
-Object.defineProperty(Phaser.Group.prototype, "visible", {
-
- get: function () {
- return this._container.visible;
- },
-
- set: function (value) {
- this._container.visible = value;
- }
-
-});
/**
* @name Phaser.Group#alpha
* @property {number} alpha - The alpha value of the Group container.
*/
-Object.defineProperty(Phaser.Group.prototype, "alpha", {
-
- get: function () {
- return this._container.alpha;
- },
-
- set: function (value) {
- this._container.alpha = value;
- }
-
-});
diff --git a/src/core/World.js b/src/core/World.js
index 0bb15ddd..8a341a02 100644
--- a/src/core/World.js
+++ b/src/core/World.js
@@ -54,38 +54,28 @@ Phaser.World.prototype.boot = function () {
this.camera = new Phaser.Camera(this.game, 0, 0, 0, this.game.width, this.game.height);
- this.camera.displayObject = this._container;
+ this.camera.displayObject = this;
this.game.camera = this.camera;
+ this.game.stage._stage.addChild(this);
+
}
/**
* 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
+* @method Phaser.World#preUpdate
*/
Phaser.World.prototype.preUpdate = function () {
- if (this.game.stage._stage.first._iNext)
+ for (var i = 0, len = this.children.length; i < len; i++)
{
- var currentNode = this.game.stage._stage.first._iNext;
-
- do
+ if (this.children[i]['preUpdate'])
{
- // If preUpdate exists, and it returns false, skip PIXI child objects
- if (currentNode['preUpdate'] && !currentNode.preUpdate())
- {
- currentNode = currentNode.last._iNext;
- }
- else
- {
- currentNode = currentNode._iNext;
- }
-
+ this.children[i].preUpdate();
}
- while (currentNode != this.game.stage._stage.last._iNext)
}
}
@@ -98,26 +88,12 @@ Phaser.World.prototype.preUpdate = function () {
*/
Phaser.World.prototype.update = function () {
- this.currentRenderOrderID = 0;
-
- if (this.game.stage._stage.first._iNext)
+ for (var i = 0, len = this.children.length; i < len; i++)
{
- var currentNode = this.game.stage._stage.first._iNext;
-
- do
+ if (this.children[i]['update'])
{
- // If update exists, and it returns false, skip PIXI child objects
- if (currentNode['update'] && !currentNode.update())
- {
- currentNode = currentNode.last._iNext;
- }
- else
- {
- currentNode = currentNode._iNext;
- }
-
+ this.children[i].update();
}
- while (currentNode != this.game.stage._stage.last._iNext)
}
}
@@ -138,40 +114,24 @@ Phaser.World.prototype.postUpdate = function () {
this.camera.update();
- if (this.game.stage._stage.first._iNext)
+ for (var i = 0, len = this.children.length; i < len; i++)
{
- var currentNode = this.game.stage._stage.first._iNext;
-
- do
+ if (this.children[i]['postUpdate'])
{
- if (currentNode['postUpdate'] && currentNode !== this.camera.target)
- {
- currentNode.postUpdate();
- }
-
- currentNode = currentNode._iNext;
+ this.children[i].postUpdate();
}
- while (currentNode != this.game.stage._stage.last._iNext)
}
}
else
{
this.camera.update();
- if (this.game.stage._stage.first._iNext)
+ for (var i = 0, len = this.children.length; i < len; i++)
{
- var currentNode = this.game.stage._stage.first._iNext;
-
- do
+ if (this.children[i]['postUpdate'])
{
- if (currentNode['postUpdate'])
- {
- currentNode.postUpdate();
- }
-
- currentNode = currentNode._iNext;
+ this.children[i].postUpdate();
}
- while (currentNode != this.game.stage._stage.last._iNext)
}
}
@@ -327,18 +287,3 @@ Object.defineProperty(Phaser.World.prototype, "randomY", {
});
-/**
-* @name Phaser.World#visible
-* @property {boolean} visible - Gets or sets the visible state of the World.
-*/
-Object.defineProperty(Phaser.World.prototype, "visible", {
-
- get: function () {
- return this._container.visible;
- },
-
- set: function (value) {
- this._container.visible = value;
- }
-
-});
diff --git a/src/gameobjects/RenderTexture.js b/src/gameobjects/RenderTexture.js
index 0c98b577..b6eab596 100644
--- a/src/gameobjects/RenderTexture.js
+++ b/src/gameobjects/RenderTexture.js
@@ -85,11 +85,6 @@ Phaser.RenderTexture.prototype.render = function(displayObject, position, clear,
if (typeof clear === 'undefined') { clear = false; }
if (typeof renderHidden === 'undefined') { renderHidden = false; }
- if (displayObject instanceof Phaser.Group)
- {
- displayObject = displayObject._container;
- }
-
if (PIXI.gl)
{
this.renderWebGL(displayObject, position, clear, renderHidden);
diff --git a/src/particles/arcade/Emitter.js b/src/particles/arcade/Emitter.js
index 444d30fe..e31e59ef 100644
--- a/src/particles/arcade/Emitter.js
+++ b/src/particles/arcade/Emitter.js
@@ -519,7 +519,6 @@ Phaser.Particles.Arcade.Emitter.prototype.at = function (object) {
* The emitters alpha value.
* @name Phaser.Particles.Arcade.Emitter#alpha
* @property {number} alpha - Gets or sets the alpha value of the Emitter.
-*/
Object.defineProperty(Phaser.Particles.Arcade.Emitter.prototype, "alpha", {
get: function () {
@@ -531,12 +530,12 @@ Object.defineProperty(Phaser.Particles.Arcade.Emitter.prototype, "alpha", {
}
});
+*/
/**
* The emitter visible state.
* @name Phaser.Particles.Arcade.Emitter#visible
* @property {boolean} visible - Gets or sets the Emitter visible state.
-*/
Object.defineProperty(Phaser.Particles.Arcade.Emitter.prototype, "visible", {
get: function () {
@@ -548,6 +547,7 @@ Object.defineProperty(Phaser.Particles.Arcade.Emitter.prototype, "visible", {
}
});
+*/
/**
* @name Phaser.Particles.Arcade.Emitter#x
diff --git a/src/physics/arcade/ArcadePhysics.js b/src/physics/arcade/ArcadePhysics.js
index 9e73a67c..96bbff5a 100644
--- a/src/physics/arcade/ArcadePhysics.js
+++ b/src/physics/arcade/ArcadePhysics.js
@@ -636,15 +636,15 @@ Phaser.Physics.Arcade.prototype = {
return;
}
- var len = group._container.children.length;
+ var len = group.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)
+ if (group.children[i] && group.children[j] && group.children[i].exists && group.children[j].exists)
{
- this.collideSpriteVsSprite(group._container.children[i], group._container.children[j], collideCallback, processCallback, callbackContext, overlapOnly);
+ this.collideSpriteVsSprite(group.children[i], group.children[j], collideCallback, processCallback, callbackContext, overlapOnly);
}
}
}
@@ -664,19 +664,12 @@ Phaser.Physics.Arcade.prototype = {
return;
}
- if (group1._container.first._iNext)
+ for (var i = 0, len = group1.children.length; i < len; i++)
{
- var currentNode = group1._container.first._iNext;
-
- do
+ if (group1.children[i].exists)
{
- if (currentNode.exists)
- {
- this.collideSpriteVsGroup(currentNode, group2, collideCallback, processCallback, callbackContext, overlapOnly);
- }
- currentNode = currentNode._iNext;
+ this.collideSpriteVsGroup(group1.children[i], group2, collideCallback, processCallback, callbackContext, overlapOnly);
}
- while (currentNode != group1._container.last._iNext);
}
},
@@ -746,19 +739,12 @@ Phaser.Physics.Arcade.prototype = {
return;
}
- if (group._container.first._iNext)
+ for (var i = 0, len = group.children.length; i < len; i++)
{
- var currentNode = group._container.first._iNext;
-
- do
+ if (group.children[i].exists)
{
- if (currentNode.exists)
- {
- this.collideSpriteVsTilemapLayer(currentNode, tilemapLayer, collideCallback, processCallback, callbackContext);
- }
- currentNode = currentNode._iNext;
+ this.collideSpriteVsTilemapLayer(group.children[i], tilemapLayer, collideCallback, processCallback, callbackContext);
}
- while (currentNode != group._container.last._iNext);
}
},
From 8eae8feeccac50c076c66cab4cf7036270f48162 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Thu, 6 Feb 2014 03:34:27 +0000
Subject: [PATCH 05/26] More Group fixes to the new format. Updated list of
included Pixi files to remove un-needed ones.
---
build/config.php | 62 ++++++------
examples/_site/view_full.html | 94 ++++++++++++-------
examples/_site/view_lite.html | 93 +++++++++++-------
examples/assets/audio/protracker/shampoo.mod | Bin 0 -> 25658 bytes
examples/audio/protracker.js | 3 +-
examples/groups/bring a group to top.js | 4 +-
examples/index.html | 4 +-
examples/sideview.html | 2 +-
examples/wip/pixi1.js | 2 +
examples/wip/pixi2.js | 88 +++++++++++++++++
src/core/Group.js | 82 +++-------------
src/utils/Utils.js | 60 +++++++++++-
12 files changed, 320 insertions(+), 174 deletions(-)
create mode 100644 examples/assets/audio/protracker/shampoo.mod
create mode 100644 examples/wip/pixi2.js
diff --git a/build/config.php b/build/config.php
index 77ba03a8..59c48231 100644
--- a/build/config.php
+++ b/build/config.php
@@ -6,6 +6,41 @@
$path = '..';
}
+/*
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+*/
+
echo <<
@@ -28,10 +63,7 @@
-
-
-
@@ -56,33 +88,9 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
diff --git a/examples/_site/view_full.html b/examples/_site/view_full.html
index 6e1a2d57..33314ad8 100644
--- a/examples/_site/view_full.html
+++ b/examples/_site/view_full.html
@@ -17,48 +17,76 @@
-
+
-
+
+
+
+
+
+
+
+
+
+
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
@@ -66,10 +94,10 @@
+
-
@@ -106,10 +134,10 @@
-
+
@@ -151,8 +179,6 @@
-
-
@@ -163,7 +189,7 @@
diff --git a/examples/wip/pixi1.js b/examples/wip/pixi1.js
index c4b3ebb0..a2c96b3a 100644
--- a/examples/wip/pixi1.js
+++ b/examples/wip/pixi1.js
@@ -26,6 +26,8 @@ function create() {
game.input.onDown.add(tint, this);
+ game.add.tween(sprite).to({y: 500}, 3000, Phaser.Easing.Linear.None, true);
+
}
function tint() {
diff --git a/examples/wip/pixi2.js b/examples/wip/pixi2.js
new file mode 100644
index 00000000..0c7faa5d
--- /dev/null
+++ b/examples/wip/pixi2.js
@@ -0,0 +1,88 @@
+
+var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('beast', 'assets/pics/shadow_of_the_beast2_karamoon.png');
+ game.load.image('snot', 'assets/pics/nslide_snot.png');
+ game.load.image('atari1', 'assets/sprites/atari130xe.png');
+ game.load.image('sonic', 'assets/sprites/sonic_havok_sanity.png');
+ game.load.image('coke', 'assets/sprites/cokecan.png');
+ game.load.image('disk', 'assets/sprites/oz_pov_melting_disk.png');
+
+}
+
+var group1;
+var group2;
+var coke;
+var disk;
+
+function create() {
+
+ // Create a background image
+ game.add.sprite(0, 0, 'beast');
+
+ // Create a Group that will sit above the background image
+ group1 = game.add.group();
+
+ // Create a Group that will sit above Group 1
+ group2 = game.add.group();
+
+ // 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.world.randomX, game.world.randomY, 'atari1');
+
+ tempSprite.name = 'atari' + i;
+ tempSprite.input.start(i, true);
+ tempSprite.input.enableDrag(false, true);
+
+ group1.add(tempSprite);
+
+ // Sonics
+
+ var tempSprite=game.add.sprite(game.world.randomX, game.world.randomY, 'sonic');
+
+ tempSprite.name = 'sonic' + i;
+ tempSprite.input.start(10 + i, true);
+ tempSprite.input.enableDrag(false, true);
+
+ group2.add(tempSprite);
+ }
+
+ // Add 2 control sprites into each group - these cannot be dragged but should be bought to the top each time
+ coke = group1.create(100, 100, 'coke');
+ disk = group2.create(400, 300, 'disk');
+
+ // Create a foreground image - everything should appear behind this, even when dragged
+ var snot = game.add.sprite(game.world.centerX, game.world.height, 'snot');
+ snot.anchor.setTo(0.5, 1);
+
+ // You can click and drag any sprite but Sonic sprites should always appear above the Atari sprites
+ // and both types of sprite should only ever appear above the background and behind the
+
+ game.input.onDown.add(wibble, this);
+
+}
+
+function wibble(p) {
+ console.log(p);
+}
+
+function update() {
+
+ if (game.input.keyboard.justReleased(Phaser.Keyboard.ONE))
+ {
+ coke.bringToTop();
+ }
+
+ if (game.input.keyboard.justReleased(Phaser.Keyboard.TWO))
+ {
+ disk.bringToTop();
+ }
+
+}
+
+function render() {
+ game.debug.renderInputInfo(32, 32);
+}
diff --git a/src/core/Group.js b/src/core/Group.js
index 0eb47cec..17a2b460 100644
--- a/src/core/Group.js
+++ b/src/core/Group.js
@@ -10,9 +10,9 @@
* @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, DisplayObject or DisplayObjectContainer that will hold this group. If undefined it will use game.world.
+* @param {*} parent - The parent Group, DisplayObject or DisplayObjectContainer that this Group will be added to. If undefined or null 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).
+* @param {boolean} [useStage=false] - Should this Group be added to the World (default, false) or direct to the Stage (true).
*/
Phaser.Group = function (game, parent, name, useStage) {
@@ -21,7 +21,7 @@ Phaser.Group = function (game, parent, name, useStage) {
*/
this.game = game;
- if (typeof parent === 'undefined')
+ if (typeof parent === 'undefined' || parent === null)
{
parent = game.world;
}
@@ -34,34 +34,20 @@ Phaser.Group = function (game, parent, name, useStage) {
PIXI.DisplayObjectContainer.call(this);
if (typeof useStage === 'undefined')
- {
- useStage = false;
- }
-
- if (useStage)
- {
- // this._container = this.game.stage._stage;
- }
- else
{
if (parent)
{
- // if (parent instanceof Phaser.Group)
- // {
- // parent.addChild(this);
- // }
- // else
- // {
- parent.addChild(this);
- // parent.updateTransform();
- // }
+ parent.addChild(this);
}
else
{
this.game.stage._stage.addChild(this);
- // this.game.stage._stage.updateTransform();
}
}
+ else
+ {
+ this.game.stage._stage.addChild(this);
+ }
/**
* @property {number} type - Internal Phaser Type value.
@@ -86,18 +72,14 @@ Phaser.Group = function (game, parent, name, useStage) {
*/
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.
+ * @property {Phaser.Point} scale - The scale of the Group container.
*/
- // this.scale = this._container.scale;
+ this.scale = new Phaser.Point(1, 1);
/**
* @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.
@@ -164,8 +146,6 @@ Phaser.Group.prototype.add = function (child) {
this.addChild(child);
- // child.updateTransform();
-
if (child.events)
{
child.events.onAddedToGroup.dispatch(child, this);
@@ -198,8 +178,6 @@ Phaser.Group.prototype.addAt = function (child, index) {
this.addChildAt(child, index);
- // child.updateTransform();
-
if (child.events)
{
child.events.onAddedToGroup.dispatch(child, this);
@@ -253,8 +231,6 @@ Phaser.Group.prototype.create = function (x, y, key, frame, exists) {
this.addChild(child);
- // child.updateTransform();
-
if (child.events)
{
child.events.onAddedToGroup.dispatch(child, this);
@@ -295,8 +271,6 @@ Phaser.Group.prototype.createMultiple = function (quantity, key, frame, exists)
this.addChild(child);
- // child.updateTransform();
-
if (child.events)
{
child.events.onAddedToGroup.dispatch(child, this);
@@ -433,7 +407,6 @@ Phaser.Group.prototype.replace = function (oldChild, newChild) {
this.addChildAt(newChild, index);
newChild.events.onAddedToGroup.dispatch(newChild, this);
- // newChild.updateTransform();
if (this.cursor === oldChild)
{
@@ -860,41 +833,10 @@ Phaser.Group.prototype.sort = function (index, order) {
if (typeof index === 'undefined') { index = 'y'; }
if (typeof order === 'undefined') { order = Phaser.Group.SORT_ASCENDING; }
- /*
- var swapped;
- var temp;
- do {
+}
- swapped = false;
-
- for (var i = 0, len = this._container.children.length - 1; i < len; i++)
- {
- if (order == Phaser.Group.SORT_ASCENDING)
- {
- if (this._container.children[i][index] > this._container.children[i + 1][index])
- {
- this.swap(this.getAt(i), this.getAt(i + 1));
- temp = this._container.children[i];
- this._container.children[i] = this._container.children[i + 1];
- this._container.children[i + 1] = temp;
- swapped = true;
- }
- }
- else
- {
- if (this._container.children[i][index] < this._container.children[i + 1][index])
- {
- this.swap(this.getAt(i), this.getAt(i + 1));
- temp = this._container.children[i];
- this._container.children[i] = this._container.children[i + 1];
- this._container.children[i + 1] = temp;
- swapped = true;
- }
- }
- }
- } while (swapped);
- */
+Phaser.Group.prototype.sortHandler = function (a, b) {
}
diff --git a/src/utils/Utils.js b/src/utils/Utils.js
index ac501e69..f1c489d7 100644
--- a/src/utils/Utils.js
+++ b/src/utils/Utils.js
@@ -197,12 +197,64 @@ Phaser.Utils = {
};
-function HEXtoRGB(hex) {
+/**
+ * Converts a hex color number to an [R, G, B] array
+ *
+ * @method hex2rgb
+ * @param hex {Number}
+ */
+PIXI.hex2rgb = function(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];
+/**
+ * Converts a color as an [R, G, B] array to a hex number
+ *
+ * @method rgb2hex
+ * @param rgb {Array}
+ */
+PIXI.rgb2hex = function(rgb) {
+ return ((rgb[0]*255 << 16) + (rgb[1]*255 << 8) + rgb[2]*255);
+};
+
+/**
+ * Checks whether the Canvas BlendModes are supported by the current browser
+ *
+ * @method canUseNewCanvasBlendModes
+ * @return {Boolean} whether they are supported
+ */
+PIXI.canUseNewCanvasBlendModes = function()
+{
+ var canvas = document.createElement('canvas');
+ canvas.width = 1;
+ canvas.height = 1;
+ var context = canvas.getContext('2d');
+ context.fillStyle = '#000';
+ context.fillRect(0,0,1,1);
+ context.globalCompositeOperation = 'multiply';
+ context.fillStyle = '#fff';
+ context.fillRect(0,0,1,1);
+ return context.getImageData(0,0,1,1).data[0] === 0;
+};
+
+/**
+ * Given a number, this function returns the closest number that is a power of two
+ * this function is taken from Starling Framework as its pretty neat ;)
+ *
+ * @method getNextPowerOfTwo
+ * @param number {Number}
+ * @return {Number} the closest number that is a power of two
+ */
+PIXI.getNextPowerOfTwo = function(number)
+{
+ if (number > 0 && (number & (number - 1)) === 0) // see: http://goo.gl/D9kPj
+ return number;
+ else
+ {
+ var result = 1;
+ while (result < number) result <<= 1;
+ return result;
+ }
};
/**
From e88b10323a3acbf84e4726abda1130806ef72836 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Thu, 6 Feb 2014 12:29:07 +0000
Subject: [PATCH 06/26] Updated Phaser geometry classes so they over-ride the
PIXI native ones, means we can do away with a whole bunch of over-rides and
object changes in Sprite, etc.
---
build/config.php | 19 +++---
examples/wip/pixi1.js | 3 +
src/Phaser.js | 2 +-
src/geom/Circle.js | 24 ++++++--
src/geom/Point.js | 35 +++++++++--
src/geom/Rectangle.js | 131 ++++++++++++++++++++++++++++++++++--------
6 files changed, 173 insertions(+), 41 deletions(-)
diff --git a/build/config.php b/build/config.php
index 59c48231..9129af4a 100644
--- a/build/config.php
+++ b/build/config.php
@@ -38,6 +38,12 @@
+
+
+
+
+
+
*/
@@ -48,11 +54,13 @@
+
+
+
+
+
-
-
-
@@ -65,7 +73,6 @@
-
@@ -138,10 +145,6 @@
-
-
-
-
diff --git a/examples/wip/pixi1.js b/examples/wip/pixi1.js
index a2c96b3a..bf8abf8e 100644
--- a/examples/wip/pixi1.js
+++ b/examples/wip/pixi1.js
@@ -10,6 +10,7 @@ function preload() {
var sprite;
var sprite2;
var g;
+var p;
function create() {
@@ -28,6 +29,8 @@ function create() {
game.add.tween(sprite).to({y: 500}, 3000, Phaser.Easing.Linear.None, true);
+ p = new PIXI.Point(43, 45);
+
}
function tint() {
diff --git a/src/Phaser.js b/src/Phaser.js
index 6cb14044..ad2bf892 100644
--- a/src/Phaser.js
+++ b/src/Phaser.js
@@ -44,7 +44,7 @@ var Phaser = Phaser || {
CANVAS_PX_ROUND: false,
CANVAS_CLEAR_RECT: true
- };
+};
PIXI.InteractionManager = function (dummy) {
// We don't need this in Pixi, so we've removed it to save space
diff --git a/src/geom/Circle.js b/src/geom/Circle.js
index 86cc21b1..d8a390b3 100644
--- a/src/geom/Circle.js
+++ b/src/geom/Circle.js
@@ -132,9 +132,16 @@ Phaser.Circle.prototype = {
*/
clone: function(out) {
- if (typeof out === "undefined") { out = new Phaser.Circle(); }
+ if (typeof out === "undefined")
+ {
+ out = new Phaser.Circle(this.x, this.y, this.diameter);
+ }
+ else
+ {
+ out.setTo(this.x, this.y, this.diameter);
+ }
- return out.setTo(this.x, this.y, this.diameter);
+ return out;
},
@@ -377,14 +384,18 @@ Object.defineProperty(Phaser.Circle.prototype, "empty", {
*/
Phaser.Circle.contains = function (a, x, y) {
- // Check if x/y are within the bounds first
- if (x >= a.left && x <= a.right && y >= a.top && y <= a.bottom) {
+ if (a.radius <= 0)
+ {
+ return false;
+ }
+ // Check if x/y are within the bounds first
+ if (x >= a.left && x <= a.right && y >= a.top && y <= a.bottom)
+ {
var dx = (a.x - x) * (a.x - x);
var dy = (a.y - y) * (a.y - y);
return (dx + dy) <= (a.radius * a.radius);
-
}
return false;
@@ -475,3 +486,6 @@ Phaser.Circle.intersectsRectangle = function (c, r) {
return xCornerDistSq + yCornerDistSq <= maxCornerDistSq;
};
+
+// Because PIXI uses its own Circle, we'll replace it with ours to avoid duplicating code or confusion.
+PIXI.Circle = Phaser.Circle;
diff --git a/src/geom/Point.js b/src/geom/Point.js
index 029341c5..c4c291d9 100644
--- a/src/geom/Point.js
+++ b/src/geom/Point.js
@@ -59,8 +59,25 @@ Phaser.Point.prototype = {
*/
setTo: function (x, y) {
- this.x = x;
- this.y = y;
+ this.x = x || 0;
+ this.y = y || ( (y !== 0) ? this.x : 0 );
+
+ return this;
+
+ },
+
+ /**
+ * Sets the x and y values of this Point object to the given coordinates.
+ * @method Phaser.Point#set
+ * @param {number} x - The horizontal position of this point.
+ * @param {number} y - The vertical position of this point.
+ * @return {Point} This Point object. Useful for chaining method calls.
+ */
+ set: function (x, y) {
+
+ this.x = x || 0;
+ this.y = y || ( (y !== 0) ? this.x : 0 );
+
return this;
},
@@ -176,9 +193,16 @@ Phaser.Point.prototype = {
*/
clone: function (output) {
- if (typeof output === "undefined") { output = new Phaser.Point(); }
+ if (typeof output === "undefined")
+ {
+ output = new Phaser.Point(this.x, this.y);
+ }
+ else
+ {
+ output.setTo(this.x, this.y);
+ }
- return output.setTo(this.x, this.y);
+ return output;
},
@@ -430,3 +454,6 @@ Phaser.Point.rotate = function (a, x, y, angle, asDegrees, distance) {
return a.setTo(x + distance * Math.cos(angle), y + distance * Math.sin(angle));
};
+
+// Because PIXI uses its own Point, we'll replace it with ours to avoid duplicating code or confusion.
+PIXI.Point = Phaser.Point;
diff --git a/src/geom/Rectangle.js b/src/geom/Rectangle.js
index 0861dcf3..2d872488 100644
--- a/src/geom/Rectangle.js
+++ b/src/geom/Rectangle.js
@@ -13,7 +13,7 @@
* @param {number} y - The y coordinate of the top-left corner of the Rectangle.
* @param {number} width - The width of the Rectangle.
* @param {number} height - The height of the Rectangle.
-* @return {Rectangle} This Rectangle object.
+* @return {Phaser.Rectangle} This Rectangle object.
*/
Phaser.Rectangle = function (x, y, width, height) {
@@ -51,7 +51,7 @@ Phaser.Rectangle.prototype = {
* @method Phaser.Rectangle#offset
* @param {number} dx - Moves the x value of the Rectangle object by this amount.
* @param {number} dy - Moves the y value of the Rectangle object by this amount.
- * @return {Rectangle} This Rectangle object.
+ * @return {Phaser.Rectangle} This Rectangle object.
*/
offset: function (dx, dy) {
@@ -65,11 +65,13 @@ Phaser.Rectangle.prototype = {
/**
* Adjusts the location of the Rectangle object using a Point object as a parameter. This method is similar to the Rectangle.offset() method, except that it takes a Point object as a parameter.
* @method Phaser.Rectangle#offsetPoint
- * @param {Point} point - A Point object to use to offset this Rectangle object.
- * @return {Rectangle} This Rectangle object.
+ * @param {Phaser.Point} point - A Point object to use to offset this Rectangle object.
+ * @return {Phaser.Rectangle} This Rectangle object.
*/
offsetPoint: function (point) {
+
return this.offset(point.x, point.y);
+
},
/**
@@ -79,7 +81,7 @@ Phaser.Rectangle.prototype = {
* @param {number} y - The y coordinate of the top-left corner of the Rectangle.
* @param {number} width - The width of the Rectangle in pixels.
* @param {number} height - The height of the Rectangle in pixels.
- * @return {Rectangle} This Rectangle object
+ * @return {Phaser.Rectangle} This Rectangle object
*/
setTo: function (x, y, width, height) {
@@ -91,7 +93,7 @@ Phaser.Rectangle.prototype = {
return this;
},
-
+
/**
* Runs Math.floor() on both the x and y values of this Rectangle.
* @method Phaser.Rectangle#floor
@@ -120,10 +122,12 @@ Phaser.Rectangle.prototype = {
* Copies the x, y, width and height properties from any given object to this Rectangle.
* @method Phaser.Rectangle#copyFrom
* @param {any} source - The object to copy from.
- * @return {Rectangle} This Rectangle object.
+ * @return {Phaser.Rectangle} This Rectangle object.
*/
copyFrom: function (source) {
+
return this.setTo(source.x, source.y, source.width, source.height);
+
},
/**
@@ -151,7 +155,9 @@ Phaser.Rectangle.prototype = {
* @return {Phaser.Rectangle} This Rectangle object.
*/
inflate: function (dx, dy) {
+
return Phaser.Rectangle.inflate(this, dx, dy);
+
},
/**
@@ -161,7 +167,9 @@ Phaser.Rectangle.prototype = {
* @return {Phaser.Point} The size of the Rectangle object.
*/
size: function (output) {
+
return Phaser.Rectangle.size(this, output);
+
},
/**
@@ -171,7 +179,9 @@ Phaser.Rectangle.prototype = {
* @return {Phaser.Rectangle}
*/
clone: function (output) {
+
return Phaser.Rectangle.clone(this, output);
+
},
/**
@@ -182,7 +192,9 @@ Phaser.Rectangle.prototype = {
* @return {boolean} A value of true if the Rectangle object contains the specified point; otherwise false.
*/
contains: function (x, y) {
+
return Phaser.Rectangle.contains(this, x, y);
+
},
/**
@@ -193,7 +205,9 @@ Phaser.Rectangle.prototype = {
* @return {boolean} A value of true if the Rectangle object contains the specified point; otherwise false.
*/
containsRect: function (b) {
+
return Phaser.Rectangle.containsRect(this, b);
+
},
/**
@@ -204,7 +218,9 @@ Phaser.Rectangle.prototype = {
* @return {boolean} A value of true if the two Rectangles have exactly the same values for the x, y, width and height properties; otherwise false.
*/
equals: function (b) {
+
return Phaser.Rectangle.equals(this, b);
+
},
/**
@@ -215,7 +231,9 @@ Phaser.Rectangle.prototype = {
* @return {Phaser.Rectangle} A Rectangle object that equals the area of intersection. If the Rectangles do not intersect, this method returns an empty Rectangle object; that is, a Rectangle with its x, y, width, and height properties set to 0.
*/
intersection: function (b, out) {
+
return Phaser.Rectangle.intersection(this, b, out);
+
},
/**
@@ -227,7 +245,9 @@ Phaser.Rectangle.prototype = {
* @return {boolean} A value of true if the specified object intersects with this Rectangle object; otherwise false.
*/
intersects: function (b, tolerance) {
+
return Phaser.Rectangle.intersects(this, b, tolerance);
+
},
/**
@@ -241,7 +261,9 @@ Phaser.Rectangle.prototype = {
* @return {boolean} A value of true if the specified object intersects with the Rectangle; otherwise false.
*/
intersectsRaw: function (left, right, top, bottom, tolerance) {
+
return Phaser.Rectangle.intersectsRaw(this, left, right, top, bottom, tolerance);
+
},
/**
@@ -252,7 +274,9 @@ Phaser.Rectangle.prototype = {
* @return {Phaser.Rectangle} A Rectangle object that is the union of the two Rectangles.
*/
union: function (b, out) {
+
return Phaser.Rectangle.union(this, b, out);
+
},
/**
@@ -261,7 +285,9 @@ Phaser.Rectangle.prototype = {
* @return {string} A string representation of the instance.
*/
toString: function () {
+
return "[{Rectangle (x=" + this.x + " y=" + this.y + " width=" + this.width + " height=" + this.height + " empty=" + this.empty + ")}]";
+
}
};
@@ -511,11 +537,14 @@ Object.defineProperty(Phaser.Rectangle.prototype, "empty", {
* @return {Phaser.Rectangle} This Rectangle object.
*/
Phaser.Rectangle.inflate = function (a, dx, dy) {
+
a.x -= dx;
a.width += 2 * dx;
a.y -= dy;
a.height += 2 * dy;
+
return a;
+
};
/**
@@ -526,7 +555,9 @@ Phaser.Rectangle.inflate = function (a, dx, dy) {
* @return {Phaser.Rectangle} The Rectangle object.
*/
Phaser.Rectangle.inflatePoint = function (a, point) {
+
return Phaser.Rectangle.inflate(a, point.x, point.y);
+
};
/**
@@ -537,8 +568,18 @@ Phaser.Rectangle.inflatePoint = function (a, point) {
* @return {Phaser.Point} The size of the Rectangle object
*/
Phaser.Rectangle.size = function (a, output) {
- if (typeof output === "undefined") { output = new Phaser.Point(); }
- return output.setTo(a.width, a.height);
+
+ if (typeof output === "undefined")
+ {
+ output = new Phaser.Point(a.width, a.height);
+ }
+ else
+ {
+ output.setTo(a.width, a.height);
+ }
+
+ return output;
+
};
/**
@@ -549,8 +590,18 @@ Phaser.Rectangle.size = function (a, output) {
* @return {Phaser.Rectangle}
*/
Phaser.Rectangle.clone = function (a, output) {
- if (typeof output === "undefined") { output = new Phaser.Rectangle(); }
- return output.setTo(a.x, a.y, a.width, a.height);
+
+ if (typeof output === "undefined")
+ {
+ output = new Phaser.Rectangle(a.x, a.y, a.width, a.height);
+ }
+ else
+ {
+ output.setTo(a.x, a.y, a.width, a.height);
+ }
+
+ return output;
+
};
/**
@@ -562,11 +613,31 @@ Phaser.Rectangle.clone = function (a, output) {
* @return {boolean} A value of true if the Rectangle object contains the specified point; otherwise false.
*/
Phaser.Rectangle.contains = function (a, x, y) {
+
+ if (a.width <= 0 || a.height <= 0)
+ {
+ return false;
+ }
+
return (x >= a.x && x <= a.right && y >= a.y && y <= a.bottom);
+
};
+/**
+* Determines whether the specified coordinates are contained within the region defined by the given raw values.
+* @method Phaser.Rectangle.containsRaw
+* @param {number} rx - The x coordinate of the top left of the area.
+* @param {number} ry - The y coordinate of the top left of the area.
+* @param {number} rw - The width of the area.
+* @param {number} rh - The height of the area.
+* @param {number} x - The x coordinate of the point to test.
+* @param {number} y - The y coordinate of the point to test.
+* @return {boolean} A value of true if the Rectangle object contains the specified point; otherwise false.
+*/
Phaser.Rectangle.containsRaw = function (rx, ry, rw, rh, x, y) {
+
return (x >= rx && x <= (rx + rw) && y >= ry && y <= (ry + rh));
+
};
/**
@@ -577,7 +648,9 @@ Phaser.Rectangle.containsRaw = function (rx, ry, rw, rh, x, y) {
* @return {boolean} A value of true if the Rectangle object contains the specified point; otherwise false.
*/
Phaser.Rectangle.containsPoint = function (a, point) {
+
return Phaser.Rectangle.contains(a, point.x, point.y);
+
};
/**
@@ -609,7 +682,9 @@ Phaser.Rectangle.containsRect = function (a, b) {
* @return {boolean} A value of true if the two Rectangles have exactly the same values for the x, y, width and height properties; otherwise false.
*/
Phaser.Rectangle.equals = function (a, b) {
+
return (a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height);
+
};
/**
@@ -617,22 +692,25 @@ Phaser.Rectangle.equals = function (a, b) {
* @method Phaser.Rectangle.intersection
* @param {Phaser.Rectangle} a - The first Rectangle object.
* @param {Phaser.Rectangle} b - The second Rectangle object.
-* @param {Phaser.Rectangle} [out] - Optional Rectangle object. If given the intersection values will be set into this object, otherwise a brand new Rectangle object will be created and returned.
+* @param {Phaser.Rectangle} [output] - Optional Rectangle object. If given the intersection values will be set into this object, otherwise a brand new Rectangle object will be created and returned.
* @return {Phaser.Rectangle} A Rectangle object that equals the area of intersection. If the Rectangles do not intersect, this method returns an empty Rectangle object; that is, a Rectangle with its x, y, width, and height properties set to 0.
*/
-Phaser.Rectangle.intersection = function (a, b, out) {
+Phaser.Rectangle.intersection = function (a, b, output) {
- out = out || new Phaser.Rectangle();
+ if (typeof output === "undefined")
+ {
+ output = new Phaser.Rectangle();
+ }
if (Phaser.Rectangle.intersects(a, b))
{
- out.x = Math.max(a.x, b.x);
- out.y = Math.max(a.y, b.y);
- out.width = Math.min(a.right, b.right) - out.x;
- out.height = Math.min(a.bottom, b.bottom) - out.y;
+ output.x = Math.max(a.x, b.x);
+ output.y = Math.max(a.y, b.y);
+ output.width = Math.min(a.right, b.right) - output.x;
+ output.height = Math.min(a.bottom, b.bottom) - output.y;
}
- return out;
+ return output;
};
@@ -678,13 +756,20 @@ Phaser.Rectangle.intersectsRaw = function (a, left, right, top, bottom, toleranc
* @method Phaser.Rectangle.union
* @param {Phaser.Rectangle} a - The first Rectangle object.
* @param {Phaser.Rectangle} b - The second Rectangle object.
-* @param {Phaser.Rectangle} [out] - Optional Rectangle object. If given the new values will be set into this object, otherwise a brand new Rectangle object will be created and returned.
+* @param {Phaser.Rectangle} [output] - Optional Rectangle object. If given the new values will be set into this object, otherwise a brand new Rectangle object will be created and returned.
* @return {Phaser.Rectangle} A Rectangle object that is the union of the two Rectangles.
*/
-Phaser.Rectangle.union = function (a, b, out) {
+Phaser.Rectangle.union = function (a, b, output) {
- if (typeof out === "undefined") { out = new Phaser.Rectangle(); }
+ if (typeof output === "undefined")
+ {
+ output = new Phaser.Rectangle();
+ }
- return out.setTo(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.max(a.right, b.right) - Math.min(a.left, b.left), Math.max(a.bottom, b.bottom) - Math.min(a.top, b.top));
+ return output.setTo(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.max(a.right, b.right) - Math.min(a.left, b.left), Math.max(a.bottom, b.bottom) - Math.min(a.top, b.top));
};
+
+// Because PIXI uses its own Rectangle, we'll replace it with ours to avoid duplicating code or confusion.
+PIXI.Rectangle = Phaser.Rectangle;
+PIXI.EmptyRectangle = new Phaser.Rectangle(0,0,0,0);
From 4ed20e0f776fe9db10463a9a6fab10198571b57b Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Thu, 6 Feb 2014 13:15:45 +0000
Subject: [PATCH 07/26] Removed all intances of Sprite.group from Group and
replaced with the already existing parent property.
---
README.md | 4 ++
examples/wip/pixi1.js | 8 ++--
src/core/Group.js | 66 ++++++++-----------------------
src/gameobjects/Sprite.js | 21 +++++-----
src/pixi/display/DisplayObject.js | 3 ++
5 files changed, 40 insertions(+), 62 deletions(-)
diff --git a/README.md b/README.md
index a4cc4d20..f4453f92 100644
--- a/README.md
+++ b/README.md
@@ -63,6 +63,10 @@ Significant API changes:
* Upgraded to Pixi.js 1.4.4
* Group now extends PIXI.DisplayObjectContainer, rather than owning a _container property, which makes life a whole lot easier re: nesting.
+* Removed Sprite.group property. You can use Sprite.parent for all similar needs now.
+* PIXI.Point is now aliased to Phaser.Point - saves on code duplication and works exactly the same.
+* PIXI.Rectangle is now aliased to Phaser.Rectangle - saves on code duplication and works exactly the same.
+* PIXI.Circle is now aliased to Phaser.Circle - saves on code duplication and works exactly the same.
New features:
diff --git a/examples/wip/pixi1.js b/examples/wip/pixi1.js
index bf8abf8e..210adfc1 100644
--- a/examples/wip/pixi1.js
+++ b/examples/wip/pixi1.js
@@ -1,5 +1,5 @@
-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() {
@@ -16,9 +16,9 @@ function create() {
sprite = game.add.sprite(0, 0, 'pic');
- g = game.add.group();
+ g = game.add.group(null, 'billy');
- g.create(0, 0, 'pic');
+ sprite2 = g.create(0, 0, 'pic');
g.y = 200;
g.rotation = 0.1;
@@ -47,4 +47,6 @@ function update() {
function render() {
+ game.debug.renderText(sprite.position.y, 32, 32);
+
}
diff --git a/src/core/Group.js b/src/core/Group.js
index 17a2b460..d135488c 100644
--- a/src/core/Group.js
+++ b/src/core/Group.js
@@ -68,9 +68,9 @@ Phaser.Group = function (game, parent, name, useStage) {
this.exists = true;
/**
- * @property {Phaser.Group} group - The parent Group of this Group, if a child of another.
+ * @property {Phaser.Group|Phaser.Sprite} parent - The parent of this Group.
*/
- this.group = null;
+ // this.group = null;
/**
* @property {Phaser.Point} scale - The scale of the Group container.
@@ -140,10 +140,8 @@ Phaser.Group.SORT_DESCENDING = 1;
*/
Phaser.Group.prototype.add = function (child) {
- if (child.group !== this)
+ if (child.parent !== this)
{
- child.group = this;
-
this.addChild(child);
if (child.events)
@@ -172,10 +170,8 @@ Phaser.Group.prototype.add = function (child) {
*/
Phaser.Group.prototype.addAt = function (child, index) {
- if (child.group !== this)
+ if (child.parent !== this)
{
- child.group = this;
-
this.addChildAt(child, index);
if (child.events)
@@ -224,7 +220,6 @@ Phaser.Group.prototype.create = function (x, y, key, frame, exists) {
var child = new Phaser.Sprite(this.game, x, y, key, frame);
- child.group = this;
child.exists = exists;
child.visible = exists;
child.alive = exists;
@@ -262,25 +257,7 @@ Phaser.Group.prototype.createMultiple = function (quantity, key, frame, exists)
for (var i = 0; i < quantity; i++)
{
- var child = new Phaser.Sprite(this.game, 0, 0, key, frame);
-
- child.group = this;
- child.exists = exists;
- child.visible = exists;
- child.alive = exists;
-
- this.addChild(child);
-
- if (child.events)
- {
- child.events.onAddedToGroup.dispatch(child, this);
- }
-
- if (this.cursor === null)
- {
- this.cursor = child;
- }
-
+ this.create(0, 0, key, frame, exists);
}
}
@@ -343,12 +320,7 @@ Phaser.Group.prototype.previous = function () {
*/
Phaser.Group.prototype.swap = function (child1, child2) {
- if (child1 === child2 || !child1.parent || !child2.parent || child1.group !== this || child2.group !== this)
- {
- return false;
- }
-
- this.swapChildren(child1, child2);
+ return this.swapChildren(child1, child2);
}
@@ -361,7 +333,7 @@ Phaser.Group.prototype.swap = function (child1, child2) {
*/
Phaser.Group.prototype.bringToTop = function (child) {
- if (child.group === this)
+ if (child.parent === this)
{
this.remove(child);
this.add(child);
@@ -473,8 +445,6 @@ Phaser.Group.prototype.setProperty = function (child, key, value, operation) {
else if (operation == 3) { child[key[0]][key[1]][key[2]][key[3]] *= value; }
else if (operation == 4) { child[key[0]][key[1]][key[2]][key[3]] /= value; }
}
-
- // TODO - Deep property scane
}
@@ -996,9 +966,9 @@ Phaser.Group.prototype.getRandom = function (startIndex, length) {
*/
Phaser.Group.prototype.remove = function (child) {
- if (child.group !== this)
+ if (this.children.length === 0)
{
- return false;
+ return;
}
if (child.events)
@@ -1006,19 +976,13 @@ Phaser.Group.prototype.remove = function (child) {
child.events.onRemovedFromGroup.dispatch(child, this);
}
- // Check it's actually in the container
- if (child.parent === this)
- {
- this.removeChild(child);
- }
+ this.removeChild(child);
if (this.cursor === child)
{
this.next();
}
- child.group = null;
-
return true;
}
@@ -1042,6 +1006,7 @@ Phaser.Group.prototype.removeAll = function () {
{
this.children[0].events.onRemovedFromGroup.dispatch(this.children[0], this);
}
+
this.removeChild(this.children[0]);
}
while (this.children.length > 0);
@@ -1071,9 +1036,12 @@ Phaser.Group.prototype.removeBetween = function (startIndex, endIndex) {
for (var i = startIndex; i < endIndex; i++)
{
- var child = this.children[i];
- child.events.onRemovedFromGroup.dispatch(child, this);
- this.removeChild(child);
+ if (this.children[i].events)
+ {
+ this.children[i].events.onRemovedFromGroup.dispatch(this.children[i], this);
+ }
+
+ this.removeChild(this.children[i]);
if (this.cursor === child)
{
diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js
index 1e7ea7ae..27f27c83 100644
--- a/src/gameobjects/Sprite.js
+++ b/src/gameobjects/Sprite.js
@@ -45,9 +45,9 @@ Phaser.Sprite = function (game, x, y, key, frame) {
this.alive = true;
/**
- * @property {Phaser.Group} group - The parent Group of this Sprite. This is usually set after Sprite instantiation by the parent.
+ * @property {Phaser.Group|Phaser.Sprite} parent - The parent of this Sprite.
*/
- this.group = null;
+ // this.group = null;
/**
* @property {string} name - The user defined name given to this Sprite.
@@ -169,7 +169,10 @@ Phaser.Sprite = function (game, x, y, key, frame) {
*
* @property {Phaser.Point} anchor - The anchor around which rotation and scaling takes place.
*/
- this.anchor = new Phaser.Point();
+ // this.anchor = new Phaser.Point();
+
+ // this.position.x = x;
+ // this.position.y = y;
/**
* @property {number} x - The x coordinate in world space of this Sprite.
@@ -181,8 +184,6 @@ Phaser.Sprite = function (game, x, y, key, frame) {
*/
this.y = y;
- this.position.x = x;
- this.position.y = y;
/**
* @property {Phaser.Point} world - The world coordinates of this Sprite. This differs from the x/y coordinates which are relative to the Sprites container.
@@ -201,7 +202,7 @@ Phaser.Sprite = function (game, x, y, key, frame) {
/**
* @property {Phaser.Point} scale - The scale of the Sprite when rendered. By default it's set to 1 (no scale). You can modify it via scale.x or scale.y or scale.setTo(x, y). A value of 1 means no change to the scale, 0.5 means "half the size", 2 means "twice the size", etc.
*/
- this.scale = new Phaser.Point(1, 1);
+ // this.scale = new Phaser.Point(1, 1);
/**
* @property {object} _cache - A mini cache for storing all of the calculated values.
@@ -381,7 +382,7 @@ Phaser.Sprite = function (game, x, y, key, frame) {
this.updateBounds();
/**
- * @property {PIXI.Point} pivot - The pivot point of the displayObject that it rotates around.
+ * @property {Phaser.Point} pivot - The pivot point of the displayObject that it rotates around.
*/
};
@@ -400,7 +401,7 @@ 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.world.setTo(this.parent.position.x + this.position.x, this.parent.position.y + this.position.y);
this.worldTransform[2] = this.world.x;
this.worldTransform[5] = this.world.y;
this._cache.fresh = false;
@@ -871,9 +872,9 @@ Phaser.Sprite.prototype.destroy = function() {
this.filters = null;
}
- if (this.group)
+ if (this.parent)
{
- this.group.remove(this);
+ this.parent.remove(this);
}
if (this.input)
diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js
index 09f33cd9..c1c82429 100644
--- a/src/pixi/display/DisplayObject.js
+++ b/src/pixi/display/DisplayObject.js
@@ -196,6 +196,9 @@ PIXI.DisplayObject = function()
*/
this._mask = null;
+ this.x = this.position.x;
+ this.y = this.position.y;
+
/*
* MOUSE Callbacks
*/
From 8ef403cfe795ca7c32b3ecf257a42caad53b7080 Mon Sep 17 00:00:00 2001
From: Georgios Kaleadis
Date: Thu, 6 Feb 2014 17:28:39 +0100
Subject: [PATCH 08/26] Timer checks now for running inside while loop. Any
event which causes a call to Timer#stop is now safe.
---
src/time/Timer.js | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/src/time/Timer.js b/src/time/Timer.js
index 410c41bf..e41acc61 100644
--- a/src/time/Timer.js
+++ b/src/time/Timer.js
@@ -327,7 +327,7 @@ Phaser.Timer.prototype = {
{
this._i = 0;
- while (this._i < this._len)
+ while (this._i < this._len && this.running)
{
if (this._now >= this.events[this._i].tick)
{
From 3748811d11fcc77f4e4d17d7aa42c57f83ced5dd Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Thu, 6 Feb 2014 19:34:05 +0000
Subject: [PATCH 09/26] Testing new Image object.
---
README.md | 1 +
build/config.php | 1 +
examples/wip/image1.js | 45 +++
examples/wip/image2.js | 39 +++
src/animation/Frame.js | 22 ++
src/gameobjects/GameObjectFactory.js | 19 +
src/gameobjects/Image.js | 500 +++++++++++++++++++++++++++
src/gameobjects/Sprite.js | 78 ++---
8 files changed, 665 insertions(+), 40 deletions(-)
create mode 100644 examples/wip/image1.js
create mode 100644 examples/wip/image2.js
create mode 100644 src/gameobjects/Image.js
diff --git a/README.md b/README.md
index f4453f92..972e94ca 100644
--- a/README.md
+++ b/README.md
@@ -67,6 +67,7 @@ Significant API changes:
* PIXI.Point is now aliased to Phaser.Point - saves on code duplication and works exactly the same.
* PIXI.Rectangle is now aliased to Phaser.Rectangle - saves on code duplication and works exactly the same.
* PIXI.Circle is now aliased to Phaser.Circle - saves on code duplication and works exactly the same.
+* Sprite.deltaX and deltaY swapped to functions: Sprite.deltaX() and Sprite.deltaY()
New features:
diff --git a/build/config.php b/build/config.php
index 9129af4a..7b047258 100644
--- a/build/config.php
+++ b/build/config.php
@@ -129,6 +129,7 @@
+
diff --git a/examples/wip/image1.js b/examples/wip/image1.js
new file mode 100644
index 00000000..aada00c2
--- /dev/null
+++ b/examples/wip/image1.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('pic', 'assets/pics/backscroll.png');
+
+}
+
+var image;
+var sprite;
+
+function create() {
+
+console.log('wtf');
+
+ image = game.add.image(game.world.centerX, game.world.centerY, 'pic');
+ image.anchor.set(0.5);
+
+ // sprite = game.add.sprite(game.world.centerX, game.world.centerY, 'pic');
+ // sprite.anchor.set(0.5);
+
+ game.input.onDown.add(tint, this);
+
+}
+
+function tint() {
+
+ image.tint = Math.random() * 0xFFFFFF;
+ // sprite.tint = Math.random() * 0xFFFFFF;
+
+}
+
+function update() {
+
+ image.angle += 1;
+ // sprite.angle += 1;
+
+}
+
+function render() {
+
+ // game.debug.renderText(sprite.position.y, 32, 32);
+
+}
diff --git a/examples/wip/image2.js b/examples/wip/image2.js
new file mode 100644
index 00000000..15560680
--- /dev/null
+++ b/examples/wip/image2.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('pic', 'assets/pics/backscroll.png');
+
+}
+
+var image;
+var image2;
+
+function create() {
+
+ image = game.add.image(32, 50, 'pic');
+
+ image2 = game.add.image(32, 250, 'pic');
+
+ game.input.onDown.add(tint, this);
+
+}
+
+function tint() {
+
+ image.tint = Math.random() * 0xFFFFFF;
+
+}
+
+function update() {
+
+ // image.angle += 1;
+
+}
+
+function render() {
+
+ // game.debug.renderText(sprite.position.y, 32, 32);
+
+}
diff --git a/src/animation/Frame.js b/src/animation/Frame.js
index c7cc3ff6..a650d090 100644
--- a/src/animation/Frame.js
+++ b/src/animation/Frame.js
@@ -155,6 +155,28 @@ Phaser.Frame.prototype = {
this.spriteSourceSizeH = destHeight;
}
+ },
+
+ /**
+ * Returns a Rectangle set to the dimensions of this Frame.
+ *
+ * @method Phaser.Frame#getRect
+ * @param {Phaser.Rectangle} [out] - A rectangle to copy the frame dimensions to.
+ * @return {Phaser.Rectangle} A rectangle.
+ */
+ getRect: function (out) {
+
+ if (typeof out === 'undefined')
+ {
+ out = new Phaser.Rectangle(this.x, this.y, this.width, this.height);
+ }
+ else
+ {
+ out.setTo(this.x, this.y, this.width, this.height);
+ }
+
+ return out;
+
}
};
diff --git a/src/gameobjects/GameObjectFactory.js b/src/gameobjects/GameObjectFactory.js
index 485f0087..955d7cd0 100644
--- a/src/gameobjects/GameObjectFactory.js
+++ b/src/gameobjects/GameObjectFactory.js
@@ -39,6 +39,25 @@ Phaser.GameObjectFactory.prototype = {
},
+ /**
+ * Create a new Image at the given coordinates, using the cache key and frame if set.
+ *
+ * @method Phaser.GameObjectFactory#image
+ * @param {number} x - X position of the image.
+ * @param {number} y - Y position of the image.
+ * @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.
+ */
+ image: function (x, y, key, frame, group) {
+
+ if (typeof group === 'undefined') { group = this.world; }
+
+ return group.add(new Phaser.Image(this.game, x, y, key, frame));
+
+ },
+
/**
* Create a new Sprite with specific position and sprite sheet key.
*
diff --git a/src/gameobjects/Image.js b/src/gameobjects/Image.js
new file mode 100644
index 00000000..f78dc678
--- /dev/null
+++ b/src/gameobjects/Image.js
@@ -0,0 +1,500 @@
+/**
+* @author Richard Davey
+* @copyright 2014 Photon Storm Ltd.
+* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
+*/
+
+/**
+* @class Phaser.Image
+*
+* @classdesc Create a new `Image` object.
+*
+* At its most basic a Sprite consists of a set of coordinates and a texture that is rendered to the canvas.
+*
+* @constructor
+* @param {Phaser.Game} game - A reference to the currently running game.
+* @param {number} x - The x coordinate (in world space) to position the Sprite at.
+* @param {number} y - The y coordinate (in world space) to position the Sprite at.
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|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.Image = function (game, x, y, key, frame) {
+
+ x = x || 0;
+ y = y || 0;
+ key = key || null;
+ frame = frame || null;
+
+ /**
+ * @property {Phaser.Game} game - A reference to the currently running Game.
+ */
+ this.game = game;
+
+ /**
+ * @property {boolean} exists - If exists = false then the Sprite isn't updated by the core game loop or physics subsystem at all.
+ * @default
+ */
+ this.exists = true;
+
+ /**
+ * @property {string} name - The user defined name given to this Sprite.
+ * @default
+ */
+ this.name = '';
+
+ /**
+ * @property {number} type - The const type of this object.
+ * @readonly
+ */
+ this.type = Phaser.IMAGE;
+
+ /**
+ * @property {Phaser.Events} events - The Events you can subscribe to that are dispatched when certain things happen on this Sprite or its components.
+ */
+ this.events = new Phaser.Events(this);
+
+ /**
+ * @property {string|Phaser.RenderTexture|Phaser.BitmapData|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, BitmapData or PIXI.Texture.
+ */
+ this.key = key;
+
+ this.currentFrame = new Phaser.Rectangle();
+
+ if (key instanceof Phaser.RenderTexture)
+ {
+ PIXI.Sprite.call(this, key);
+
+ this.currentFrame = this.game.cache.getTextureFrame(key.name);
+ }
+ else if (key instanceof Phaser.BitmapData)
+ {
+ PIXI.Sprite.call(this, key.texture, key.textureFrame);
+
+ this.currentFrame = key.textureFrame;
+ }
+ else if (key instanceof PIXI.Texture)
+ {
+ PIXI.Sprite.call(this, key);
+
+ this.currentFrame = frame;
+ }
+ else
+ {
+ if (key === null || typeof key === 'undefined')
+ {
+ key = '__default';
+ this.key = key;
+ }
+ else if (typeof key === 'string' && this.game.cache.checkImageKey(key) === false)
+ {
+ key = '__missing';
+ this.key = key;
+ }
+
+ PIXI.Sprite.call(this, PIXI.TextureCache[key]);
+
+ if (this.game.cache.isSpriteSheet(key))
+ {
+ this.animations.loadFrameData(this.game.cache.getFrameData(key));
+
+ if (frame !== null)
+ {
+ if (typeof frame === 'string')
+ {
+ this.frameName = frame;
+ }
+ else
+ {
+ this.frame = frame;
+ }
+ }
+ }
+ else
+ {
+ this.currentFrame = this.game.cache.getFrame(key);
+ }
+ }
+
+ // this.loadTexture(key, frame);
+
+ /**
+ * The rectangular area from the texture that will be rendered.
+ * @property {Phaser.Rectangle} textureRegion
+ */
+ // this.textureRegion = new Phaser.Rectangle(this.texture.frame.x, this.texture.frame.y, this.texture.frame.width, this.texture.frame.height);
+
+ this.position.x = x;
+ this.position.y = y;
+
+ /**
+ * @property {Phaser.Point} world - The world coordinates of this Sprite. This differs from the x/y coordinates which are relative to the Sprites container.
+ */
+ this.world = new Phaser.Point(x, y);
+
+ /**
+ * Should this Sprite be automatically culled if out of range of the camera?
+ * A culled sprite has its renderable property set to 'false'.
+ * Be advised this is quite an expensive operation, as it has to calculate the bounds of the object every frame, so only enable it if you really need it.
+ *
+ * @property {boolean} autoCull - A flag indicating if the Sprite should be automatically camera culled or not.
+ * @default
+ */
+ this.autoCull = false;
+
+ /**
+ * A Sprite 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 Sprite to the Camera.
+ * @default
+ */
+ this.fixedToCamera = false;
+
+ /**
+ * @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(x, y);
+
+};
+
+Phaser.Image.prototype = Object.create(PIXI.Sprite.prototype);
+Phaser.Image.prototype.constructor = Phaser.Image;
+
+/**
+* Automatically called by World.preUpdate. Handles cache updates, lifespan checks, animation updates and physics updates.
+*
+* @method Phaser.Image#preUpdate
+* @memberof Phaser.Image
+*/
+Phaser.Image.prototype.preUpdate = function() {
+
+ if (!this.exists || !this.parent.exists)
+ {
+ return false;
+ }
+
+ if (this.autoCull)
+ {
+ // Won't get rendered but will still get its transform updated
+ this.renderable = this.game.world.camera.screenView.intersects(this.getBounds());
+ }
+
+ return true;
+
+};
+
+/**
+* Checks if the Image bounds are within the game world, otherwise false if fully outside of it.
+*
+* @method Phaser.Image#inWorld
+* @memberof Phaser.Image
+* @return {boolean} True if the Image bounds is within the game world, otherwise false if fully outside of it.
+*/
+Phaser.Image.prototype.inWorld = function() {
+
+ return this.game.world.bounds.intersects(this.getBounds());
+
+};
+
+/**
+* Resets the Sprite.crop value back to the frame dimensions.
+*
+* @method Phaser.Image#resetCrop
+* @memberof Phaser.Image
+Phaser.Image.prototype.resetCrop = function() {
+
+ this.crop = new Phaser.Rectangle(0, 0, this._cache.width, this._cache.height);
+ this.texture.setFrame(this.crop);
+ this.cropEnabled = false;
+
+};
+*/
+
+/**
+* Internal function called by the World postUpdate cycle.
+*
+* @method Phaser.Image#postUpdate
+* @memberof Phaser.Image
+*/
+Phaser.Image.prototype.postUpdate = function() {
+
+ if (this.key instanceof Phaser.BitmapData && this.key._dirty)
+ {
+ this.key.render();
+ }
+
+ if (this.exists)
+ {
+ // if (this.body)
+ // {
+ // this.body.postUpdate();
+ // }
+
+ if (this.fixedToCamera)
+ {
+ this.position.x = this.game.camera.view.x + this.cameraOffset.x;
+ this.position.y = this.game.camera.view.y + this.cameraOffset.y;
+ }
+
+ }
+
+};
+
+/**
+* Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
+* This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
+*
+* @method Phaser.Image#loadTexture
+* @memberof Phaser.Image
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|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, BitmapData 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.Image.prototype.loadTexture = function (key, frame) {
+
+ console.log('loadTexture');
+
+ this.key = key;
+
+ if (key instanceof Phaser.RenderTexture)
+ {
+ this.game.cache.getTextureFrame(key.name).clone(this.currentFrame);
+ }
+ else if (key instanceof Phaser.BitmapData)
+ {
+ this.setTexture(key.texture);
+ this.currentFrame = key.textureFrame;
+ }
+ else if (key instanceof PIXI.Texture)
+ {
+ // this.currentFrame = frame;
+ frame.clone(this.currentFrame);
+ console.log('loadTexture 2');
+ }
+ else
+ {
+ if (typeof key === 'undefined' || this.game.cache.checkImageKey(key) === false)
+ {
+ key = '__default';
+ this.key = key;
+ }
+
+ if (this.game.cache.isSpriteSheet(key))
+ {
+ // this.animations.loadFrameData(this.game.cache.getFrameData(key));
+
+ // if (typeof frame !== 'undefined')
+ // {
+ // if (typeof frame === 'string')
+ // {
+ // this.frameName = frame;
+ // }
+ // else
+ // {
+ // this.frame = frame;
+ // }
+ // }
+ }
+ else
+ {
+ console.log('loadTexture 1', this.game.cache.getFrame(key));
+
+ this.game.cache.getFrame(key).getRect(this.currentFrame);
+
+ console.log('loadTexture 1', this.currentFrame);
+
+ this.setTexture(PIXI.TextureCache[key]);
+ }
+ }
+
+};
+
+/**
+* Moves the sprite so its center is located on the given x and y coordinates.
+* Doesn't change the anchor point of the sprite.
+*
+* @method Phaser.Image#centerOn
+* @memberof Phaser.Image
+* @param {number} x - The x coordinate (in world space) to position the Sprite at.
+* @param {number} y - The y coordinate (in world space) to position the Sprite at.
+* @return (Phaser.Image) This instance.
+Phaser.Image.prototype.centerOn = function(x, 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;
+
+};
+*/
+
+/**
+* Brings a 'dead' Sprite back to life, optionally giving it the health value specified.
+* A resurrected Sprite has its alive, exists and visible properties all set to true.
+* It will dispatch the onRevived event, you can listen to Sprite.events.onRevived for the signal.
+*
+* @method Phaser.Image#revive
+* @memberof Phaser.Image
+* @return (Phaser.Image) This instance.
+*/
+Phaser.Image.prototype.revive = function() {
+
+ this.alive = true;
+ this.exists = true;
+ this.visible = true;
+
+ if (this.events)
+ {
+ this.events.onRevived.dispatch(this);
+ }
+
+ return this;
+
+};
+
+/**
+* Kills a Sprite. A killed Sprite has its alive, exists and visible properties all set to false.
+* It will dispatch the onKilled event, you can listen to Sprite.events.onKilled for the signal.
+* Note that killing a Sprite is a way for you to quickly recycle it in a Sprite pool, it doesn't free it up from memory.
+* If you don't need this Sprite any more you should call Sprite.destroy instead.
+*
+* @method Phaser.Image#kill
+* @memberof Phaser.Image
+* @return (Phaser.Image) This instance.
+*/
+Phaser.Image.prototype.kill = function() {
+
+ this.alive = false;
+ this.exists = false;
+ this.visible = false;
+
+ if (this.events)
+ {
+ this.events.onKilled.dispatch(this);
+ }
+
+ return this;
+
+};
+
+/**
+* Destroys the Sprite. This removes it from its parent group, destroys the input, event and animation handlers if present
+* and nulls its reference to game, freeing it up for garbage collection.
+*
+* @method Phaser.Image#destroy
+* @memberof Phaser.Image
+*/
+Phaser.Image.prototype.destroy = function() {
+
+ if (this.filters)
+ {
+ this.filters = null;
+ }
+
+ if (this.parent)
+ {
+ this.parent.remove(this);
+ }
+
+ if (this.events)
+ {
+ this.events.destroy();
+ }
+
+ this.alive = false;
+ this.exists = false;
+ this.visible = false;
+
+ this.game = null;
+
+};
+
+/**
+* Resets the Sprite. This places the Sprite at the given x/y world coordinates and then
+* sets alive, exists, visible and renderable all to true. Also resets the outOfBounds state and health values.
+* If the Sprite has a physics body that too is reset.
+*
+* @method Phaser.Image#reset
+* @memberof Phaser.Image
+* @param {number} x - The x coordinate (in world space) to position the Sprite at.
+* @param {number} y - The y coordinate (in world space) to position the Sprite at.
+* @return (Phaser.Image) This instance.
+*/
+Phaser.Image.prototype.reset = function(x, y) {
+
+ this.world.setTo(x, y);
+ this.position.x = x;
+ this.position.y = y;
+ this.alive = true;
+ this.exists = true;
+ this.visible = true;
+ this.renderable = true;
+ this._outOfBoundsFired = false;
+
+ return this;
+
+};
+
+/**
+* Brings the Sprite to the top of the display list it is a child of. Sprites that are members of a Phaser.Group are only
+* bought to the top of that Group, not the entire display list.
+*
+* @method Phaser.Image#bringToTop
+* @memberof Phaser.Image
+* @return (Phaser.Image) This instance.
+*/
+Phaser.Image.prototype.bringToTop = function(child) {
+
+ if (typeof child === 'undefined')
+ {
+ if (this.parent)
+ {
+ this.parent.bringToTop(this);
+ }
+ }
+ else
+ {
+
+ }
+
+ return this;
+
+};
+
+/**
+* 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.Image#angle
+* @property {number} angle - Gets or sets the Sprites angle of rotation in degrees.
+*/
+Object.defineProperty(Phaser.Image.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.Image#inCamera
+* @property {boolean} inCamera - Is this sprite visible to the camera or not?
+* @readonly
+*/
+Object.defineProperty(Phaser.Image.prototype, "inCamera", {
+
+ get: function () {
+ return this._cache.cameraVisible;
+ }
+
+});
+
diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js
index 27f27c83..0b98feb1 100644
--- a/src/gameobjects/Sprite.js
+++ b/src/gameobjects/Sprite.js
@@ -946,8 +946,8 @@ Phaser.Sprite.prototype.reset = function(x, y, health) {
if (typeof health === 'undefined') { health = 1; }
- this.x = x;
- this.y = y;
+ // this.x = x;
+ // this.y = y;
this.world.setTo(x, y);
this.position.x = this.x;
this.position.y = this.y;
@@ -978,9 +978,9 @@ Phaser.Sprite.prototype.reset = function(x, y, health) {
*/
Phaser.Sprite.prototype.bringToTop = function() {
- if (this.group)
+ if (this.parent)
{
- this.group.bringToTop(this);
+ this.parent.bringToTop(this);
}
else
{
@@ -1014,31 +1014,29 @@ 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
+*
+* @method Phaser.Sprite#deltaX
+* @memberof Phaser.Sprite
+* @return {number} The delta value. Positive if the motion was to the right, negative if to the left.
*/
-Object.defineProperty(Phaser.Sprite.prototype, 'deltaX', {
+Phaser.Sprite.prototype.deltaX = function () {
- get: function() {
- return this.world.x - this._cache.prevX;
- }
+ 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
+*
+* @method Phaser.Sprite#deltaY
+* @memberof Phaser.Sprite
+* @return {number} The delta value. Positive if the motion was downwards, negative if upwards.
*/
-Object.defineProperty(Phaser.Sprite.prototype, 'deltaY', {
+Phaser.Sprite.prototype.deltaY = function () {
- get: function() {
- return this.world.y - this._cache.prevY;
- }
+ 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.
@@ -1137,21 +1135,21 @@ Object.defineProperty(Phaser.Sprite.prototype, "worldCenterY", {
* @name Phaser.Sprite#width
* @property {number} width - The width of the Sprite in pixels.
*/
-Object.defineProperty(Phaser.Sprite.prototype, 'width', {
+// Object.defineProperty(Phaser.Sprite.prototype, 'width', {
- get: function() {
- return this.scale.x * this.currentFrame.width;
- },
+// get: function() {
+// return this.scale.x * this.currentFrame.width;
+// },
- set: function(value) {
+// set: function(value) {
- this.scale.x = value / this.currentFrame.width;
- this._cache.scaleX = value / this.currentFrame.width;
- this._width = value;
+// this.scale.x = value / this.currentFrame.width;
+// this._cache.scaleX = value / this.currentFrame.width;
+// this._width = value;
- }
+// }
-});
+// });
/**
* The height of the sprite in pixels, setting this will actually modify the scale to acheive the value desired.
@@ -1160,21 +1158,21 @@ Object.defineProperty(Phaser.Sprite.prototype, 'width', {
* @name Phaser.Sprite#height
* @property {number} height - The height of the Sprite in pixels.
*/
-Object.defineProperty(Phaser.Sprite.prototype, 'height', {
+// Object.defineProperty(Phaser.Sprite.prototype, 'height', {
- get: function() {
- return this.scale.y * this.currentFrame.height;
- },
+// get: function() {
+// return this.scale.y * this.currentFrame.height;
+// },
- set: function(value) {
+// set: function(value) {
- this.scale.y = value / this.currentFrame.height;
- this._cache.scaleY = value / this.currentFrame.height;
- this._height = value;
+// this.scale.y = value / this.currentFrame.height;
+// this._cache.scaleY = value / this.currentFrame.height;
+// this._height = value;
- }
+// }
-});
+// });
/**
* By default a Sprite won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is
From 7ba1196c0dd4a74fbad42b1fbe18e1b265bd68b7 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Thu, 6 Feb 2014 19:41:32 +0000
Subject: [PATCH 10/26] Fixed TypeScript defs on lines 1741-1748 (thanks
wombatbuddy)
---
README.md | 1 +
build/phaser.d.ts | 16 ++++++++--------
2 files changed, 9 insertions(+), 8 deletions(-)
diff --git a/README.md b/README.md
index 972e94ca..9b3aec4e 100644
--- a/README.md
+++ b/README.md
@@ -83,6 +83,7 @@ Bug Fixes:
* Explicitly paused Timer continues if you un-focus and focus the browser window (thanks georgiee)
* Added TimerEvent.pendingDelete and checks in Timer.update, so that removing an event in a callback no longer throws an exception (thanks georgiee)
+* Fixed TypeScript defs on lines 1741-1748 (thanks wombatbuddy)
You can view the Change Log for all previous versions at https://github.com/photonstorm/phaser/changelog.md
diff --git a/build/phaser.d.ts b/build/phaser.d.ts
index 03393e79..cc1d3087 100644
--- a/build/phaser.d.ts
+++ b/build/phaser.d.ts
@@ -1738,14 +1738,14 @@ declare module Phaser {
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;
+ 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;
From 4b7fc8d5067e7ac9db99d4d4387eb030474e4c20 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Thu, 6 Feb 2014 22:42:23 +0000
Subject: [PATCH 11/26] Change to boot order to try and resolve short-TTL
timers.
---
build/phaser.d.ts | 2 +-
src/core/Game.js | 2 +-
src/gameobjects/Image.js | 222 ++++++++++++---------------------------
3 files changed, 69 insertions(+), 157 deletions(-)
diff --git a/build/phaser.d.ts b/build/phaser.d.ts
index cc1d3087..c8786c83 100644
--- a/build/phaser.d.ts
+++ b/build/phaser.d.ts
@@ -1748,7 +1748,7 @@ declare module Phaser {
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;
+ 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;
diff --git a/src/core/Game.js b/src/core/Game.js
index 13466bc9..9d841e4b 100644
--- a/src/core/Game.js
+++ b/src/core/Game.js
@@ -457,7 +457,6 @@ Phaser.Game.prototype = {
this.world.boot();
this.input.boot();
this.sound.boot();
- this.state.boot();
this.load.onLoadComplete.add(this.loadComplete, this);
@@ -469,6 +468,7 @@ Phaser.Game.prototype = {
this.raf = new Phaser.RequestAnimationFrame(this);
this.raf.start();
+ this.state.boot();
}
},
diff --git a/src/gameobjects/Image.js b/src/gameobjects/Image.js
index f78dc678..3ee0d82b 100644
--- a/src/gameobjects/Image.js
+++ b/src/gameobjects/Image.js
@@ -60,68 +60,9 @@ Phaser.Image = function (game, x, y, key, frame) {
this.currentFrame = new Phaser.Rectangle();
- if (key instanceof Phaser.RenderTexture)
- {
- PIXI.Sprite.call(this, key);
+ PIXI.Sprite.call(this, PIXI.TextureCache['__default']);
- this.currentFrame = this.game.cache.getTextureFrame(key.name);
- }
- else if (key instanceof Phaser.BitmapData)
- {
- PIXI.Sprite.call(this, key.texture, key.textureFrame);
-
- this.currentFrame = key.textureFrame;
- }
- else if (key instanceof PIXI.Texture)
- {
- PIXI.Sprite.call(this, key);
-
- this.currentFrame = frame;
- }
- else
- {
- if (key === null || typeof key === 'undefined')
- {
- key = '__default';
- this.key = key;
- }
- else if (typeof key === 'string' && this.game.cache.checkImageKey(key) === false)
- {
- key = '__missing';
- this.key = key;
- }
-
- PIXI.Sprite.call(this, PIXI.TextureCache[key]);
-
- if (this.game.cache.isSpriteSheet(key))
- {
- this.animations.loadFrameData(this.game.cache.getFrameData(key));
-
- if (frame !== null)
- {
- if (typeof frame === 'string')
- {
- this.frameName = frame;
- }
- else
- {
- this.frame = frame;
- }
- }
- }
- else
- {
- this.currentFrame = this.game.cache.getFrame(key);
- }
- }
-
- // this.loadTexture(key, frame);
-
- /**
- * The rectangular area from the texture that will be rendered.
- * @property {Phaser.Rectangle} textureRegion
- */
- // this.textureRegion = new Phaser.Rectangle(this.texture.frame.x, this.texture.frame.y, this.texture.frame.width, this.texture.frame.height);
+ this.loadTexture(key, frame);
this.position.x = x;
this.position.y = y;
@@ -142,17 +83,13 @@ Phaser.Image = function (game, x, y, key, frame) {
this.autoCull = false;
/**
- * A Sprite 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.
+ * A Sprite that is fixed to the camera uses its x/y coordinates as offsets from the top left of the camera.
+ * Note that if this Image is a child of a display object that has changed its position then the offset will be calculated from that.
* @property {boolean} fixedToCamera - Fixes this Sprite to the Camera.
* @default
*/
this.fixedToCamera = false;
- /**
- * @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(x, y);
-
};
Phaser.Image.prototype = Object.create(PIXI.Sprite.prototype);
@@ -181,33 +118,6 @@ Phaser.Image.prototype.preUpdate = function() {
};
-/**
-* Checks if the Image bounds are within the game world, otherwise false if fully outside of it.
-*
-* @method Phaser.Image#inWorld
-* @memberof Phaser.Image
-* @return {boolean} True if the Image bounds is within the game world, otherwise false if fully outside of it.
-*/
-Phaser.Image.prototype.inWorld = function() {
-
- return this.game.world.bounds.intersects(this.getBounds());
-
-};
-
-/**
-* Resets the Sprite.crop value back to the frame dimensions.
-*
-* @method Phaser.Image#resetCrop
-* @memberof Phaser.Image
-Phaser.Image.prototype.resetCrop = function() {
-
- this.crop = new Phaser.Rectangle(0, 0, this._cache.width, this._cache.height);
- this.texture.setFrame(this.crop);
- this.cropEnabled = false;
-
-};
-*/
-
/**
* Internal function called by the World postUpdate cycle.
*
@@ -221,23 +131,40 @@ Phaser.Image.prototype.postUpdate = function() {
this.key.render();
}
- if (this.exists)
+ if (this.fixedToCamera)
{
- // if (this.body)
- // {
- // this.body.postUpdate();
- // }
-
- if (this.fixedToCamera)
- {
- this.position.x = this.game.camera.view.x + this.cameraOffset.x;
- this.position.y = this.game.camera.view.y + this.cameraOffset.y;
- }
-
+ this.position.x = this.game.camera.view.x + this.x;
+ this.position.y = this.game.camera.view.y + this.y;
}
};
+/**
+* Checks if the Image bounds are within the game world, otherwise false if fully outside of it.
+*
+* @method Phaser.Image#inWorld
+* @memberof Phaser.Image
+* @return {boolean} True if the Image bounds is within the game world, even if only partially. Otherwise false if fully outside of it.
+*/
+Phaser.Image.prototype.inWorld = function() {
+
+ return this.game.world.bounds.intersects(this.getBounds());
+
+};
+
+/**
+* Checks if the Image bounds are within the game camera, otherwise false if fully outside of it.
+*
+* @method Phaser.Image#inCamera
+* @memberof Phaser.Image
+* @return {boolean} True if the Image bounds is within the game camera, even if only partially. Otherwise false if fully outside of it.
+*/
+Phaser.Image.prototype.inCamera = function() {
+
+ return this.game.world.camera.screenView.intersects(this.getBounds());
+
+};
+
/**
* Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
* This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
@@ -270,11 +197,16 @@ Phaser.Image.prototype.loadTexture = function (key, frame) {
}
else
{
- if (typeof key === 'undefined' || this.game.cache.checkImageKey(key) === false)
+ if (key === null || typeof key === 'undefined')
{
key = '__default';
this.key = key;
}
+ else if (typeof key === 'string' && this.game.cache.checkImageKey(key) === false)
+ {
+ key = '__missing';
+ this.key = key;
+ }
if (this.game.cache.isSpriteSheet(key))
{
@@ -307,31 +239,19 @@ Phaser.Image.prototype.loadTexture = function (key, frame) {
};
/**
-* Moves the sprite so its center is located on the given x and y coordinates.
-* Doesn't change the anchor point of the sprite.
-*
-* @method Phaser.Image#centerOn
+* Crop allows you to crop the texture used to display this Image. Cropping takes place from the top-left of the Image and can be modified in real-time.
+*
+* @method Phaser.Image#crop
* @memberof Phaser.Image
-* @param {number} x - The x coordinate (in world space) to position the Sprite at.
-* @param {number} y - The y coordinate (in world space) to position the Sprite at.
-* @return (Phaser.Image) This instance.
-Phaser.Image.prototype.centerOn = function(x, y) {
+* @param {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.Image.prototype.crop = function(x, y, width, height) {
- 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;
+ // this.crop = new Phaser.Rectangle(0, 0, this._cache.width, this._cache.height);
+ // this.texture.setFrame(this.crop);
+ // this.cropEnabled = false;
};
-*/
/**
* Brings a 'dead' Sprite back to life, optionally giving it the health value specified.
@@ -340,7 +260,7 @@ Phaser.Image.prototype.centerOn = function(x, y) {
*
* @method Phaser.Image#revive
* @memberof Phaser.Image
-* @return (Phaser.Image) This instance.
+* @return {Phaser.Image} This instance.
*/
Phaser.Image.prototype.revive = function() {
@@ -365,7 +285,7 @@ Phaser.Image.prototype.revive = function() {
*
* @method Phaser.Image#kill
* @memberof Phaser.Image
-* @return (Phaser.Image) This instance.
+* @return {Phaser.Image} This instance.
*/
Phaser.Image.prototype.kill = function() {
@@ -423,7 +343,7 @@ Phaser.Image.prototype.destroy = function() {
* @memberof Phaser.Image
* @param {number} x - The x coordinate (in world space) to position the Sprite at.
* @param {number} y - The y coordinate (in world space) to position the Sprite at.
-* @return (Phaser.Image) This instance.
+* @return {Phaser.Image} This instance.
*/
Phaser.Image.prototype.reset = function(x, y) {
@@ -446,7 +366,7 @@ Phaser.Image.prototype.reset = function(x, y) {
*
* @method Phaser.Image#bringToTop
* @memberof Phaser.Image
-* @return (Phaser.Image) This instance.
+* @return {Phaser.Image} This instance.
*/
Phaser.Image.prototype.bringToTop = function(child) {
@@ -469,32 +389,24 @@ Phaser.Image.prototype.bringToTop = function(child) {
/**
* 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.Image#angle
-* @property {number} angle - Gets or sets the Sprites angle of rotation in degrees.
+* If you wish to work in radians instead of degrees use the property Sprite.rotation instead. Working in radians is also computationally faster.
+*
+* @method Phaser.Image#angle
+* @memberof Phaser.Image
+* @param {number} [value] - If given it will set the Images angle to this value. Value should be given in degrees.
+* @return {number} The angle of this Image in degrees.
*/
-Object.defineProperty(Phaser.Image.prototype, 'angle', {
+Phaser.Image.prototype.angle = function(value) {
- get: function() {
+ if (typeof value === 'undefined')
+ {
return Phaser.Math.wrapAngle(Phaser.Math.radToDeg(this.rotation));
- },
-
- set: function(value) {
+ }
+ else
+ {
this.rotation = Phaser.Math.degToRad(Phaser.Math.wrapAngle(value));
+
+ return Phaser.Math.radToDeg(this.rotation);
}
-});
-
-/**
-* @name Phaser.Image#inCamera
-* @property {boolean} inCamera - Is this sprite visible to the camera or not?
-* @readonly
-*/
-Object.defineProperty(Phaser.Image.prototype, "inCamera", {
-
- get: function () {
- return this._cache.cameraVisible;
- }
-
-});
-
+};
From 6cabb03a825c7e937df96a53197401e4ce71a704 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Thu, 6 Feb 2014 23:13:39 +0000
Subject: [PATCH 12/26] Sprite.crop() now takes a Phaser.Rectangle instead of
explicit parameters. Phaser.Image is a brand new display object perfect for
logos, backgrounds, etc. You can scale, rotate, tint and blend and Image, but
it has no animation, physics body or input events. Previously if you used
Sprite.crop() it would crop all Sprites using the same base image. It now
takes a local copy of the texture data and crops just that.
---
README.md | 3 +++
examples/wip/image2.js | 19 ++++++++++++++++--
src/gameobjects/Image.js | 43 +++++++++++++++++++++++++++++++++++-----
3 files changed, 58 insertions(+), 7 deletions(-)
diff --git a/README.md b/README.md
index 9b3aec4e..0b8f4598 100644
--- a/README.md
+++ b/README.md
@@ -68,10 +68,12 @@ Significant API changes:
* PIXI.Rectangle is now aliased to Phaser.Rectangle - saves on code duplication and works exactly the same.
* PIXI.Circle is now aliased to Phaser.Circle - saves on code duplication and works exactly the same.
* Sprite.deltaX and deltaY swapped to functions: Sprite.deltaX() and Sprite.deltaY()
+* Sprite.crop() now takes a Phaser.Rectangle instead of explicit parameters.
New features:
+* Phaser.Image is a brand new display object perfect for logos, backgrounds, etc. You can scale, rotate, tint and blend and Image, but it has no animation, physics body or input events.
New Examples:
@@ -84,6 +86,7 @@ Bug Fixes:
* Explicitly paused Timer continues if you un-focus and focus the browser window (thanks georgiee)
* Added TimerEvent.pendingDelete and checks in Timer.update, so that removing an event in a callback no longer throws an exception (thanks georgiee)
* Fixed TypeScript defs on lines 1741-1748 (thanks wombatbuddy)
+* Previously if you used Sprite.crop() it would crop all Sprites using the same base image. It now takes a local copy of the texture data and crops just that.
You can view the Change Log for all previous versions at https://github.com/photonstorm/phaser/changelog.md
diff --git a/examples/wip/image2.js b/examples/wip/image2.js
index 15560680..b289ac4f 100644
--- a/examples/wip/image2.js
+++ b/examples/wip/image2.js
@@ -1,4 +1,5 @@
+// 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() {
@@ -9,6 +10,7 @@ function preload() {
var image;
var image2;
+var r;
function create() {
@@ -16,6 +18,10 @@ function create() {
image2 = game.add.image(32, 250, 'pic');
+ r = new Phaser.Rectangle(0, 0, 100, 100);
+
+ image2.crop(r);
+
game.input.onDown.add(tint, this);
}
@@ -28,12 +34,21 @@ function tint() {
function update() {
- // image.angle += 1;
+ if (r && r.width < 300)
+ {
+ r.width += 1;
+ image2.crop(r);
+ }
+ else
+ {
+ image2.crop();
+ r = null;
+ }
}
function render() {
- // game.debug.renderText(sprite.position.y, 32, 32);
+ game.debug.renderText(image2.width, 32, 32);
}
diff --git a/src/gameobjects/Image.js b/src/gameobjects/Image.js
index 3ee0d82b..d56b6db7 100644
--- a/src/gameobjects/Image.js
+++ b/src/gameobjects/Image.js
@@ -90,6 +90,8 @@ Phaser.Image = function (game, x, y, key, frame) {
*/
this.fixedToCamera = false;
+
+
};
Phaser.Image.prototype = Object.create(PIXI.Sprite.prototype);
@@ -243,13 +245,44 @@ Phaser.Image.prototype.loadTexture = function (key, frame) {
*
* @method Phaser.Image#crop
* @memberof Phaser.Image
-* @param {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.Rectangle} rect - The Rectangle to crop the Image to. Pass as null to clear any previously set crop.
*/
-Phaser.Image.prototype.crop = function(x, y, width, height) {
+Phaser.Image.prototype.crop = function(rect) {
- // this.crop = new Phaser.Rectangle(0, 0, this._cache.width, this._cache.height);
- // this.texture.setFrame(this.crop);
- // this.cropEnabled = false;
+ if (typeof rect === 'undefined' || rect === null)
+ {
+ // Clear any crop that may be set
+ if (this.texture.hasOwnProperty('sourceWidth'))
+ {
+ this.texture.setFrame(new Phaser.Rectangle(0, 0, this.texture.sourceWidth, this.texture.sourceHeight));
+ }
+ }
+ else
+ {
+ // Do we need to clone the PIXI.Texture object?
+ if (this.texture instanceof PIXI.Texture)
+ {
+ // Yup, let's rock it ...
+ var local = {};
+
+ Phaser.Utils.extend(true, local, this.texture);
+
+ local.sourceWidth = local.width;
+ local.sourceHeight = local.height;
+ local.frame = rect;
+ local.width = rect.width;
+ local.height = rect.height;
+
+ this.texture = local;
+
+ this.texture.updateFrame = true;
+ PIXI.Texture.frameUpdates.push(this.texture);
+ }
+ else
+ {
+ this.texture.setFrame(rect);
+ }
+ }
};
From 3cae06d1addf35e0fe62840a528c159b27df6e55 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Fri, 7 Feb 2014 00:57:41 +0000
Subject: [PATCH 13/26] Phaser.AnimationParser now sets the trimmed data
directly for Pixi Texture frames. Tested across JSON Hash, JSON Data, Sprite
Sheet and XML.
---
README.md | 10 +++++
examples/wip/anim1.js | 18 ++++++++
examples/wip/anim2.js | 73 ++++++++++++++++++++++++++++++++
examples/wip/bounds.js | 32 ++++++++++++++
examples/wip/crop.js | 47 ++++++++++++++++++++
src/animation/AnimationParser.js | 30 +++++++++----
src/core/Stage.js | 15 ++-----
src/gameobjects/Image.js | 6 +--
src/utils/Debug.js | 19 +++++++--
9 files changed, 223 insertions(+), 27 deletions(-)
create mode 100644 examples/wip/anim1.js
create mode 100644 examples/wip/anim2.js
create mode 100644 examples/wip/bounds.js
create mode 100644 examples/wip/crop.js
diff --git a/README.md b/README.md
index 0b8f4598..45981fa4 100644
--- a/README.md
+++ b/README.md
@@ -69,6 +69,7 @@ Significant API changes:
* PIXI.Circle is now aliased to Phaser.Circle - saves on code duplication and works exactly the same.
* Sprite.deltaX and deltaY swapped to functions: Sprite.deltaX() and Sprite.deltaY()
* Sprite.crop() now takes a Phaser.Rectangle instead of explicit parameters.
+* PixiPatch no longer needed, all features that it patched are now native in Pixi :)
New features:
@@ -80,6 +81,9 @@ New Examples:
Updates:
+* Debug.renderRectangle has a new parameter: filled. If true it renders as with fillRect, if false strokeRect.
+* Phaser.AnimationParser now sets the trimmed data directly for Pixi Texture frames. Tested across JSON Hash, JSON Data, Sprite Sheet and XML.
+
Bug Fixes:
@@ -262,6 +266,12 @@ Beyond version 2.0
* Multiple Camera support.
+Nadion
+------
+
+[Nadion](https://github.com/jcd-as/nadion) is a set of powerful enhancements for Phaser that makes level building even easier. It includes features such as Trigger, Area, Alarms and Emitters, debug panels, state machines, parallax layer scrolling, 'developer mode' short-cuts and more.
+
+
Contributing
------------
diff --git a/examples/wip/anim1.js b/examples/wip/anim1.js
new file mode 100644
index 00000000..04c438e0
--- /dev/null
+++ b/examples/wip/anim1.js
@@ -0,0 +1,18 @@
+
+var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create });
+
+function preload() {
+
+ game.load.spritesheet('mummy', 'assets/sprites/metalslug_mummy37x45.png', 37, 45, 18);
+
+}
+
+function create() {
+
+ var mummy = game.add.sprite(300, 200, 'mummy', 5);
+
+ mummy.animations.add('walk');
+
+ mummy.animations.play('walk', 20, true);
+
+}
diff --git a/examples/wip/anim2.js b/examples/wip/anim2.js
new file mode 100644
index 00000000..b5eacdf6
--- /dev/null
+++ b/examples/wip/anim2.js
@@ -0,0 +1,73 @@
+
+var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create });
+
+function preload() {
+
+ game.load.atlasXML('seacreatures', 'assets/sprites/seacreatures.png', 'assets/sprites/seacreatures.xml');
+ // game.load.atlas('seacreatures', 'assets/sprites/seacreatures_json.png', 'assets/sprites/seacreatures_json.json');
+
+ // Just a few images to use in our underwater scene
+ game.load.image('undersea', 'assets/pics/undersea.jpg');
+ game.load.image('coral', 'assets/pics/seabed.png');
+
+}
+
+var jellyfish;
+var crab;
+var greenJellyfish;
+var octopus;
+var purpleFish;
+var seahorse;
+var squid;
+var stingray;
+var flyingfish;
+
+function create() {
+
+ game.add.sprite(0, 0, 'undersea');
+
+ jellyfish = game.add.sprite(670, 20, 'seacreatures', 'blueJellyfish0000');
+
+ // In the texture atlas the jellyfish uses the frame names blueJellyfish0000 to blueJellyfish0032
+ // So we can use the handy generateFrameNames function to create this for us.
+ jellyfish.animations.add('swim', Phaser.Animation.generateFrameNames('blueJellyfish', 0, 32, '', 4), 30, true);
+ jellyfish.animations.play('swim');
+
+ // Let's make some more sea creatures in the same way as the jellyfish
+ crab = game.add.sprite(550, 480, 'seacreatures');
+ crab.animations.add('swim', Phaser.Animation.generateFrameNames('crab1', 0, 25, '', 4), 30, true);
+ crab.animations.play('swim');
+
+ greenJellyfish = game.add.sprite(330, 100, 'seacreatures');
+ greenJellyfish.animations.add('swim', Phaser.Animation.generateFrameNames('greenJellyfish', 0, 39, '', 4), 30, true);
+ greenJellyfish.animations.play('swim');
+
+ octopus = game.add.sprite(160, 400, 'seacreatures');
+ octopus.animations.add('swim', Phaser.Animation.generateFrameNames('octopus', 0, 24, '', 4), 30, true);
+ octopus.animations.play('swim');
+
+ purpleFish = game.add.sprite(800, 413, 'seacreatures');
+ purpleFish.animations.add('swim', Phaser.Animation.generateFrameNames('purpleFish', 0, 20, '', 4), 30, true);
+ purpleFish.animations.play('swim');
+
+ seahorse = game.add.sprite(491, 40, 'seacreatures');
+ seahorse.animations.add('swim', Phaser.Animation.generateFrameNames('seahorse', 0, 5, '', 4), 30, true);
+ seahorse.animations.play('swim');
+
+ squid = game.add.sprite(610, 215, 'seacreatures', 'squid0000');
+
+ stingray = game.add.sprite(80, 190, 'seacreatures');
+ stingray.animations.add('swim', Phaser.Animation.generateFrameNames('stingray', 0, 23, '', 4), 30, true);
+ stingray.animations.play('swim');
+
+ flyingfish = game.add.sprite(60, 40, 'seacreatures', 'flyingFish0000');
+
+
+ game.add.sprite(0, 466, 'coral');
+
+ game.add.tween(purpleFish).to({ x: -200 }, 7500, Phaser.Easing.Quadratic.InOut, true, 0, 1000, false);
+ game.add.tween(octopus).to({ y: 530 }, 2000, Phaser.Easing.Quadratic.InOut, true, 0, 1000, true);
+ game.add.tween(greenJellyfish).to({ y: 250 }, 4000, Phaser.Easing.Quadratic.InOut, true, 0, 1000, true);
+ game.add.tween(jellyfish).to({ y: 100 }, 8000, Phaser.Easing.Quadratic.InOut, true, 0, 1000, true);
+
+}
diff --git a/examples/wip/bounds.js b/examples/wip/bounds.js
new file mode 100644
index 00000000..e60e2713
--- /dev/null
+++ b/examples/wip/bounds.js
@@ -0,0 +1,32 @@
+
+var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('pic', 'assets/sprites/exocet_spaceman.png');
+
+}
+
+var sprite;
+
+function create() {
+
+ game.stage.backgroundColor = '#997683';
+
+ sprite = game.add.sprite(game.world.centerX, game.world.centerY, 'pic');
+ sprite.anchor.setTo(0.5);
+
+}
+
+
+function update() {
+
+ sprite.rotation += 0.01;
+
+}
+
+function render() {
+
+ game.debug.renderRectangle(sprite.getLocalBounds(), 'rgb(255, 255, 255)', false);
+
+}
diff --git a/examples/wip/crop.js b/examples/wip/crop.js
new file mode 100644
index 00000000..14f3803f
--- /dev/null
+++ b/examples/wip/crop.js
@@ -0,0 +1,47 @@
+
+// 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() {
+
+ game.load.image('pic', 'assets/pics/backscroll.png');
+
+}
+
+var image;
+var image2;
+var r;
+
+function create() {
+
+ image = game.add.image(32, 50, 'pic');
+ image2 = game.add.image(32, 250, 'pic');
+
+ r = new Phaser.Rectangle(0, 0, 0, 176);
+
+ image2.crop(r);
+
+}
+
+function update() {
+
+ if (r !== null)
+ {
+ r.width += 1;
+
+ image2.crop(r);
+
+ if (r.width == 720)
+ {
+ image2.crop();
+ r = null;
+ }
+ }
+
+}
+
+function render() {
+
+ game.debug.renderText(image2.width, 32, 32);
+
+}
diff --git a/src/animation/AnimationParser.js b/src/animation/AnimationParser.js
index d8bcd720..03b4b25c 100644
--- a/src/animation/AnimationParser.js
+++ b/src/animation/AnimationParser.js
@@ -153,10 +153,14 @@ Phaser.AnimationParser = {
frames[i].spriteSourceSize.h
);
- // We had to hack Pixi to get this to work :(
PIXI.TextureCache[uuid].trimmed = true;
- PIXI.TextureCache[uuid].trim.x = frames[i].spriteSourceSize.x;
- PIXI.TextureCache[uuid].trim.y = frames[i].spriteSourceSize.y;
+
+ PIXI.TextureCache[uuid].trim = {
+ x: frames[i].spriteSourceSize.x,
+ y: frames[i].spriteSourceSize.y,
+ realWidth: frames[i].sourceSize.w,
+ realHeight: frames[i].sourceSize.h
+ }
}
}
@@ -225,10 +229,14 @@ Phaser.AnimationParser = {
frames[key].spriteSourceSize.h
);
- // We had to hack Pixi to get this to work :(
PIXI.TextureCache[uuid].trimmed = true;
- PIXI.TextureCache[uuid].trim.x = frames[key].spriteSourceSize.x;
- PIXI.TextureCache[uuid].trim.y = frames[key].spriteSourceSize.y;
+
+ PIXI.TextureCache[uuid].trim = {
+ x: frames[i].spriteSourceSize.x,
+ y: frames[i].spriteSourceSize.y,
+ realWidth: frames[i].sourceSize.w,
+ realHeight: frames[i].sourceSize.h
+ }
}
@@ -313,10 +321,14 @@ Phaser.AnimationParser = {
PIXI.TextureCache[uuid].realSize = { x: frameX, y: frameY, w: frameWidth, h: frameHeight };
- // We had to hack Pixi to get this to work :(
PIXI.TextureCache[uuid].trimmed = true;
- PIXI.TextureCache[uuid].trim.x = frameX;
- PIXI.TextureCache[uuid].trim.y = frameY;
+
+ PIXI.TextureCache[uuid].trim = {
+ x: frameX,
+ y: frameY,
+ realWidth: width,
+ realHeight: height
+ }
}
}
diff --git a/src/core/Stage.js b/src/core/Stage.js
index e766fe6b..ce3fa01f 100644
--- a/src/core/Stage.js
+++ b/src/core/Stage.js
@@ -248,21 +248,12 @@ Object.defineProperty(Phaser.Stage.prototype, "backgroundColor", {
if (this.game.transparent === false)
{
- if (this.game.renderType == Phaser.CANVAS)
+ if (typeof color === 'string')
{
- // Set it directly, this allows us to use rgb alpha values in Canvas mode.
- this.game.canvas.style.backgroundColor = color;
- }
- else
- {
- if (typeof color === 'string')
- {
- color = Phaser.Color.hexToRGB(color);
- }
-
- this._stage.setBackgroundColor(color);
+ color = Phaser.Color.hexToRGB(color);
}
+ this._stage.setBackgroundColor(color);
}
}
diff --git a/src/gameobjects/Image.js b/src/gameobjects/Image.js
index d56b6db7..c9fb5073 100644
--- a/src/gameobjects/Image.js
+++ b/src/gameobjects/Image.js
@@ -90,8 +90,6 @@ Phaser.Image = function (game, x, y, key, frame) {
*/
this.fixedToCamera = false;
-
-
};
Phaser.Image.prototype = Object.create(PIXI.Sprite.prototype);
@@ -185,6 +183,7 @@ Phaser.Image.prototype.loadTexture = function (key, frame) {
if (key instanceof Phaser.RenderTexture)
{
this.game.cache.getTextureFrame(key.name).clone(this.currentFrame);
+ // WOKWOKSK
}
else if (key instanceof Phaser.BitmapData)
{
@@ -241,7 +240,8 @@ Phaser.Image.prototype.loadTexture = function (key, frame) {
};
/**
-* Crop allows you to crop the texture used to display this Image. Cropping takes place from the top-left of the Image and can be modified in real-time.
+* Crop allows you to crop the texture used to display this Image.
+* Cropping takes place from the top-left of the Image and can be modified in real-time by providing an updated rectangle object.
*
* @method Phaser.Image#crop
* @memberof Phaser.Image
diff --git a/src/utils/Debug.js b/src/utils/Debug.js
index b44fc1d5..3da168af 100644
--- a/src/utils/Debug.js
+++ b/src/utils/Debug.js
@@ -745,19 +745,32 @@ Phaser.Utils.Debug.prototype = {
* @method Phaser.Utils.Debug#renderRectangle
* @param {Phaser.Rectangle} rect - The Rectangle to render.
* @param {string} [color] - Color of the debug info to be rendered (format is css color string).
+ * @param {boolean} [filled=true] - Render the rectangle as a fillRect (default, true) or a strokeRect (false)
*/
- renderRectangle: function (rect, color) {
+ renderRectangle: function (rect, color, filled) {
if (this.context == null)
{
return;
}
+ if (typeof filled === 'undefined') { filled = true; }
+
color = color || 'rgba(0,255,0,0.3)';
this.start();
- this.context.fillStyle = color;
- this.context.fillRect(rect.x, rect.y, rect.width, rect.height);
+
+ if (filled)
+ {
+ this.context.fillStyle = color;
+ this.context.fillRect(rect.x, rect.y, rect.width, rect.height);
+ }
+ else
+ {
+ this.context.strokeStyle = color;
+ this.context.strokeRect(rect.x, rect.y, rect.width, rect.height);
+ }
+
this.stop();
},
From ddc255382d46b1284b683cc90ee13f75d3d10044 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Fri, 7 Feb 2014 02:31:29 +0000
Subject: [PATCH 14/26] Updated Rectangle to use prototype based getters and
setters (re: iOS speed discussion on the forum).
---
examples/wip/bmd.js | 44 +++++
examples/wip/rendertexture.js | 54 +++++
src/gameobjects/Image.js | 9 +-
src/gameobjects/RenderTexture.js | 286 ++-------------------------
src/geom/Rectangle.js | 325 ++++++++++++++++---------------
5 files changed, 276 insertions(+), 442 deletions(-)
create mode 100644 examples/wip/bmd.js
create mode 100644 examples/wip/rendertexture.js
diff --git a/examples/wip/bmd.js b/examples/wip/bmd.js
new file mode 100644
index 00000000..c9cd8a80
--- /dev/null
+++ b/examples/wip/bmd.js
@@ -0,0 +1,44 @@
+
+var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('pic', 'assets/pics/backscroll.png');
+
+}
+
+var image;
+var bmd;
+
+function create() {
+
+ bmd = game.add.bitmapData(800, 600);
+ bmd.fillStyle('rgba(255,0,0,0.2)');
+ // bmd.fillRect(0, 0, 300, 100);
+ // bmd.fillRect(0, 200, 300, 100);
+
+ image = game.add.image(0, 0, bmd);
+ // image.anchor.set(0.5);
+
+ game.input.onDown.add(tint, this);
+
+}
+
+function tint() {
+
+ image.tint = Math.random() * 0xFFFFFF;
+
+}
+
+function update() {
+
+ bmd.fillStyle('rgba(255,0,0,0.2)');
+ bmd.fillRect(game.input.x, game.input.y, 6, 6);
+
+}
+
+function render() {
+
+ game.debug.renderText(game.input.x, 32, 32);
+
+}
diff --git a/examples/wip/rendertexture.js b/examples/wip/rendertexture.js
new file mode 100644
index 00000000..bacc9698
--- /dev/null
+++ b/examples/wip/rendertexture.js
@@ -0,0 +1,54 @@
+
+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 mushroom;
+var texture;
+var image;
+
+function create() {
+
+ // Here we'll create a renderTexture the same size as our game
+ texture = game.add.renderTexture('mousetrail', 800, 600);
+
+ // This is the sprite that will be drawn to the texture, we set it to visible false as we only need its texture data
+ mushroom = game.add.sprite(0, 0, 'mushroom');
+ // mushroom.visible = false;
+ // mushroom.anchor.setTo(0.5, 0.5);
+
+ // This is the sprite that is drawn to the display. We've given it the renderTexture as its texture.
+ // game.add.image(0, 0, texture);
+
+
+ game.input.onDown.add(tint, this);
+
+}
+
+function tint() {
+
+ image.tint = Math.random() * 0xFFFFFF;
+
+}
+
+function update() {
+
+ 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);
+ }
+
+}
+
+function render() {
+
+ game.debug.renderText(game.input.x, 32, 32);
+
+}
diff --git a/src/gameobjects/Image.js b/src/gameobjects/Image.js
index c9fb5073..690670d6 100644
--- a/src/gameobjects/Image.js
+++ b/src/gameobjects/Image.js
@@ -96,7 +96,7 @@ Phaser.Image.prototype = Object.create(PIXI.Sprite.prototype);
Phaser.Image.prototype.constructor = Phaser.Image;
/**
-* Automatically called by World.preUpdate. Handles cache updates, lifespan checks, animation updates and physics updates.
+* Automatically called by World.preUpdate.
*
* @method Phaser.Image#preUpdate
* @memberof Phaser.Image
@@ -114,6 +114,8 @@ Phaser.Image.prototype.preUpdate = function() {
this.renderable = this.game.world.camera.screenView.intersects(this.getBounds());
}
+ this.world.setTo(this.game.camera.x + this.worldTransform[2], this.game.camera.y + this.worldTransform[5]);
+
return true;
};
@@ -176,19 +178,16 @@ Phaser.Image.prototype.inCamera = function() {
*/
Phaser.Image.prototype.loadTexture = function (key, frame) {
- console.log('loadTexture');
-
this.key = key;
if (key instanceof Phaser.RenderTexture)
{
- this.game.cache.getTextureFrame(key.name).clone(this.currentFrame);
+ // this.game.cache.getTextureFrame(key.name).clone(this.currentFrame);
// WOKWOKSK
}
else if (key instanceof Phaser.BitmapData)
{
this.setTexture(key.texture);
- this.currentFrame = key.textureFrame;
}
else if (key instanceof PIXI.Texture)
{
diff --git a/src/gameobjects/RenderTexture.js b/src/gameobjects/RenderTexture.js
index b6eab596..42c608b2 100644
--- a/src/gameobjects/RenderTexture.js
+++ b/src/gameobjects/RenderTexture.js
@@ -25,8 +25,6 @@ Phaser.RenderTexture = function (game, key, width, height) {
*/
this.name = key;
- PIXI.EventTarget.call(this);
-
/**
* @property {number} width - the width.
*/
@@ -37,11 +35,6 @@ Phaser.RenderTexture = function (game, key, width, height) {
*/
this.height = height || 100;
- /**
- * @property {PIXI.mat3} indetityMatrix - Matrix object.
- */
- this.indetityMatrix = PIXI.mat3.create();
-
/**
* @property {PIXI.Rectangle} frame - The frame for this texture.
*/
@@ -52,276 +45,19 @@ Phaser.RenderTexture = function (game, key, width, height) {
*/
this.type = Phaser.RENDERTEXTURE;
- this._tempPoint = { x: 0, y: 0 };
+ // this._tempPoint = { x: 0, y: 0 };
- if (PIXI.gl)
- {
- this.initWebGL();
- }
- else
- {
- this.initCanvas();
- }
+ // if (PIXI.gl)
+ // {
+ // this.initWebGL();
+ // }
+ // else
+ // {
+ // this.initCanvas();
+ // }
};
-Phaser.RenderTexture.prototype = Object.create(PIXI.Texture.prototype);
-Phaser.RenderTexture.prototype.constructor = PIXI.RenderTexture;
+Phaser.RenderTexture.prototype = Object.create(PIXI.RenderTexture.prototype);
+Phaser.RenderTexture.prototype.constructor = Phaser.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 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, renderHidden) {
-
- if (typeof position === 'undefined') { position = false; }
- if (typeof clear === 'undefined') { clear = false; }
- if (typeof renderHidden === 'undefined') { renderHidden = false; }
-
- if (PIXI.gl)
- {
- this.renderWebGL(displayObject, position, clear, renderHidden);
- }
- else
- {
- this.renderCanvas(displayObject, position, 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.
-*
-* @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, renderHidden) {
-
- this._tempPoint.x = x;
- this._tempPoint.y = y;
-
- this.render(displayObject, this._tempPoint, clear, renderHidden);
-
-}
-
-/**
-* 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();
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- this.glFramebuffer.width = this.width;
- this.glFramebuffer.height = this.height;
-
- this.baseTexture = new PIXI.BaseTexture();
-
- 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.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);
-
- this.baseTexture.isRender = true;
-
- 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);
-
- // set the correct render function..
- // this.render = this.renderWebGL;
-}
-
-/**
-* Resizes the RenderTexture.
-*
-* @method Phaser.RenderTexture#resize
-* @memberof Phaser.RenderTexture
-*/
-Phaser.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);
- }
-}
-
-/**
-* 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);
-
- this.baseTexture = new PIXI.BaseTexture(this.renderer.view);
- this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
-
- // this.render = this.renderCanvas;
-}
-
-/**
-* 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;
-
- // enable the alpha color mask..
- gl.colorMask(true, true, true, true);
-
- gl.viewport(0, 0, this.width, this.height);
-
- gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
-
- if (clear)
- {
- gl.clearColor(0,0,0, 0);
- gl.clear(gl.COLOR_BUFFER_BIT);
- }
-
- // 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;
-
- 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 < j; i++)
- {
- children[i].updateTransform();
- }
-
- var renderGroup = displayObject.__renderGroup;
-
- if (renderGroup)
- {
- if (displayObject == renderGroup.root)
- {
- renderGroup.render(this.projection, this.glFramebuffer);
- }
- else
- {
- renderGroup.renderSpecific(displayObject, this.projection, this.glFramebuffer);
- }
- }
- else
- {
- if (!this.renderGroup)
- {
- this.renderGroup = new PIXI.WebGLRenderGroup(gl);
- }
-
- this.renderGroup.setRenderable(displayObject);
- this.renderGroup.render(this.projection, this.glFramebuffer);
- }
-
- displayObject.worldTransform = originalWorldTransform;
-}
-
-/**
- * This function will draw the display object to the texture.
- *
-* @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;
-
- displayObject.worldTransform = PIXI.mat3.create();
-
- if (position)
- {
- displayObject.worldTransform[2] = position.x;
- displayObject.worldTransform[5] = position.y;
- }
-
- for (var i = 0, j = children.length; i < j; i++)
- {
- children[i].updateTransform();
- }
-
- if (clear)
- {
- this.renderer.context.clearRect(0, 0, this.width, this.height);
- }
-
- this.renderer.renderDisplayObject(displayObject, renderHidden);
-
- this.renderer.context.setTransform(1, 0, 0, 1, 0, 0);
-
-}
diff --git a/src/geom/Rectangle.js b/src/geom/Rectangle.js
index 2d872488..96270ea9 100644
--- a/src/geom/Rectangle.js
+++ b/src/geom/Rectangle.js
@@ -288,236 +288,235 @@ Phaser.Rectangle.prototype = {
return "[{Rectangle (x=" + this.x + " y=" + this.y + " width=" + this.width + " height=" + this.height + " empty=" + this.empty + ")}]";
- }
+ },
-};
+ /**
+ * @name Phaser.Rectangle#halfWidth
+ * @property {number} halfWidth - Half of the width of the Rectangle.
+ * @readonly
+ */
+ get halfWidth() {
-Phaser.Rectangle.prototype.constructor = Phaser.Rectangle;
-
-/**
-* @name Phaser.Rectangle#halfWidth
-* @property {number} halfWidth - Half of the width of the Rectangle.
-* @readonly
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "halfWidth", {
-
- get: function () {
return Math.round(this.width / 2);
- }
-});
+ },
-/**
-* @name Phaser.Rectangle#halfHeight
-* @property {number} halfHeight - Half of the height of the Rectangle.
-* @readonly
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "halfHeight", {
+ /**
+ * @name Phaser.Rectangle#halfHeight
+ * @property {number} halfHeight - Half of the height of the Rectangle.
+ * @readonly
+ */
+ get halfHeight() {
- get: function () {
return Math.round(this.height / 2);
- }
-});
+ },
+
+ /**
+ * 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.
+ * @name Phaser.Rectangle#bottom
+ * @property {number} bottom - The sum of the y and height properties.
+ */
+ get bottom() {
-/**
-* 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.
-* @name Phaser.Rectangle#bottom
-* @property {number} bottom - The sum of the y and height properties.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "bottom", {
-
- get: function () {
return this.y + this.height;
+
},
- set: function (value) {
- if (value <= this.y) {
+ set bottom(value) {
+
+ if (value <= this.y)
+ {
this.height = 0;
- } else {
+ }
+ else
+ {
this.height = (this.y - value);
}
- }
+ },
-});
+ /**
+ * The location of the Rectangles bottom right corner as a Point object.
+ * @name Phaser.Rectangle#bottomRight
+ * @property {Phaser.Point} bottomRight - Gets or sets the location of the Rectangles bottom right corner as a Point object.
+ */
+ get bottomRight() {
-/**
-* The location of the Rectangles bottom right corner as a Point object.
-* @name Phaser.Rectangle#bottom
-* @property {Phaser.Point} bottomRight - Gets or sets the location of the Rectangles bottom right corner as a Point object.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "bottomRight", {
-
- get: function () {
return new Phaser.Point(this.right, this.bottom);
},
- set: function (value) {
+
+ set bottomRight(value) {
+
this.right = value.x;
this.bottom = value.y;
- }
-});
-
-/**
-* The x coordinate of the left of the Rectangle. Changing the left property of a Rectangle object has no effect on the y and height properties. However it does affect the width property, whereas changing the x value does not affect the width property.
-* @name Phaser.Rectangle#left
-* @property {number} left - The x coordinate of the left of the Rectangle.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "left", {
-
- get: function () {
- return this.x;
},
- set: function (value) {
- if (value >= this.right) {
+ /**
+ * The x coordinate of the left of the Rectangle. Changing the left property of a Rectangle object has no effect on the y and height properties. However it does affect the width property, whereas changing the x value does not affect the width property.
+ * @name Phaser.Rectangle#left
+ * @property {number} left - The x coordinate of the left of the Rectangle.
+ */
+ get left() {
+
+ return this.x;
+
+ },
+
+ set left(value) {
+
+ if (value >= this.right)
+ {
this.width = 0;
- } else {
+ }
+ else
+ {
this.width = this.right - value;
}
+
this.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.
-* @name Phaser.Rectangle#right
-* @property {number} right - The sum of the x and width properties.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "right", {
-
- get: function () {
- return this.x + this.width;
},
- set: function (value) {
- if (value <= this.x) {
+ /**
+ * 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.
+ * @name Phaser.Rectangle#right
+ * @property {number} right - The sum of the x and width properties.
+ */
+ get right() {
+
+ return this.x + this.width;
+
+ },
+
+ set right(value) {
+
+ if (value <= this.x)
+ {
this.width = 0;
- } else {
+ }
+ else
+ {
this.width = this.x + value;
}
- }
-});
+ },
+
+ /**
+ * The volume of the Rectangle derived from width * height.
+ * @name Phaser.Rectangle#volume
+ * @property {number} volume - The volume of the Rectangle derived from width * height.
+ * @readonly
+ */
+ get volume() {
-/**
-* The volume of the Rectangle derived from width * height.
-* @name Phaser.Rectangle#volume
-* @property {number} volume - The volume of the Rectangle derived from width * height.
-* @readonly
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "volume", {
-
- get: function () {
return this.width * this.height;
- }
-});
+ },
+
+ /**
+ * The perimeter size of the Rectangle. This is the sum of all 4 sides.
+ * @name Phaser.Rectangle#perimeter
+ * @property {number} perimeter - The perimeter size of the Rectangle. This is the sum of all 4 sides.
+ * @readonly
+ */
+ get perimeter() {
-/**
-* The perimeter size of the Rectangle. This is the sum of all 4 sides.
-* @name Phaser.Rectangle#perimeter
-* @property {number} perimeter - The perimeter size of the Rectangle. This is the sum of all 4 sides.
-* @readonly
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "perimeter", {
-
- get: function () {
return (this.width * 2) + (this.height * 2);
- }
-});
+ },
+
+ /**
+ * The x coordinate of the center of the Rectangle.
+ * @name Phaser.Rectangle#centerX
+ * @property {number} centerX - The x coordinate of the center of the Rectangle.
+ */
+ get centerX() {
-/**
-* The x coordinate of the center of the Rectangle.
-* @name Phaser.Rectangle#centerX
-* @property {number} centerX - The x coordinate of the center of the Rectangle.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "centerX", {
-
- get: function () {
return this.x + this.halfWidth;
+
},
- set: function (value) {
+ set centerX(value) {
+
this.x = value - this.halfWidth;
- }
-});
+ },
+
+ /**
+ * The y coordinate of the center of the Rectangle.
+ * @name Phaser.Rectangle#centerY
+ * @property {number} centerY - The y coordinate of the center of the Rectangle.
+ */
+ get centerY() {
-/**
-* The y coordinate of the center of the Rectangle.
-* @name Phaser.Rectangle#centerY
-* @property {number} centerY - The y coordinate of the center of the Rectangle.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "centerY", {
-
- get: function () {
return this.y + this.halfHeight;
+
},
- set: function (value) {
+ set centerY(value) {
+
this.y = value - this.halfHeight;
- }
-});
-
-/**
-* The y coordinate of the top of the Rectangle. Changing the top property of a Rectangle object has no effect on the x and width properties.
-* However it does affect the height property, whereas changing the y value does not affect the height property.
-* @name Phaser.Rectangle#top
-* @property {number} top - The y coordinate of the top of the Rectangle.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "top", {
-
- get: function () {
- return this.y;
},
- set: function (value) {
- if (value >= this.bottom) {
+ /**
+ * The y coordinate of the top of the Rectangle. Changing the top property of a Rectangle object has no effect on the x and width properties.
+ * However it does affect the height property, whereas changing the y value does not affect the height property.
+ * @name Phaser.Rectangle#top
+ * @property {number} top - The y coordinate of the top of the Rectangle.
+ */
+ get top() {
+
+ return this.y;
+
+ },
+
+ set top(value) {
+
+ if (value >= this.bottom)
+ {
this.height = 0;
this.y = value;
- } else {
+ }
+ else
+ {
this.height = (this.bottom - value);
}
- }
-});
+ },
-/**
-* The location of the Rectangles top left corner as a Point object.
-* @name Phaser.Rectangle#topLeft
-* @property {Phaser.Point} topLeft - The location of the Rectangles top left corner as a Point object.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "topLeft", {
+ /**
+ * The location of the Rectangles top left corner as a Point object.
+ * @name Phaser.Rectangle#topLeft
+ * @property {Phaser.Point} topLeft - The location of the Rectangles top left corner as a Point object.
+ */
+ get topLeft() {
- get: function () {
return new Phaser.Point(this.x, this.y);
+
},
- set: function (value) {
+ set topLeft(value) {
+
this.x = value.x;
this.y = value.y;
- }
-});
-
-/**
-* Determines whether or not this Rectangle object is empty. A Rectangle object is empty if its width or height is less than or equal to 0.
-* If set to true then all of the Rectangle properties are set to 0.
-* @name Phaser.Rectangle#empty
-* @property {boolean} empty - Gets or sets the Rectangles empty state.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "empty", {
-
- get: function () {
- return (!this.width || !this.height);
},
- set: function (value) {
+ /**
+ * Determines whether or not this Rectangle object is empty. A Rectangle object is empty if its width or height is less than or equal to 0.
+ * If set to true then all of the Rectangle properties are set to 0.
+ * @name Phaser.Rectangle#empty
+ * @property {boolean} empty - Gets or sets the Rectangles empty state.
+ */
+ get empty() {
+
+ return (!this.width || !this.height);
+
+ },
+
+ set empty(value) {
if (value === true)
{
@@ -526,7 +525,9 @@ Object.defineProperty(Phaser.Rectangle.prototype, "empty", {
}
-});
+};
+
+Phaser.Rectangle.prototype.constructor = Phaser.Rectangle;
/**
* Increases the size of the Rectangle object by the specified amounts. The center point of the Rectangle object stays the same, and its size increases to the left and right by the dx value, and to the top and the bottom by the dy value.
@@ -772,4 +773,4 @@ Phaser.Rectangle.union = function (a, b, output) {
// Because PIXI uses its own Rectangle, we'll replace it with ours to avoid duplicating code or confusion.
PIXI.Rectangle = Phaser.Rectangle;
-PIXI.EmptyRectangle = new Phaser.Rectangle(0,0,0,0);
+PIXI.EmptyRectangle = new Phaser.Rectangle(0, 0, 0, 0);
From 6958ac73d3c08b58d371f7e136c8e1c0e7a98f93 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Fri, 7 Feb 2014 04:12:04 +0000
Subject: [PATCH 15/26] Added the SAT class to the TypeScript defs file. Also
this fixes #369.
---
build/phaser.d.ts | 73 +++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 73 insertions(+)
diff --git a/build/phaser.d.ts b/build/phaser.d.ts
index c8786c83..ff10a516 100644
--- a/build/phaser.d.ts
+++ b/build/phaser.d.ts
@@ -1,3 +1,76 @@
+declare class SAT {
+
+ flattenPointsOn(points: Array, normal: SAT.Vector, result: Array): Array;
+ isSeparatingAxis(aPos: SAT.Vector, bPos: SAT.Vector, aPoints: Array, bPoints: Array, axis: SAT.Vector, response: SAT.Response): boolean;
+ vornoiRegion(line: SAT.Vector, point: SAT.Vector): number;
+ testCircleCircle(a: SAT.Circle, b: SAT.Circle, response: SAT.Response): boolean;
+ testPolygonCircle(a: SAT.Polygon, b: SAT.Circle, response: SAT.Response): boolean;
+ testCirclePolygon(a: SAT.Circle, b: SAT.Polygon, response: SAT.Response): boolean;
+ testPolygonPolygon(a: SAT.Polygon, b: SAT.Polygon, response: SAT.Response): boolean;
+
+}
+
+declare module SAT {
+
+ class Vector {
+ constructor(x: number, y: number);
+ x: number;
+ y: number;
+ copy(other: SAT.Vector): SAT.Vector;
+ perp(): SAT.Vector;
+ rotate(angle: number): SAT.Vector;
+ rotatePrecalc(sin: number, cos: number): SAT.Vector;
+ reverse(): SAT.Vector;
+ normalize(): SAT.Vector;
+ add(other: SAT.Vector): SAT.Vector;
+ sub(other: SAT.Vector): SAT.Vector;
+ scale(x: number, y: number): SAT.Vector;
+ project(other: SAT.Vector): SAT.Vector;
+ projectN(other: SAT.Vector): SAT.Vector;
+ reflect(axis: SAT.Vector): SAT.Vector;
+ reflectN(axis: SAT.Vector): SAT.Vector;
+ dot(other: SAT.Vector): SAT.Vector;
+ len2(): SAT.Vector;
+ len(): SAT.Vector;
+ }
+
+ class Circle {
+ constructor(pos: SAT.Vector, radius: number);
+ pos: SAT.Vector;
+ r: number;
+ }
+
+ class Polygon {
+ constructor(pos: SAT.Vector, points: Array);
+ pos: SAT.Vector;
+ points: Array;
+ recalc(): SAT.Polygon;
+ rotate(angle: number): SAT.Polygon;
+ scale(x: number, y: number): SAT.Polygon;
+ translate(x: number, y: number): SAT.Polygon;
+ }
+
+ class Box {
+ constructor(pos: SAT.Vector, w: number, h: number);
+ pos: SAT.Vector;
+ w: number;
+ h: number;
+ toPolygon(): SAT.Polygon;
+ }
+
+ class Response {
+ constructor();
+ a: any;
+ b: any;
+ overlapN: SAT.Vector;
+ overlapV: SAT.Vector;
+ clear(): SAT.Response;
+ aInB: boolean;
+ bInA: boolean;
+ overlap: number;
+ }
+}
+
declare class Phaser {
static VERSION: string;
static DEV_VERSION: string;
From 773b4d5ed1ad397293f74dc8f7f312c0901b4033 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Fri, 7 Feb 2014 04:12:23 +0000
Subject: [PATCH 16/26] More animation tests.
---
build/config.php | 3 +-
examples/wip/image3.js | 24 ++
src/animation/FrameData.js | 6 +-
src/gameobjects/Image.js | 55 ++---
src/gameobjects/old_RenderTexture.js | 327 +++++++++++++++++++++++++++
5 files changed, 379 insertions(+), 36 deletions(-)
create mode 100644 examples/wip/image3.js
create mode 100644 src/gameobjects/old_RenderTexture.js
diff --git a/build/config.php b/build/config.php
index 7b047258..a8f45ea7 100644
--- a/build/config.php
+++ b/build/config.php
@@ -99,6 +99,8 @@
+
+
@@ -143,7 +145,6 @@
-
diff --git a/examples/wip/image3.js b/examples/wip/image3.js
new file mode 100644
index 00000000..c2332a6d
--- /dev/null
+++ b/examples/wip/image3.js
@@ -0,0 +1,24 @@
+
+var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create });
+
+function preload() {
+
+ game.load.spritesheet('mummy', 'assets/sprites/metalslug_mummy37x45.png', 37, 45, 18);
+ game.load.atlas('seacreatures', 'assets/sprites/seacreatures_json.png', 'assets/sprites/seacreatures_json.json');
+
+}
+
+function create() {
+
+ // Testing both sprite sheets and texture atlases with a Phaser.Image
+
+ for (var i = 0; i < 18; i++)
+ {
+ game.add.image(4 + 44 * i, 200, 'mummy', i);
+ }
+
+ game.add.image(200, 300, 'seacreatures', 'blueJellyfish0000');
+ game.add.image(300, 300, 'seacreatures', 'crab10000');
+ game.add.image(470, 300, 'seacreatures', 'purpleFish0000');
+
+}
diff --git a/src/animation/FrameData.js b/src/animation/FrameData.js
index ab790fa0..1051fced 100644
--- a/src/animation/FrameData.js
+++ b/src/animation/FrameData.js
@@ -60,12 +60,12 @@ Phaser.FrameData.prototype = {
*/
getFrame: function (index) {
- if (this._frames.length > index)
+ if (index > this._frames.length)
{
- return this._frames[index];
+ index = 0;
}
- return null;
+ return this._frames[index];
},
diff --git a/src/gameobjects/Image.js b/src/gameobjects/Image.js
index 690670d6..3dcf7e8b 100644
--- a/src/gameobjects/Image.js
+++ b/src/gameobjects/Image.js
@@ -179,6 +179,7 @@ Phaser.Image.prototype.inCamera = function() {
Phaser.Image.prototype.loadTexture = function (key, frame) {
this.key = key;
+ frame = frame || 0;
if (key instanceof Phaser.RenderTexture)
{
@@ -210,28 +211,23 @@ Phaser.Image.prototype.loadTexture = function (key, frame) {
if (this.game.cache.isSpriteSheet(key))
{
- // this.animations.loadFrameData(this.game.cache.getFrameData(key));
+ var frameData = this.game.cache.getFrameData(key);
- // if (typeof frame !== 'undefined')
- // {
- // if (typeof frame === 'string')
- // {
- // this.frameName = frame;
- // }
- // else
- // {
- // this.frame = frame;
- // }
- // }
+ // console.log(frameData);
+ // console.log(frameData.getFrame(0));
+ // console.log(frameData.getFrame(1));
+
+ if (typeof frame === 'string')
+ {
+ this.setTexture(PIXI.TextureCache[frameData.getFrameByName(frame).uuid]);
+ }
+ else
+ {
+ this.setTexture(PIXI.TextureCache[frameData.getFrame(frame).uuid]);
+ }
}
else
{
- console.log('loadTexture 1', this.game.cache.getFrame(key));
-
- this.game.cache.getFrame(key).getRect(this.currentFrame);
-
- console.log('loadTexture 1', this.currentFrame);
-
this.setTexture(PIXI.TextureCache[key]);
}
}
@@ -421,24 +417,19 @@ Phaser.Image.prototype.bringToTop = function(child) {
/**
* 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. Working in radians is also computationally faster.
+* If you wish to work in radians instead of degrees use the property Sprite.rotation instead. Working in radians is also faster on mobile devices where Object.defineProperty is expensive to call.
*
-* @method Phaser.Image#angle
-* @memberof Phaser.Image
-* @param {number} [value] - If given it will set the Images angle to this value. Value should be given in degrees.
-* @return {number} The angle of this Image in degrees.
+* @name Phaser.Image#angle
+* @property {number} angle - The angle of this Image in degrees.
*/
-Phaser.Image.prototype.angle = function(value) {
+Object.defineProperty(Phaser.Image.prototype, "angle", {
- if (typeof value === 'undefined')
- {
+ get: function() {
return Phaser.Math.wrapAngle(Phaser.Math.radToDeg(this.rotation));
- }
- else
- {
+ },
+
+ set: function(value) {
this.rotation = Phaser.Math.degToRad(Phaser.Math.wrapAngle(value));
-
- return Phaser.Math.radToDeg(this.rotation);
}
-};
+});
diff --git a/src/gameobjects/old_RenderTexture.js b/src/gameobjects/old_RenderTexture.js
new file mode 100644
index 00000000..b6eab596
--- /dev/null
+++ b/src/gameobjects/old_RenderTexture.js
@@ -0,0 +1,327 @@
+/**
+* @author Richard Davey
+* @copyright 2014 Photon Storm Ltd.
+* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
+*/
+
+/**
+* A RenderTexture is a special texture that allows any displayObject to be rendered to it.
+* @class Phaser.RenderTexture
+* @constructor
+* @param {Phaser.Game} game - Current game instance.
+* @param {string} key - Asset key for the render texture.
+* @param {number} width - the width of the render texture.
+* @param {number} height - the height of the render texture.
+*/
+Phaser.RenderTexture = function (game, key, width, height) {
+
+ /**
+ * @property {Phaser.Game} game - A reference to the currently running game.
+ */
+ this.game = game;
+
+ /**
+ * @property {string} name - the name of the object.
+ */
+ this.name = key;
+
+ PIXI.EventTarget.call(this);
+
+ /**
+ * @property {number} width - the width.
+ */
+ this.width = width || 100;
+
+ /**
+ * @property {number} height - the height.
+ */
+ this.height = height || 100;
+
+ /**
+ * @property {PIXI.mat3} indetityMatrix - Matrix object.
+ */
+ this.indetityMatrix = PIXI.mat3.create();
+
+ /**
+ * @property {PIXI.Rectangle} frame - The frame for this texture.
+ */
+ this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
+
+ /**
+ * @property {number} type - Base Phaser object type.
+ */
+ this.type = Phaser.RENDERTEXTURE;
+
+ this._tempPoint = { x: 0, y: 0 };
+
+ if (PIXI.gl)
+ {
+ this.initWebGL();
+ }
+ else
+ {
+ this.initCanvas();
+ }
+
+};
+
+Phaser.RenderTexture.prototype = Object.create(PIXI.Texture.prototype);
+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 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, renderHidden) {
+
+ if (typeof position === 'undefined') { position = false; }
+ if (typeof clear === 'undefined') { clear = false; }
+ if (typeof renderHidden === 'undefined') { renderHidden = false; }
+
+ if (PIXI.gl)
+ {
+ this.renderWebGL(displayObject, position, clear, renderHidden);
+ }
+ else
+ {
+ this.renderCanvas(displayObject, position, 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.
+*
+* @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, renderHidden) {
+
+ this._tempPoint.x = x;
+ this._tempPoint.y = y;
+
+ this.render(displayObject, this._tempPoint, clear, renderHidden);
+
+}
+
+/**
+* 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();
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
+
+ this.glFramebuffer.width = this.width;
+ this.glFramebuffer.height = this.height;
+
+ this.baseTexture = new PIXI.BaseTexture();
+
+ 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.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);
+
+ this.baseTexture.isRender = true;
+
+ 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);
+
+ // set the correct render function..
+ // this.render = this.renderWebGL;
+}
+
+/**
+* Resizes the RenderTexture.
+*
+* @method Phaser.RenderTexture#resize
+* @memberof Phaser.RenderTexture
+*/
+Phaser.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);
+ }
+}
+
+/**
+* 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);
+
+ this.baseTexture = new PIXI.BaseTexture(this.renderer.view);
+ this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
+
+ // this.render = this.renderCanvas;
+}
+
+/**
+* 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;
+
+ // enable the alpha color mask..
+ gl.colorMask(true, true, true, true);
+
+ gl.viewport(0, 0, this.width, this.height);
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, this.glFramebuffer );
+
+ if (clear)
+ {
+ gl.clearColor(0,0,0, 0);
+ gl.clear(gl.COLOR_BUFFER_BIT);
+ }
+
+ // 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;
+
+ 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 < j; i++)
+ {
+ children[i].updateTransform();
+ }
+
+ var renderGroup = displayObject.__renderGroup;
+
+ if (renderGroup)
+ {
+ if (displayObject == renderGroup.root)
+ {
+ renderGroup.render(this.projection, this.glFramebuffer);
+ }
+ else
+ {
+ renderGroup.renderSpecific(displayObject, this.projection, this.glFramebuffer);
+ }
+ }
+ else
+ {
+ if (!this.renderGroup)
+ {
+ this.renderGroup = new PIXI.WebGLRenderGroup(gl);
+ }
+
+ this.renderGroup.setRenderable(displayObject);
+ this.renderGroup.render(this.projection, this.glFramebuffer);
+ }
+
+ displayObject.worldTransform = originalWorldTransform;
+}
+
+/**
+ * This function will draw the display object to the texture.
+ *
+* @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;
+
+ displayObject.worldTransform = PIXI.mat3.create();
+
+ if (position)
+ {
+ displayObject.worldTransform[2] = position.x;
+ displayObject.worldTransform[5] = position.y;
+ }
+
+ for (var i = 0, j = children.length; i < j; i++)
+ {
+ children[i].updateTransform();
+ }
+
+ if (clear)
+ {
+ this.renderer.context.clearRect(0, 0, this.width, this.height);
+ }
+
+ this.renderer.renderDisplayObject(displayObject, renderHidden);
+
+ this.renderer.context.setTransform(1, 0, 0, 1, 0, 0);
+
+}
From d583b364bd650aa9950ccf0c01e1dba12cc39913 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Fri, 7 Feb 2014 06:25:28 +0000
Subject: [PATCH 17/26] Game.add.renderTexture now has the addToCache
parameter. If set the texture will be stored in Game.Cache and can be
retrieved with Cache.getTexture(key). Game.add.bitmapData now has the
addToCache parameter. If set the texture will be stored in Game.Cache and can
be retrieved with Cache.getBitmapData(key).
---
README.md | 2 +
build/config.php | 4 +-
examples/wip/rendertexture.js | 18 ++--
src/gameobjects/BitmapData.js | 15 +--
src/gameobjects/GameObjectFactory.js | 41 +++++---
src/gameobjects/Image.js | 142 ++++++++++++++++++++-------
src/gameobjects/RenderTexture.js | 37 ++-----
7 files changed, 158 insertions(+), 101 deletions(-)
diff --git a/README.md b/README.md
index 45981fa4..e115e584 100644
--- a/README.md
+++ b/README.md
@@ -83,6 +83,8 @@ Updates:
* Debug.renderRectangle has a new parameter: filled. If true it renders as with fillRect, if false strokeRect.
* Phaser.AnimationParser now sets the trimmed data directly for Pixi Texture frames. Tested across JSON Hash, JSON Data, Sprite Sheet and XML.
+* Game.add.renderTexture now has the addToCache parameter. If set the texture will be stored in Game.Cache and can be retrieved with Cache.getTexture(key).
+* Game.add.bitmapData now has the addToCache parameter. If set the texture will be stored in Game.Cache and can be retrieved with Cache.getBitmapData(key).
Bug Fixes:
diff --git a/build/config.php b/build/config.php
index a8f45ea7..5e21cefd 100644
--- a/build/config.php
+++ b/build/config.php
@@ -99,8 +99,6 @@
-
-
@@ -144,10 +142,10 @@
+
-
diff --git a/examples/wip/rendertexture.js b/examples/wip/rendertexture.js
index bacc9698..7324c90a 100644
--- a/examples/wip/rendertexture.js
+++ b/examples/wip/rendertexture.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.WEBGL, 'phaser-example', { preload: preload, create: create, update: update, render: render });
function preload() {
@@ -13,17 +13,14 @@ var image;
function create() {
- // Here we'll create a renderTexture the same size as our game
texture = game.add.renderTexture('mousetrail', 800, 600);
- // This is the sprite that will be drawn to the texture, we set it to visible false as we only need its texture data
- mushroom = game.add.sprite(0, 0, 'mushroom');
- // mushroom.visible = false;
- // mushroom.anchor.setTo(0.5, 0.5);
+ // We create a sprite (rather than using the factory) so it doesn't get added to the display, as we only need its texture data.
+ mushroom = new Phaser.Sprite(game, 0, 0, 'mushroom');
+ mushroom.anchor.setTo(0.5, 0.5);
// This is the sprite that is drawn to the display. We've given it the renderTexture as its texture.
- // game.add.image(0, 0, texture);
-
+ image = game.add.image(0, 0, texture);
game.input.onDown.add(tint, this);
@@ -41,14 +38,11 @@ function update() {
{
// 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);
+ texture.render(mushroom, game.input.activePointer.position, false);
}
}
function render() {
- game.debug.renderText(game.input.x, 32, 32);
-
}
diff --git a/src/gameobjects/BitmapData.js b/src/gameobjects/BitmapData.js
index ec0c678f..3c783ab1 100644
--- a/src/gameobjects/BitmapData.js
+++ b/src/gameobjects/BitmapData.js
@@ -17,13 +17,14 @@
*
* @constructor
* @param {Phaser.Game} game - A reference to the currently running game.
-* @param {number} [width=256] - The width of the BitmapData in pixels.
-* @param {number} [height=256] - The height of the BitmapData in pixels.
+* @param {string} key - Internal Phaser reference key for the render texture.
+* @param {number} [width=100] - The width of the BitmapData in pixels.
+* @param {number} [height=100] - The height of the BitmapData in pixels.
*/
-Phaser.BitmapData = function (game, width, height) {
+Phaser.BitmapData = function (game, key, width, height) {
- if (typeof width === 'undefined') { width = 256; }
- if (typeof height === 'undefined') { height = 256; }
+ if (typeof width === 'undefined') { width = 100; }
+ if (typeof height === 'undefined') { height = 100; }
/**
* @property {Phaser.Game} game - A reference to the currently running game.
@@ -31,9 +32,9 @@ Phaser.BitmapData = function (game, width, height) {
this.game = game;
/**
- * @property {string} name - The name of the BitmapData.
+ * @property {string} key - The key of the BitmapData in the Cache, if stored there.
*/
- this.name = '';
+ this.key = key;
/**
* @property {number} width - The width of the BitmapData in pixels.
diff --git a/src/gameobjects/GameObjectFactory.js b/src/gameobjects/GameObjectFactory.js
index 955d7cd0..0077ee4e 100644
--- a/src/gameobjects/GameObjectFactory.js
+++ b/src/gameobjects/GameObjectFactory.js
@@ -288,32 +288,51 @@ Phaser.GameObjectFactory.prototype = {
* A dynamic initially blank canvas to which images can be drawn.
*
* @method Phaser.GameObjectFactory#renderTexture
- * @param {string} key - Asset key for the render texture.
- * @param {number} width - the width of the render texture.
- * @param {number} height - the height of the render texture.
- * @return {Phaser.RenderTexture} The newly created renderTexture object.
+ * @param {number} [width=100] - the width of the RenderTexture.
+ * @param {number} [height=100] - the height of the RenderTexture.
+ * @param {string} [key=''] - Asset key for the RenderTexture when stored in the Cache (see addToCache parameter).
+ * @param {boolean} [addToCache=false] - Should this RenderTexture be added to the Game.Cache? If so you can retrieve it with Cache.getTexture(key)
+ * @return {Phaser.RenderTexture} The newly created RenderTexture object.
*/
- renderTexture: function (key, width, height) {
+ renderTexture: function (width, height, key, addToCache) {
+
+ if (typeof addToCache === 'undefined') { addToCache = false; }
+ if (typeof key === 'undefined' || key === '') { key = this.game.rnd.uuid(); }
var texture = new Phaser.RenderTexture(this.game, key, width, height);
- this.game.cache.addRenderTexture(key, texture);
+ if (addToCache)
+ {
+ this.game.cache.addRenderTexture(key, texture);
+ }
return texture;
},
/**
- * Experimental: A BitmapData object which can be manipulated and drawn to like a traditional Canvas object and used to texture Sprites.
+ * 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.
- * @param {number} [height=256] - The height of the BitmapData in pixels.
+ * @param {number} [width=100] - The width of the BitmapData in pixels.
+ * @param {number} [height=100] - The height of the BitmapData in pixels.
+ * @param {string} [key=''] - Asset key for the BitmapData when stored in the Cache (see addToCache parameter).
+ * @param {boolean} [addToCache=false] - Should this BitmapData be added to the Game.Cache? If so you can retrieve it with Cache.getBitmapData(key)
* @return {Phaser.BitmapData} The newly created BitmapData object.
*/
- bitmapData: function (width, height) {
+ bitmapData: function (width, height, addToCache) {
- return new Phaser.BitmapData(this.game, width, height);
+ if (typeof addToCache === 'undefined') { addToCache = false; }
+ if (typeof key === 'undefined' || key === '') { key = this.game.rnd.uuid(); }
+
+ var texture = new Phaser.BitmapData(this.game, key, width, height);
+
+ if (addToCache)
+ {
+ this.game.cache.addBitmapData(key, texture);
+ }
+
+ return texture;
},
diff --git a/src/gameobjects/Image.js b/src/gameobjects/Image.js
index 3dcf7e8b..68b8d736 100644
--- a/src/gameobjects/Image.js
+++ b/src/gameobjects/Image.js
@@ -64,8 +64,7 @@ Phaser.Image = function (game, x, y, key, frame) {
this.loadTexture(key, frame);
- this.position.x = x;
- this.position.y = y;
+ this.position.set(x, y);
/**
* @property {Phaser.Point} world - The world coordinates of this Sprite. This differs from the x/y coordinates which are relative to the Sprites container.
@@ -90,6 +89,12 @@ Phaser.Image = function (game, x, y, key, frame) {
*/
this.fixedToCamera = false;
+ /**
+ * @property {array} _cache - A small cache for previous step values.
+ * @private
+ */
+ this._cache = [0, 0, 0];
+
};
Phaser.Image.prototype = Object.create(PIXI.Sprite.prototype);
@@ -103,6 +108,10 @@ Phaser.Image.prototype.constructor = Phaser.Image;
*/
Phaser.Image.prototype.preUpdate = function() {
+ this._cache[0] = this.world.x;
+ this._cache[1] = this.world.y;
+ this._cache[2] = this.rotation;
+
if (!this.exists || !this.parent.exists)
{
return false;
@@ -141,32 +150,6 @@ Phaser.Image.prototype.postUpdate = function() {
};
-/**
-* Checks if the Image bounds are within the game world, otherwise false if fully outside of it.
-*
-* @method Phaser.Image#inWorld
-* @memberof Phaser.Image
-* @return {boolean} True if the Image bounds is within the game world, even if only partially. Otherwise false if fully outside of it.
-*/
-Phaser.Image.prototype.inWorld = function() {
-
- return this.game.world.bounds.intersects(this.getBounds());
-
-};
-
-/**
-* Checks if the Image bounds are within the game camera, otherwise false if fully outside of it.
-*
-* @method Phaser.Image#inCamera
-* @memberof Phaser.Image
-* @return {boolean} True if the Image bounds is within the game camera, even if only partially. Otherwise false if fully outside of it.
-*/
-Phaser.Image.prototype.inCamera = function() {
-
- return this.game.world.camera.screenView.intersects(this.getBounds());
-
-};
-
/**
* Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
* This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
@@ -183,8 +166,8 @@ Phaser.Image.prototype.loadTexture = function (key, frame) {
if (key instanceof Phaser.RenderTexture)
{
- // this.game.cache.getTextureFrame(key.name).clone(this.currentFrame);
- // WOKWOKSK
+ this.key = key.name;
+ this.setTexture(key);
}
else if (key instanceof Phaser.BitmapData)
{
@@ -192,9 +175,7 @@ Phaser.Image.prototype.loadTexture = function (key, frame) {
}
else if (key instanceof PIXI.Texture)
{
- // this.currentFrame = frame;
- frame.clone(this.currentFrame);
- console.log('loadTexture 2');
+ this.setTexture(key);
}
else
{
@@ -202,21 +183,19 @@ Phaser.Image.prototype.loadTexture = function (key, frame) {
{
key = '__default';
this.key = key;
+ this.setTexture(PIXI.TextureCache[key]);
}
else if (typeof key === 'string' && this.game.cache.checkImageKey(key) === false)
{
key = '__missing';
this.key = key;
+ this.setTexture(PIXI.TextureCache[key]);
}
if (this.game.cache.isSpriteSheet(key))
{
var frameData = this.game.cache.getFrameData(key);
- // console.log(frameData);
- // console.log(frameData.getFrame(0));
- // console.log(frameData.getFrame(1));
-
if (typeof frame === 'string')
{
this.setTexture(PIXI.TextureCache[frameData.getFrameByName(frame).uuid]);
@@ -425,11 +404,100 @@ Phaser.Image.prototype.bringToTop = function(child) {
Object.defineProperty(Phaser.Image.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));
+
+ }
+
+});
+
+/**
+* Returns the delta x value. The difference between world.x now and in the previous step.
+*
+* @name Phaser.Image#deltaX
+* @property {number} deltaX - The delta value. Positive if the motion was to the right, negative if to the left.
+* @readonly
+*/
+Object.defineProperty(Phaser.Image.prototype, "deltaX", {
+
+ get: function() {
+
+ return this.world.x - this._cache[0];
+
+ }
+
+});
+
+/**
+* Returns the delta y value. The difference between world.y now and in the previous step.
+*
+* @name Phaser.Image#deltaY
+* @property {number} deltaY - The delta value. Positive if the motion was downwards, negative if upwards.
+* @readonly
+*/
+Object.defineProperty(Phaser.Image.prototype, "deltaY", {
+
+ get: function() {
+
+ return this.world.y - this._cache[1];
+
+ }
+
+});
+
+/**
+* Returns the delta z value. The difference between rotation now and in the previous step.
+*
+* @name Phaser.Image#deltaZ
+* @property {number} deltaZ - The delta value.
+* @readonly
+*/
+Object.defineProperty(Phaser.Image.prototype, "deltaZ", {
+
+ get: function() {
+
+ return this.rotation - this._cache[2];
+
+ }
+
+});
+
+/**
+* Checks if the Image bounds are within the game world, otherwise false if fully outside of it.
+*
+* @name Phaser.Image#inWorld
+* @property {boolean} inWorld - True if the Image bounds is within the game world, even if only partially. Otherwise false if fully outside of it.
+* @readonly
+*/
+Object.defineProperty(Phaser.Image.prototype, "inWorld", {
+
+ get: function() {
+
+ return this.game.world.bounds.intersects(this.getBounds());
+
+ }
+
+});
+
+/**
+* Checks if the Image bounds are within the game camera, otherwise false if fully outside of it.
+*
+* @name Phaser.Image#inCamera
+* @property {boolean} inCamera - True if the Image bounds is within the game camera, even if only partially. Otherwise false if fully outside of it.
+* @readonly
+*/
+Object.defineProperty(Phaser.Image.prototype, "inCamera", {
+
+ get: function() {
+
+ return this.game.world.camera.screenView.intersects(this.getBounds());
+
}
});
diff --git a/src/gameobjects/RenderTexture.js b/src/gameobjects/RenderTexture.js
index 42c608b2..d05cefba 100644
--- a/src/gameobjects/RenderTexture.js
+++ b/src/gameobjects/RenderTexture.js
@@ -9,9 +9,9 @@
* @class Phaser.RenderTexture
* @constructor
* @param {Phaser.Game} game - Current game instance.
-* @param {string} key - Asset key for the render texture.
-* @param {number} width - the width of the render texture.
-* @param {number} height - the height of the render texture.
+* @param {string} key - Internal Phaser reference key for the render texture.
+* @param {number} [width=100] - The width of the render texture.
+* @param {number} [height=100] - The height of the render texture.
*/
Phaser.RenderTexture = function (game, key, width, height) {
@@ -21,43 +21,18 @@ Phaser.RenderTexture = function (game, key, width, height) {
this.game = game;
/**
- * @property {string} name - the name of the object.
+ * @property {string} key - The key of the RenderTexture in the Cache, if stored there.
*/
- this.name = key;
-
- /**
- * @property {number} width - the width.
- */
- this.width = width || 100;
-
- /**
- * @property {number} height - the height.
- */
- this.height = height || 100;
-
- /**
- * @property {PIXI.Rectangle} frame - The frame for this texture.
- */
- this.frame = new PIXI.Rectangle(0, 0, this.width, this.height);
+ this.key = key;
/**
* @property {number} type - Base Phaser object type.
*/
this.type = Phaser.RENDERTEXTURE;
- // this._tempPoint = { x: 0, y: 0 };
-
- // if (PIXI.gl)
- // {
- // this.initWebGL();
- // }
- // else
- // {
- // this.initCanvas();
- // }
+ PIXI.RenderTexture.call(this, width, height, renderer);
};
Phaser.RenderTexture.prototype = Object.create(PIXI.RenderTexture.prototype);
Phaser.RenderTexture.prototype.constructor = Phaser.RenderTexture;
-
From 9b9baa83a95fb6a3bf07810c9413b67d49716b7e Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Fri, 7 Feb 2014 06:52:49 +0000
Subject: [PATCH 18/26] Added Image.frame and Image.frameName support in.
---
examples/wip/frame.js | 55 ++++++++++++++++++++
src/gameobjects/Image.js | 105 ++++++++++++++++++++++++++++++++-------
2 files changed, 142 insertions(+), 18 deletions(-)
create mode 100644 examples/wip/frame.js
diff --git a/examples/wip/frame.js b/examples/wip/frame.js
new file mode 100644
index 00000000..4637dbcd
--- /dev/null
+++ b/examples/wip/frame.js
@@ -0,0 +1,55 @@
+
+var game = new Phaser.Game(800, 600, Phaser.AUTO, 'phaser-example', { preload: preload, create: create, update: update });
+
+function preload() {
+
+ game.load.spritesheet('mummy', 'assets/sprites/metalslug_mummy37x45.png', 37, 45, 18);
+ game.load.atlas('seacreatures', 'assets/sprites/seacreatures_json.png', 'assets/sprites/seacreatures_json.json');
+
+}
+
+var mummy;
+var jelly;
+
+function create() {
+
+ // Testing both sprite sheets and texture atlases with a Phaser.Image
+
+ mummy = game.add.image(200, 200, 'mummy');
+
+ jelly = game.add.image(200, 300, 'seacreatures', 'blueJellyfish0000');
+
+ game.input.onDown.add(changeFrame, this);
+
+}
+
+function changeFrame() {
+
+ if (jelly.frameName === 'blueJellyfish0000')
+ {
+ jelly.frameName = 'crab10000';
+ }
+ else if (jelly.frameName === 'crab10000')
+ {
+ jelly.frameName = 'purpleFish0000';
+ }
+ else
+ {
+ jelly.frameName = 'blueJellyfish0000';
+ }
+
+}
+
+function update() {
+
+ // You could animate an Image like this! But it makes more sense to use a Sprite
+ if (mummy.frame < 17)
+ {
+ mummy.frame++;
+ }
+ else
+ {
+ mummy.frame = 0;
+ }
+
+}
\ No newline at end of file
diff --git a/src/gameobjects/Image.js b/src/gameobjects/Image.js
index 68b8d736..0db20710 100644
--- a/src/gameobjects/Image.js
+++ b/src/gameobjects/Image.js
@@ -7,16 +7,15 @@
/**
* @class Phaser.Image
*
-* @classdesc Create a new `Image` object.
-*
-* At its most basic a Sprite consists of a set of coordinates and a texture that is rendered to the canvas.
+* @classdesc Create a new `Image` object. An Image is a light-weight object you can use to display anything that doesn't need physics, animation or input events.
+* It can still rotate, scale and crop. This makes it perfect for logos, backgrounds and other non-Sprite graphics.
*
* @constructor
* @param {Phaser.Game} game - A reference to the currently running game.
-* @param {number} x - The x coordinate (in world space) to position the Sprite at.
-* @param {number} y - The y coordinate (in world space) to position the Sprite at.
-* @param {string|Phaser.RenderTexture|Phaser.BitmapData|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 {number} x - The x coordinate of the Imaget. The coordinate is relative to any parent container this Image may be in.
+* @param {number} y - The y coordinate of the Image. The coordinate is relative to any parent container this Image may be in.
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|PIXI.Texture} key - The texture used by the Image during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture, BitmapData or PIXI.Texture.
+* @param {string|number} frame - If this Image 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.Image = function (game, x, y, key, frame) {
@@ -58,7 +57,8 @@ Phaser.Image = function (game, x, y, key, frame) {
*/
this.key = key;
- this.currentFrame = new Phaser.Rectangle();
+ this._frame = 0;
+ this._frameName = '';
PIXI.Sprite.call(this, PIXI.TextureCache['__default']);
@@ -161,52 +161,58 @@ Phaser.Image.prototype.postUpdate = function() {
*/
Phaser.Image.prototype.loadTexture = function (key, frame) {
- this.key = key;
frame = frame || 0;
if (key instanceof Phaser.RenderTexture)
{
- this.key = key.name;
+ this.key = key.key;
this.setTexture(key);
}
else if (key instanceof Phaser.BitmapData)
{
+ this.key = key.key;
this.setTexture(key.texture);
}
else if (key instanceof PIXI.Texture)
{
+ this.key = key;
this.setTexture(key);
}
else
{
if (key === null || typeof key === 'undefined')
{
- key = '__default';
- this.key = key;
- this.setTexture(PIXI.TextureCache[key]);
+ this.key = '__default';
+ this.setTexture(PIXI.TextureCache[this.key]);
}
- else if (typeof key === 'string' && this.game.cache.checkImageKey(key) === false)
+ else if (typeof key === 'string' && !this.game.cache.checkImageKey(key))
{
- key = '__missing';
- this.key = key;
- this.setTexture(PIXI.TextureCache[key]);
+ this.key = '__missing';
+ this.setTexture(PIXI.TextureCache[this.key]);
}
if (this.game.cache.isSpriteSheet(key))
{
+ this.key = key;
+
var frameData = this.game.cache.getFrameData(key);
if (typeof frame === 'string')
{
+ this._frame = 0;
+ this._frameName = frame;
this.setTexture(PIXI.TextureCache[frameData.getFrameByName(frame).uuid]);
}
else
{
+ this._frame = frame;
+ this._frameName = '';
this.setTexture(PIXI.TextureCache[frameData.getFrame(frame).uuid]);
}
}
else
{
+ this.key = key;
this.setTexture(PIXI.TextureCache[key]);
}
}
@@ -219,7 +225,7 @@ Phaser.Image.prototype.loadTexture = function (key, frame) {
*
* @method Phaser.Image#crop
* @memberof Phaser.Image
-* @param {Phaser.Rectangle} rect - The Rectangle to crop the Image to. Pass as null to clear any previously set crop.
+* @param {Phaser.Rectangle} rect - The Rectangle to crop the Image to. Pass null or no parameters to clear a previously set crop rectangle.
*/
Phaser.Image.prototype.crop = function(rect) {
@@ -501,3 +507,66 @@ Object.defineProperty(Phaser.Image.prototype, "inCamera", {
}
});
+
+/**
+* .
+*
+* @name Phaser.Image#frame
+* @property {boolean} frame - .
+*/
+Object.defineProperty(Phaser.Image.prototype, "frame", {
+
+ get: function() {
+
+ return this._frame;
+
+ },
+
+ set: function(value) {
+
+ if (value !== this.frame && this.game.cache.isSpriteSheet(this.key))
+ {
+ var frameData = this.game.cache.getFrameData(this.key);
+
+ if (frameData && value < frameData.total && frameData.getFrame(value))
+ {
+ this.setTexture(PIXI.TextureCache[frameData.getFrame(value).uuid]);
+ this._frame = value;
+ }
+ }
+
+ }
+
+});
+
+/**
+* .
+*
+* @name Phaser.Image#frameName
+* @property {boolean} frameName - .
+*/
+Object.defineProperty(Phaser.Image.prototype, "frameName", {
+
+ get: function() {
+
+ return this._frameName;
+
+ },
+
+ set: function(value) {
+
+ if (value !== this.frameName && this.game.cache.isSpriteSheet(this.key))
+ {
+ var frameData = this.game.cache.getFrameData(this.key);
+
+ if (frameData && frameData.getFrameByName(value))
+ {
+ this.setTexture(PIXI.TextureCache[frameData.getFrameByName(value).uuid]);
+ this._frameName = value;
+ }
+ }
+
+ }
+
+});
+
From 890e52008a8bd6c2d310b1656e60ced7a41f5742 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Fri, 7 Feb 2014 07:32:11 +0000
Subject: [PATCH 19/26] Mouse callback tests.
---
examples/wip/mouse.js | 102 ++++++++++++++++++++++++++
examples/wip/mouse2.js | 106 +++++++++++++++++++++++++++
src/gameobjects/GameObjectFactory.js | 20 +----
src/gameobjects/Image.js | 10 +--
src/gameobjects/RenderTexture.js | 4 +-
5 files changed, 214 insertions(+), 28 deletions(-)
create mode 100644 examples/wip/mouse.js
create mode 100644 examples/wip/mouse2.js
diff --git a/examples/wip/mouse.js b/examples/wip/mouse.js
new file mode 100644
index 00000000..6735d71d
--- /dev/null
+++ b/examples/wip/mouse.js
@@ -0,0 +1,102 @@
+function distanceBetween(point1, point2) {
+ return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
+}
+function angleBetween(point1, point2) {
+ return Math.atan2( point2.x - point1.x, point2.y - point1.y );
+}
+
+var isDrawing, lastPoint;
+
+
+
+// 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.WEBGL, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('mushroom', 'assets/sprites/chunk.png');
+
+}
+
+var mushroom;
+var texture;
+var image;
+
+var down;
+var p;
+
+function create() {
+
+ texture = game.add.renderTexture(800, 600, 'mousetrail', true);
+
+ // We create a sprite (rather than using the factory) so it doesn't get added to the display, as we only need its texture data.
+ mushroom = new Phaser.Sprite(game, 0, 0, 'mushroom');
+ mushroom.anchor.setTo(0.5, 0.5);
+
+ // This is the sprite that is drawn to the display. We've given it the renderTexture as its texture.
+ image = game.add.image(0, 0, texture);
+
+ domElement = document.getElementById('phaser-example');
+
+ p = new Phaser.Point();
+
+ domElement.addEventListener('mousemove', onMouseMove, true);
+ domElement.addEventListener('mousedown', onMouseDown, true);
+ // domElement.addEventListener('mouseout', onMouseOut, true);
+ domElement.addEventListener('mouseup', onMouseUp, true);
+
+ texture.render(mushroom, p, false);
+
+}
+
+function onMouseDown(e) {
+ isDrawing = true;
+ lastPoint = { x: e.clientX, y: e.clientY };
+}
+
+function onMouseUp(e) {
+ isDrawing = false;
+}
+
+function onMouseMove(e) {
+
+ if (!isDrawing) return;
+
+ var currentPoint = { x: e.clientX, y: e.clientY };
+ var dist = distanceBetween(lastPoint, currentPoint);
+ var angle = angleBetween(lastPoint, currentPoint);
+
+ for (var i = 0; i < dist; i+=5) {
+ x = lastPoint.x + (Math.sin(angle) * i) - 25;
+ y = lastPoint.y + (Math.cos(angle) * i) - 25;
+ p.set(x, y);
+ texture.render(mushroom, p, false);
+
+ // ctx.beginPath();
+ // ctx.arc(x+10, y+10, 20, false, Math.PI * 2, false);
+ // ctx.closePath();
+ // ctx.fill();
+ // ctx.stroke();
+ }
+
+ lastPoint = currentPoint;
+
+}
+
+function tint() {
+
+ image.tint = Math.random() * 0xFFFFFF;
+
+}
+
+function update() {
+
+ // if (down)
+ // {
+ // }
+
+}
+
+function render() {
+
+}
diff --git a/examples/wip/mouse2.js b/examples/wip/mouse2.js
new file mode 100644
index 00000000..0b0afa79
--- /dev/null
+++ b/examples/wip/mouse2.js
@@ -0,0 +1,106 @@
+function distanceBetween(point1, point2) {
+ return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));
+}
+function angleBetween(point1, point2) {
+ return Math.atan2( point2.x - point1.x, point2.y - point1.y );
+}
+
+var isDrawing, lastPoint;
+
+
+
+// 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.WEBGL, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('mushroom', 'assets/sprites/chunk.png');
+
+}
+
+var mushroom;
+var texture;
+var image;
+
+var down;
+var p;
+
+function create() {
+
+ texture = game.add.renderTexture(800, 600, 'mousetrail', true);
+
+ // We create a sprite (rather than using the factory) so it doesn't get added to the display, as we only need its texture data.
+ mushroom = new Phaser.Sprite(game, 0, 0, 'mushroom');
+ mushroom.anchor.setTo(0.5, 0.5);
+
+ // This is the sprite that is drawn to the display. We've given it the renderTexture as its texture.
+ image = game.add.image(0, 0, texture);
+
+ domElement = document.getElementById('phaser-example');
+
+ p = new Phaser.Point();
+
+ // domElement.addEventListener('mousemove', onMouseMove, true);
+ // domElement.addEventListener('mousedown', onMouseDown, true);
+ // // domElement.addEventListener('mouseout', onMouseOut, true);
+ // domElement.addEventListener('mouseup', onMouseUp, true);
+
+ game.input.mouse.mouseDownCallback = onMouseDown;
+ game.input.mouse.mouseUpCallback = onMouseUp;
+ game.input.mouse.mouseMoveCallback = onMouseMove;
+
+ texture.render(mushroom, p, false);
+
+}
+
+function onMouseDown(e) {
+ isDrawing = true;
+ lastPoint = { x: e.clientX, y: e.clientY };
+}
+
+function onMouseUp(e) {
+ isDrawing = false;
+}
+
+function onMouseMove(e) {
+
+ if (!isDrawing) return;
+
+ var currentPoint = { x: e.clientX, y: e.clientY };
+ var dist = distanceBetween(lastPoint, currentPoint);
+ var angle = angleBetween(lastPoint, currentPoint);
+
+ for (var i = 0; i < dist; i+=5) {
+ x = lastPoint.x + (Math.sin(angle) * i) - 25;
+ y = lastPoint.y + (Math.cos(angle) * i) - 25;
+ p.set(x, y);
+ texture.render(mushroom, p, false);
+
+ // ctx.beginPath();
+ // ctx.arc(x+10, y+10, 20, false, Math.PI * 2, false);
+ // ctx.closePath();
+ // ctx.fill();
+ // ctx.stroke();
+ }
+
+ lastPoint = currentPoint;
+
+}
+
+function tint() {
+
+ image.tint = Math.random() * 0xFFFFFF;
+
+}
+
+function update() {
+
+ // if (down)
+ // {
+ // }
+
+}
+
+function render() {
+
+}
diff --git a/src/gameobjects/GameObjectFactory.js b/src/gameobjects/GameObjectFactory.js
index 0077ee4e..16f06485 100644
--- a/src/gameobjects/GameObjectFactory.js
+++ b/src/gameobjects/GameObjectFactory.js
@@ -77,24 +77,6 @@ Phaser.GameObjectFactory.prototype = {
},
- /**
- * 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
- * @param {Phaser.Group} group - The Group to add this child to.
- * @param {number} x - X position of the new sprite.
- * @param {number} y - Y position of the new sprite.
- * @param {string|RenderTexture} [key] - The image key as defined in the Game.Cache to use as the texture for this sprite OR a RenderTexture.
- * @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.
- * @returns {Phaser.Sprite} the newly created sprite object.
- */
- child: function (group, x, y, key, frame) {
-
- return group.create(x, y, key, frame);
-
- },
-
/**
* Create a tween object for a specific object. The object can be any JavaScript object or Phaser object such as Sprite.
*
@@ -299,7 +281,7 @@ Phaser.GameObjectFactory.prototype = {
if (typeof addToCache === 'undefined') { addToCache = false; }
if (typeof key === 'undefined' || key === '') { key = this.game.rnd.uuid(); }
- var texture = new Phaser.RenderTexture(this.game, key, width, height);
+ var texture = new Phaser.RenderTexture(this.game, width, height, key);
if (addToCache)
{
diff --git a/src/gameobjects/Image.js b/src/gameobjects/Image.js
index 0db20710..64a9dfa0 100644
--- a/src/gameobjects/Image.js
+++ b/src/gameobjects/Image.js
@@ -402,7 +402,7 @@ Phaser.Image.prototype.bringToTop = function(child) {
/**
* 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. Working in radians is also faster on mobile devices where Object.defineProperty is expensive to call.
+* If you wish to work in radians instead of degrees use the property Sprite.rotation instead. Working in radians is also a little faster as it doesn't have to convert the angle.
*
* @name Phaser.Image#angle
* @property {number} angle - The angle of this Image in degrees.
@@ -509,10 +509,8 @@ Object.defineProperty(Phaser.Image.prototype, "inCamera", {
});
/**
-* .
-*
* @name Phaser.Image#frame
-* @property {boolean} frame - .
+* @property {number} frame - Gets or sets the current frame index and updates the Texture for display.
*/
Object.defineProperty(Phaser.Image.prototype, "frame", {
@@ -540,10 +538,8 @@ Object.defineProperty(Phaser.Image.prototype, "frame", {
});
/**
-* .
-*
* @name Phaser.Image#frameName
-* @property {boolean} frameName - .
+* @property {string} frameName - Gets or sets the current frame by name and updates the Texture for display.
*/
Object.defineProperty(Phaser.Image.prototype, "frameName", {
diff --git a/src/gameobjects/RenderTexture.js b/src/gameobjects/RenderTexture.js
index d05cefba..1fb002d9 100644
--- a/src/gameobjects/RenderTexture.js
+++ b/src/gameobjects/RenderTexture.js
@@ -13,7 +13,7 @@
* @param {number} [width=100] - The width of the render texture.
* @param {number} [height=100] - The height of the render texture.
*/
-Phaser.RenderTexture = function (game, key, width, height) {
+Phaser.RenderTexture = function (game, width, height, key) {
/**
* @property {Phaser.Game} game - A reference to the currently running game.
@@ -30,7 +30,7 @@ Phaser.RenderTexture = function (game, key, width, height) {
*/
this.type = Phaser.RENDERTEXTURE;
- PIXI.RenderTexture.call(this, width, height, renderer);
+ PIXI.RenderTexture.call(this, width, height);
};
From bc3a3fd43ded80ad77478071e250f8d5ea0fc31c Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Fri, 7 Feb 2014 17:14:10 +0000
Subject: [PATCH 20/26] You can now use the hitArea property on Sprites and
Image objects. hitArea can be a geometry object (Rectangle, Circle, Polygon,
Ellipse) and is used in pointerOver checks.
---
README.md | 3 +
examples/wip/grid-drag.js | 86 ++++++++++++++++++++++
examples/wip/grid.js | 54 ++++++++++++++
examples/wip/hitArea.js | 81 +++++++++++++++++++++
src/core/Game.js | 3 +-
src/core/World.js | 2 +
src/gameobjects/GameObjectFactory.js | 3 +-
src/gameobjects/Image.js | 73 +++++++++++++++++--
src/geom/Circle.js | 13 ++--
src/input/Input.js | 103 ++++++++++++++++++++++++++-
src/input/InputHandler.js | 14 +++-
11 files changed, 417 insertions(+), 18 deletions(-)
create mode 100644 examples/wip/grid-drag.js
create mode 100644 examples/wip/grid.js
create mode 100644 examples/wip/hitArea.js
diff --git a/README.md b/README.md
index e115e584..dc3fd26a 100644
--- a/README.md
+++ b/README.md
@@ -75,6 +75,8 @@ Significant API changes:
New features:
* Phaser.Image is a brand new display object perfect for logos, backgrounds, etc. You can scale, rotate, tint and blend and Image, but it has no animation, physics body or input events.
+* You can now use the hitArea property on Sprites and Image objects. hitArea can be a geometry object (Rectangle, Circle, Polygon, Ellipse) and is used in pointerOver checks.
+
New Examples:
@@ -85,6 +87,7 @@ Updates:
* Phaser.AnimationParser now sets the trimmed data directly for Pixi Texture frames. Tested across JSON Hash, JSON Data, Sprite Sheet and XML.
* Game.add.renderTexture now has the addToCache parameter. If set the texture will be stored in Game.Cache and can be retrieved with Cache.getTexture(key).
* Game.add.bitmapData now has the addToCache parameter. If set the texture will be stored in Game.Cache and can be retrieved with Cache.getBitmapData(key).
+* The InputManager now sets the canvas style cursor to 'inherit' instead of 'default'.
Bug Fixes:
diff --git a/examples/wip/grid-drag.js b/examples/wip/grid-drag.js
new file mode 100644
index 00000000..3be98cb4
--- /dev/null
+++ b/examples/wip/grid-drag.js
@@ -0,0 +1,86 @@
+
+var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('block', 'assets/sprites/block.png');
+
+}
+
+var grid = [];
+var currentTile = new Phaser.Point();
+
+function create() {
+
+ // The block.png is 95x95, so for this we'll create a little grid or it won't fit:
+
+ for (var y = 0; y < 5; y++)
+ {
+ grid[y] = [];
+
+ for (var x = 0; x < 5; x++)
+ {
+ // grid[y][x] = game.add.sprite(x * 95, y * 95, 'block');
+ // coz the grid is empty like
+ grid[y][x] = null;
+ }
+ }
+
+ var block1 = game.add.sprite(600, 100, 'block');
+ block1.name = 'block1';
+ block1.inputEnabled = true;
+ block1.input.enableDrag(true);
+ block1.events.onDragStop.add(dropBlock, this);
+
+ var block2 = game.add.sprite(600, 300, 'block');
+ block2.name = 'block2';
+ block2.inputEnabled = true;
+ block2.input.enableDrag(true);
+ block2.events.onDragStop.add(dropBlock, this);
+
+}
+
+function dropBlock(sprite, pointer) {
+
+ // Convert the pointer into a grid location
+ var x = this.game.math.snapToFloor(pointer.x, 95) / 95;
+ var y = this.game.math.snapToFloor(pointer.y, 95) / 95;
+
+ // Bounds check it
+ if (x >= 0 && x <= 4 && y >= 0 && y <= 4)
+ {
+ // something in there already?
+ if (grid[y][x] !== null)
+ {
+ // This is very hacky - what you SHOULD do is have a Pipe object which has properties startX and startY or something, and snap back to those.
+ if (sprite.name === 'block1')
+ {
+ game.add.tween(sprite).to( { x: 600, y: 100 }, 1000, Phaser.Easing.Linear.None, true);
+ }
+ else
+ {
+ game.add.tween(sprite).to( { x: 600, y: 300 }, 1000, Phaser.Easing.Linear.None, true);
+ }
+ }
+ else
+ {
+ grid[y][x] = sprite;
+ sprite.inputEnabled = false;
+ }
+ }
+
+}
+
+function update() {
+
+ // 95 = width and height of the block.png
+ currentTile.x = this.game.math.snapToFloor(game.input.x, 95) / 95;
+ currentTile.y = this.game.math.snapToFloor(game.input.y, 95) / 95;
+
+}
+
+function render() {
+
+ game.debug.renderText('Tile X: ' + currentTile.x + ' Y: ' + currentTile.y, 32, 32);
+
+}
\ No newline at end of file
diff --git a/examples/wip/grid.js b/examples/wip/grid.js
new file mode 100644
index 00000000..2faf5364
--- /dev/null
+++ b/examples/wip/grid.js
@@ -0,0 +1,54 @@
+
+var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('block', 'assets/sprites/block.png');
+
+}
+
+var grid = [];
+var currentTile = new Phaser.Point();
+
+function create() {
+
+ // The block.png is 95x95, so for this we'll create a little grid or it won't fit:
+
+ for (var y = 0; y < 5; y++)
+ {
+ grid[y] = [];
+
+ for (var x = 0; x < 5; x++)
+ {
+ grid[y][x] = game.add.sprite(x * 95, y * 95, 'block');
+ }
+ }
+
+ game.input.onDown.add(clickedBlock, this);
+
+}
+
+function clickedBlock() {
+
+ // Bounds check
+ if (currentTile.x >= 0 && currentTile.x <= 4 && currentTile.y >= 0 && currentTile.y <= 4)
+ {
+ block = grid[currentTile.y][currentTile.x];
+ block.alpha = 0.5;
+ }
+
+}
+
+function update() {
+
+ // 95 = width and height of the block.png
+ currentTile.x = this.game.math.snapToFloor(game.input.x, 95) / 95;
+ currentTile.y = this.game.math.snapToFloor(game.input.y, 95) / 95;
+
+}
+
+function render() {
+
+ game.debug.renderText('Tile X: ' + currentTile.x + ' Y: ' + currentTile.y, 32, 32);
+
+}
\ No newline at end of file
diff --git a/examples/wip/hitArea.js b/examples/wip/hitArea.js
new file mode 100644
index 00000000..f14c28a7
--- /dev/null
+++ b/examples/wip/hitArea.js
@@ -0,0 +1,81 @@
+
+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('ball', 'assets/sprites/wizball.png');
+
+}
+
+var image;
+var image2;
+
+var down;
+var p;
+var c;
+
+function create() {
+
+ image = game.add.image(200, 200, 'mushroom');
+
+ image2 = game.add.image(400, 200, 'ball');
+
+ // image.rotation = 0.8;
+
+ image.inputEnabled = true;
+
+ image.events.onInputDown.add(clicked, this);
+ image.events.onInputOver.add(over, this);
+ image.events.onInputOut.add(out, this);
+
+
+
+ image2.hitArea = new Phaser.Circle(image2.width / 2, image2.height / 2, 90);
+ image2.inputEnabled = true;
+
+ image2.events.onInputDown.add(clicked, this);
+ image2.events.onInputOver.add(over, this);
+ image2.events.onInputOut.add(out, this);
+
+
+ // game.input.mouse.mouseDownCallback = onMouseDown;
+ // game.input.mouse.mouseUpCallback = onMouseUp;
+ // game.input.mouse.mouseMoveCallback = onMouseMove;
+
+}
+
+function over(object, pointer) {
+
+ object.alpha = 0.5;
+
+}
+
+function out(object, pointer) {
+
+ object.alpha = 1;
+
+}
+
+function clicked(object, pointer) {
+
+ console.log('boom');
+
+}
+
+function update() {
+
+
+}
+
+function render() {
+
+ // var p = game.input.getLocalPosition(image);
+ var p = game.input.getLocalPosition(image2);
+
+
+ game.debug.renderPointInfo(p, 32, 32);
+ game.debug.renderPoint(p);
+ game.debug.renderCircle(image2.hitArea);
+
+}
diff --git a/src/core/Game.js b/src/core/Game.js
index 9d841e4b..c7ddb647 100644
--- a/src/core/Game.js
+++ b/src/core/Game.js
@@ -457,6 +457,7 @@ Phaser.Game.prototype = {
this.world.boot();
this.input.boot();
this.sound.boot();
+ this.state.boot();
this.load.onLoadComplete.add(this.loadComplete, this);
@@ -467,8 +468,6 @@ Phaser.Game.prototype = {
this.raf = new Phaser.RequestAnimationFrame(this);
this.raf.start();
-
- this.state.boot();
}
},
diff --git a/src/core/World.js b/src/core/World.js
index 8a341a02..601ec6f6 100644
--- a/src/core/World.js
+++ b/src/core/World.js
@@ -70,6 +70,8 @@ Phaser.World.prototype.boot = function () {
*/
Phaser.World.prototype.preUpdate = function () {
+ this.currentRenderOrderID = 0;
+
for (var i = 0, len = this.children.length; i < len; i++)
{
if (this.children[i]['preUpdate'])
diff --git a/src/gameobjects/GameObjectFactory.js b/src/gameobjects/GameObjectFactory.js
index 16f06485..9a721045 100644
--- a/src/gameobjects/GameObjectFactory.js
+++ b/src/gameobjects/GameObjectFactory.js
@@ -40,7 +40,8 @@ Phaser.GameObjectFactory.prototype = {
},
/**
- * Create a new Image at the given coordinates, using the cache key and frame if set.
+ * Create a new `Image` object. An Image is a light-weight object you can use to display anything that doesn't need physics or animation.
+ * It can still rotate, scale, crop and receive input events. This makes it perfect for logos, backgrounds, simple buttons and other non-Sprite graphics.
*
* @method Phaser.GameObjectFactory#image
* @param {number} x - X position of the image.
diff --git a/src/gameobjects/Image.js b/src/gameobjects/Image.js
index 64a9dfa0..bae88878 100644
--- a/src/gameobjects/Image.js
+++ b/src/gameobjects/Image.js
@@ -7,8 +7,8 @@
/**
* @class Phaser.Image
*
-* @classdesc Create a new `Image` object. An Image is a light-weight object you can use to display anything that doesn't need physics, animation or input events.
-* It can still rotate, scale and crop. This makes it perfect for logos, backgrounds and other non-Sprite graphics.
+* @classdesc Create a new `Image` object. An Image is a light-weight object you can use to display anything that doesn't need physics or animation.
+* It can still rotate, scale, crop and receive input events. This makes it perfect for logos, backgrounds, simple buttons and other non-Sprite graphics.
*
* @constructor
* @param {Phaser.Game} game - A reference to the currently running game.
@@ -90,10 +90,15 @@ Phaser.Image = function (game, x, y, key, frame) {
this.fixedToCamera = false;
/**
- * @property {array} _cache - A small cache for previous step values.
+ * @property {Phaser.InputHandler|null} input - The Input Handler for this object. Needs to be enabled with image.inputEnabled = true before you can use it.
+ */
+ this.input = null;
+
+ /**
+ * @property {array} _cache - A small cache for previous step values. 0 = x, 1 = y, 2 = rotation, 3 = renderID
* @private
*/
- this._cache = [0, 0, 0];
+ this._cache = [0, 0, 0, 0];
};
@@ -125,6 +130,11 @@ Phaser.Image.prototype.preUpdate = function() {
this.world.setTo(this.game.camera.x + this.worldTransform[2], this.game.camera.y + this.worldTransform[5]);
+ if (this.visible)
+ {
+ this._cache[3] = this.game.world.currentRenderOrderID++;
+ }
+
return true;
};
@@ -339,6 +349,11 @@ Phaser.Image.prototype.destroy = function() {
this.events.destroy();
}
+ if (this.input)
+ {
+ this.input.destroy();
+ }
+
this.alive = false;
this.exists = false;
this.visible = false;
@@ -566,3 +581,53 @@ Object.defineProperty(Phaser.Image.prototype, "frameName", {
});
+/**
+* @name Phaser.Image#renderOrderID
+* @property {number} renderOrderID - The render order ID, reset every frame.
+* @readonly
+*/
+Object.defineProperty(Phaser.Image.prototype, "renderOrderID", {
+
+ get: function() {
+
+ return this._cache[3];
+
+ }
+
+});
+
+/**
+* By default an Image won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is
+* activated for this object and it will then start to process click/touch events and more.
+*
+* @name Phaser.Image#inputEnabled
+* @property {boolean} inputEnabled - Set to true to allow this object to receive input events.
+*/
+Object.defineProperty(Phaser.Image.prototype, "inputEnabled", {
+
+ get: function () {
+
+ return (this.input && this.input.enabled);
+
+ },
+
+ set: function (value) {
+
+ if (value)
+ {
+ if (this.input === null)
+ {
+ this.input = new Phaser.InputHandler(this);
+ this.input.start();
+ }
+ }
+ else
+ {
+ if (this.input && this.input.enabled)
+ {
+ this.input.stop();
+ }
+ }
+ }
+
+});
diff --git a/src/geom/Circle.js b/src/geom/Circle.js
index d8a390b3..7e21cdd6 100644
--- a/src/geom/Circle.js
+++ b/src/geom/Circle.js
@@ -384,21 +384,18 @@ Object.defineProperty(Phaser.Circle.prototype, "empty", {
*/
Phaser.Circle.contains = function (a, x, y) {
- if (a.radius <= 0)
- {
- return false;
- }
-
// Check if x/y are within the bounds first
- if (x >= a.left && x <= a.right && y >= a.top && y <= a.bottom)
+ if (a.radius > 0 && x >= a.left && x <= a.right && y >= a.top && y <= a.bottom)
{
var dx = (a.x - x) * (a.x - x);
var dy = (a.y - y) * (a.y - y);
return (dx + dy) <= (a.radius * a.radius);
}
-
- return false;
+ else
+ {
+ return false;
+ }
};
diff --git a/src/input/Input.js b/src/input/Input.js
index f25e5ab0..131de73f 100644
--- a/src/input/Input.js
+++ b/src/input/Input.js
@@ -530,7 +530,7 @@ Phaser.Input.prototype = {
if (this.game.canvas.style.cursor !== 'none')
{
- this.game.canvas.style.cursor = 'default';
+ this.game.canvas.style.cursor = 'inherit';
}
if (hard === true)
@@ -724,6 +724,107 @@ Phaser.Input.prototype = {
return null;
+ },
+
+ /**
+ * This will return the local coordinates of the specified displayObject for this InteractionData
+ *
+ * @method getLocalPosition
+ * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
+ * @return {Point} A point containing the coordinates of the InteractionData position relative to the DisplayObject
+ */
+ getLocalPosition: function (displayObject) {
+
+ var worldTransform = displayObject.worldTransform;
+ var global = new Phaser.Point(this.x, this.y);
+
+ // do a cheeky transform to get the mouse coords;
+ var a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx,
+ a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty,
+ id = 1 / (a00 * a11 + a01 * -a10);
+ // set the mouse coords...
+ return new Phaser.Point(a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
+ a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id);
+ },
+
+ /**
+ * Tests if the current mouse coordinates hit a sprite
+ *
+ * @method hitTest
+ * @param item {DisplayObject} The displayObject to test for a hit
+ * @param interactionData {InteractionData} The interactionData object to update in the case there is a hit
+ * @private
+ */
+ // hitTest: function (item, interactionData) {
+ hitTest: function (item, pointer) {
+
+ // var global = interactionData.global;
+ var global = new Phaser.Point(pointer.x, pointer.y);
+
+ if( !item.worldVisible )return false;
+
+ // temp fix for if the element is in a non visible
+
+ var isSprite = (item instanceof PIXI.Sprite),
+ worldTransform = item.worldTransform,
+ a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx,
+ a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty,
+ id = 1 / (a00 * a11 + a01 * -a10),
+ x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
+ y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id;
+
+ // interactionData.target = item;
+
+ //a sprite or display object with a hit area defined
+ if(item.hitArea && item.hitArea.contains) {
+ if(item.hitArea.contains(x, y)) {
+ console.log('AREA HIT!', x, y);
+ //if(isSprite)
+ // interactionData.target = item;
+
+ return true;
+ }
+
+ return false;
+ }
+ // a sprite with no hitarea defined
+ else if(isSprite)
+ {
+ var width = item.texture.frame.width,
+ height = item.texture.frame.height,
+ x1 = -width * item.anchor.x,
+ y1;
+
+ if(x > x1 && x < x1 + width)
+ {
+ y1 = -height * item.anchor.y;
+
+ if(y > y1 && y < y1 + height)
+ {
+ // set the target property if a hit is true!
+ // interactionData.target = item;
+ console.log('HIT!', x, y, x1, y1);
+ return true;
+ }
+ }
+ }
+
+ var length = item.children.length;
+
+ for (var i = 0; i < length; i++)
+ {
+ var tempItem = item.children[i];
+ // var hit = this.hitTest(tempItem, interactionData);
+ var hit = this.hitTest(tempItem);
+ if(hit)
+ {
+ // hmm.. TODO SET CORRECT TARGET?
+ // interactionData.target = item;
+ return true;
+ }
+ }
+
+ return false;
}
};
diff --git a/src/input/InputHandler.js b/src/input/InputHandler.js
index 658735f0..e39514d4 100644
--- a/src/input/InputHandler.js
+++ b/src/input/InputHandler.js
@@ -215,7 +215,7 @@ Phaser.InputHandler.prototype = {
this.enabled = true;
// Create the signals the Input component will emit
- if (this.sprite.events && this.sprite.events.onInputOver == null)
+ if (this.sprite.events && this.sprite.events.onInputOver === null)
{
this.sprite.events.onInputOver = new Phaser.Signal();
this.sprite.events.onInputOut = new Phaser.Signal();
@@ -492,11 +492,18 @@ Phaser.InputHandler.prototype = {
*/
checkPointerOver: function (pointer) {
- if (this.enabled === false || this.sprite.visible === false || (this.sprite.group && this.sprite.group.visible === false))
+ if (this.enabled === false || this.sprite.visible === false || this.sprite.parent.visible === false)
{
return false;
}
+ // Need to pass it a temp point, in case we need it again for the pixel check
+ if (this.game.input.hitTest(this.sprite, pointer))
+ {
+ return true;
+ }
+
+ /*
this.sprite.getLocalUnmodifiedPosition(this._tempPoint, pointer.x, pointer.y);
if (this._tempPoint.x >= 0 && this._tempPoint.x <= this.sprite.currentFrame.width && this._tempPoint.y >= 0 && this._tempPoint.y <= this.sprite.currentFrame.height)
@@ -510,6 +517,9 @@ Phaser.InputHandler.prototype = {
return true;
}
}
+ */
+
+ return false;
},
From dd43d59cce22ba9df581964b8d50785cbd91a8cc Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Fri, 7 Feb 2014 18:01:58 +0000
Subject: [PATCH 21/26] InputManager.getLocalPosition(displayObject, pointer,
output) will return the local coordinates of the specified displayObject and
pointer. InputManager.hitTest will test for pointer hits against a
Sprite/Image, its hitArea (if set) or any of its children.
---
README.md | 2 +
examples/wip/hitArea.js | 6 +-
src/input/Input.js | 645 +++++++++++++++++---------------------
src/input/InputHandler.js | 2 +-
4 files changed, 294 insertions(+), 361 deletions(-)
diff --git a/README.md b/README.md
index dc3fd26a..6092877b 100644
--- a/README.md
+++ b/README.md
@@ -76,6 +76,8 @@ New features:
* Phaser.Image is a brand new display object perfect for logos, backgrounds, etc. You can scale, rotate, tint and blend and Image, but it has no animation, physics body or input events.
* You can now use the hitArea property on Sprites and Image objects. hitArea can be a geometry object (Rectangle, Circle, Polygon, Ellipse) and is used in pointerOver checks.
+* InputManager.getLocalPosition(displayObject, pointer, output) will return the local coordinates of the specified displayObject and pointer.
+* InputManager.hitTest will test for pointer hits against a Sprite/Image, its hitArea (if set) or any of its children.
New Examples:
diff --git a/examples/wip/hitArea.js b/examples/wip/hitArea.js
index f14c28a7..a5f6a1ad 100644
--- a/examples/wip/hitArea.js
+++ b/examples/wip/hitArea.js
@@ -71,11 +71,11 @@ function update() {
function render() {
// var p = game.input.getLocalPosition(image);
- var p = game.input.getLocalPosition(image2);
+ // var p = game.input.getLocalPosition(image2);
- game.debug.renderPointInfo(p, 32, 32);
- game.debug.renderPoint(p);
+ // game.debug.renderPointInfo(p, 32, 32);
+ // game.debug.renderPoint(p);
game.debug.renderCircle(image2.hitArea);
}
diff --git a/src/input/Input.js b/src/input/Input.js
index 131de73f..c9b7dbc1 100644
--- a/src/input/Input.js
+++ b/src/input/Input.js
@@ -40,6 +40,257 @@ Phaser.Input = function (game) {
* @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;
+
+ /**
+ * @property {number} pollRate - How often should the input pointers be checked for updates? A value of 0 means every single frame (60fps); a value of 1 means every other frame (30fps) and so on.
+ * @default
+ */
+ this.pollRate = 0;
+
+ /**
+ * @property {number} _pollCounter - Internal var holding the current poll counter.
+ * @private
+ */
+ this._pollCounter = 0;
+
+ /**
+ * @property {Phaser.Point} _oldPosition - A point object representing the previous position of the Pointer.
+ * @private
+ */
+ this._oldPosition = null;
+
+ /**
+ * @property {number} _x - x coordinate of the most recent Pointer event
+ * @private
+ */
+ this._x = 0;
+
+ /**
+ * @property {number} _y - Y coordinate of the most recent Pointer event
+ * @private
+ */
+ this._y = 0;
+
+ /**
+ * You can disable all Input by setting Input.disabled = true. While set all new input related events will be ignored.
+ * If you need to disable just one type of input; for example mouse; use Input.mouse.disabled = true instead
+ * @property {boolean} disabled
+ * @default
+ */
+ this.disabled = false;
+
+ /**
+ * @property {number} multiInputOverride - Controls the expected behaviour when using a mouse and touch together on a multi-input device.
+ * @default
+ */
+ this.multiInputOverride = Phaser.Input.MOUSE_TOUCH_COMBINE;
+
+ /**
+ * @property {Phaser.Point} position - A point object representing the current position of the Pointer.
+ * @default
+ */
+ this.position = null;
+
+ /**
+ * @property {Phaser.Point} speed - A point object representing the speed of the Pointer. Only really useful in single Pointer games; otherwise see the Pointer objects directly.
+ */
+ this.speed = null;
+
+ /**
+ * A Circle object centered on the x/y screen coordinates of the Input.
+ * Default size of 44px (Apples recommended "finger tip" size) but can be changed to anything.
+ * @property {Phaser.Circle} circle
+ */
+ this.circle = null;
+
+ /**
+ * @property {Phaser.Point} scale - The scale by which all input coordinates are multiplied; calculated by the StageScaleMode. In an un-scaled game the values will be x = 1 and y = 1.
+ */
+ this.scale = null;
+
+ /**
+ * @property {number} maxPointers - The maximum number of Pointers allowed to be active at any one time. For lots of games it's useful to set this to 1.
+ * @default
+ */
+ this.maxPointers = 10;
+
+ /**
+ * @property {number} currentPointers - The current number of active Pointers.
+ * @default
+ */
+ this.currentPointers = 0;
+
+ /**
+ * @property {number} tapRate - The number of milliseconds that the Pointer has to be pressed down and then released to be considered a tap or click.
+ * @default
+ */
+ this.tapRate = 200;
+
+ /**
+ * @property {number} doubleTapRate - The number of milliseconds between taps of the same Pointer for it to be considered a double tap / click.
+ * @default
+ */
+ this.doubleTapRate = 300;
+
+ /**
+ * @property {number} holdRate - The number of milliseconds that the Pointer has to be pressed down for it to fire a onHold event.
+ * @default
+ */
+ this.holdRate = 2000;
+
+ /**
+ * @property {number} justPressedRate - The number of milliseconds below which the Pointer is considered justPressed.
+ * @default
+ */
+ this.justPressedRate = 200;
+
+ /**
+ * @property {number} justReleasedRate - The number of milliseconds below which the Pointer is considered justReleased .
+ * @default
+ */
+ this.justReleasedRate = 200;
+
+ /**
+ * Sets if the Pointer objects should record a history of x/y coordinates they have passed through.
+ * The history is cleared each time the Pointer is pressed down.
+ * The history is updated at the rate specified in Input.pollRate
+ * @property {boolean} recordPointerHistory
+ * @default
+ */
+ this.recordPointerHistory = false;
+
+ /**
+ * @property {number} recordRate - The rate in milliseconds at which the Pointer objects should update their tracking history.
+ * @default
+ */
+ this.recordRate = 100;
+
+ /**
+ * The total number of entries that can be recorded into the Pointer objects tracking history.
+ * If the Pointer is tracking one event every 100ms; then a trackLimit of 100 would store the last 10 seconds worth of history.
+ * @property {number} recordLimit
+ * @default
+ */
+ this.recordLimit = 100;
+
+ /**
+ * @property {Phaser.Pointer} pointer1 - A Pointer object.
+ */
+ this.pointer1 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer2 - A Pointer object.
+ */
+ this.pointer2 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer3 - A Pointer object.
+ */
+ this.pointer3 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer4 - A Pointer object.
+ */
+ this.pointer4 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer5 - A Pointer object.
+ */
+ this.pointer5 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer6 - A Pointer object.
+ */
+ this.pointer6 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer7 - A Pointer object.
+ */
+ this.pointer7 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer8 - A Pointer object.
+ */
+ this.pointer8 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer9 - A Pointer object.
+ */
+ this.pointer9 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer10 - A Pointer object.
+ */
+ this.pointer10 = null;
+
+ /**
+ * The most recently active Pointer object.
+ * When you've limited max pointers to 1 this will accurately be either the first finger touched or mouse.
+ * @property {Phaser.Pointer} activePointer
+ */
+ this.activePointer = null;
+
+ /**
+ * @property {Pointer} mousePointer - The mouse has its own unique Phaser.Pointer object which you can use if making a desktop specific game.
+ */
+ this.mousePointer = null;
+
+ /**
+ * @property {Phaser.Mouse} mouse - The Mouse Input manager.
+ */
+ this.mouse = null;
+
+ /**
+ * @property {Phaser.Keyboard} keyboard - The Keyboard Input manager.
+ */
+ this.keyboard = null;
+
+ /**
+ * @property {Phaser.Touch} touch - the Touch Input manager.
+ */
+ this.touch = null;
+
+ /**
+ * @property {Phaser.MSPointer} mspointer - The MSPointer Input manager.
+ */
+ this.mspointer = null;
+
+ /**
+ * @property {Phaser.Gamepad} gamepad - The Gamepad Input manager.
+ */
+ this.gamepad = null;
+
+ /**
+ * @property {Phaser.Signal} onDown - A Signal that is dispatched each time a pointer is pressed down.
+ */
+ this.onDown = null;
+
+ /**
+ * @property {Phaser.Signal} onUp - A Signal that is dispatched each time a pointer is released.
+ */
+ this.onUp = null;
+
+ /**
+ * @property {Phaser.Signal} onTap - A Signal that is dispatched each time a pointer is tapped.
+ */
+ this.onTap = null;
+
+ /**
+ * @property {Phaser.Signal} onHold - A Signal that is dispatched each time a pointer is held down.
+ */
+ this.onHold = null;
+
+ /**
+ * A linked list of interactive objects; the InputHandler components (belonging to Sprites) register themselves with this.
+ * @property {Phaser.LinkedList} interactiveItems
+ */
+ this.interactiveItems = new Phaser.LinkedList();
+
+ /**
+ * @property {Phaser.Point} _localPoint - Internal cache var.
+ * @private
+ */
+ this._localPoint = new Phaser.Point();
};
@@ -63,300 +314,6 @@ Phaser.Input.MOUSE_TOUCH_COMBINE = 2;
Phaser.Input.prototype = {
- /**
- * How often should the input pointers be checked for updates?
- * A value of 0 means every single frame (60fps), a value of 1 means every other frame (30fps) and so on.
- * @property {number} pollRate
- * @default
- */
- pollRate: 0,
-
- /**
- * @property {number} _pollCounter - Internal var holding the current poll counter.
- * @private
- * @default
- */
- _pollCounter: 0,
-
- /**
- * @property {Phaser.Point} _oldPosition - A point object representing the previous position of the Pointer.
- * @private
- * @default
- */
- _oldPosition: null,
-
- /**
- * @property {number} _x - x coordinate of the most recent Pointer event
- * @private
- * @default
- */
- _x: 0,
-
- /**
- * @property {number} _y - Y coordinate of the most recent Pointer event
- * @private
- * @default
- */
- _y: 0,
-
- /**
- * You can disable all Input by setting Input.disabled: true. While set all new input related events will be ignored.
- * If you need to disable just one type of input, for example mouse, use Input.mouse.disabled: true instead
- * @property {boolean} disabled
- * @default
- */
- disabled: false,
-
- /**
- * Controls the expected behaviour when using a mouse and touch together on a multi-input device.
- * @property {Description} multiInputOverride
- */
- multiInputOverride: Phaser.Input.MOUSE_TOUCH_COMBINE,
-
- /**
- * @property {Phaser.Point} position - A point object representing the current position of the Pointer.
- * @default
- */
- position: null,
-
- /**
- * A point object representing the speed of the Pointer. Only really useful in single Pointer games, otherwise see the Pointer objects directly.
- * @property {Phaser.Point} speed
- */
- speed: null,
-
- /**
- * A Circle object centered on the x/y screen coordinates of the Input.
- * Default size of 44px (Apples recommended "finger tip" size) but can be changed to anything.
- * @property {Phaser.Circle} circle
- */
- circle: null,
-
- /**
- * The scale by which all input coordinates are multiplied, calculated by the StageScaleMode.
- * In an un-scaled game the values will be x: 1 and y: 1.
- * @property {Phaser.Point} scale
- */
- scale: null,
-
- /**
- * The maximum number of Pointers allowed to be active at any one time.
- * For lots of games it's useful to set this to 1.
- * @property {number} maxPointers
- * @default
- */
- maxPointers: 10,
-
- /**
- * The current number of active Pointers.
- * @property {number} currentPointers
- * @default
- */
- currentPointers: 0,
-
- /**
- * The number of milliseconds that the Pointer has to be pressed down and then released to be considered a tap or clicke
- * @property {number} tapRate
- * @default
- */
- tapRate: 200,
-
- /**
- * The number of milliseconds between taps of the same Pointer for it to be considered a double tap / click
- * @property {number} doubleTapRate
- * @default
- */
- doubleTapRate: 300,
-
- /**
- * The number of milliseconds that the Pointer has to be pressed down for it to fire a onHold event
- * @property {number} holdRate
- * @default
- */
- holdRate: 2000,
-
- /**
- * The number of milliseconds below which the Pointer is considered justPressed
- * @property {number} justPressedRate
- * @default
- */
- justPressedRate: 200,
-
- /**
- * The number of milliseconds below which the Pointer is considered justReleased
- * @property {number} justReleasedRate
- * @default
- */
- justReleasedRate: 200,
-
- /**
- * Sets if the Pointer objects should record a history of x/y coordinates they have passed through.
- * The history is cleared each time the Pointer is pressed down.
- * The history is updated at the rate specified in Input.pollRate
- * @property {boolean} recordPointerHistory
- * @default
- */
- recordPointerHistory: false,
-
- /**
- * The rate in milliseconds at which the Pointer objects should update their tracking history
- * @property {number} recordRate
- * @default
- */
- recordRate: 100,
-
- /**
- * The total number of entries that can be recorded into the Pointer objects tracking history.
- * If the Pointer is tracking one event every 100ms, then a trackLimit of 100 would store the last 10 seconds worth of history.
- * @property {number} recordLimit
- * @default
- */
- recordLimit: 100,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer1
- */
- pointer1: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer2
- */
- pointer2: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer3
- */
- pointer3: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer4
- */
- pointer4: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer5
- */
- pointer5: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer6
- */
- pointer6: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer7
- */
- pointer7: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer8
- */
- pointer8: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer9
- */
- pointer9: null,
-
- /**
- * A Pointer object.
- * @property {Phaser.Pointer} pointer10
- */
- pointer10: null,
-
- /**
- * The most recently active Pointer object.
- * When you've limited max pointers to 1 this will accurately be either the first finger touched or mouse.
- * @property {Phaser.Pointer} activePointer
- * @default
- */
- activePointer: null,
-
- /**
- * The mouse has its own unique Phaser.Pointer object which you can use if making a desktop specific game.
- * @property {Pointer} mousePointer
- * @default
- */
- mousePointer: null,
-
- /**
- * The Mouse Input manager.
- * @property {Phaser.Mouse} mouse - The Mouse Input manager.
- * @default
- */
- mouse: null,
-
- /**
- * The Keyboard Input manager.
- * @property {Phaser.Keyboard} keyboard - The Keyboard Input manager.
- * @default
- */
- keyboard: null,
-
- /**
- * The Touch Input manager.
- * @property {Phaser.Touch} touch - the Touch Input manager.
- * @default
- */
- touch: null,
-
- /**
- * The MSPointer Input manager.
- * @property {Phaser.MSPointer} mspointer - The MSPointer Input manager.
- * @default
- */
- 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
- * @default
- */
- onDown: null,
-
- /**
- * A Signal that is dispatched each time a pointer is released.
- * @property {Phaser.Signal} onUp
- * @default
- */
- onUp: null,
-
- /**
- * A Signal that is dispatched each time a pointer is tapped.
- * @property {Phaser.Signal} onTap
- * @default
- */
- onTap: null,
-
- /**
- * A Signal that is dispatched each time a pointer is held down.
- * @property {Phaser.Signal} onHold
- * @default
- */
- onHold: null,
-
- /**
- * A linked list of interactive objects, the InputHandler components (belonging to Sprites) register themselves with this.
- * @property {Phaser.LinkedList} interactiveItems
- */
- interactiveItems: new Phaser.LinkedList(),
-
/**
* Starts the Input Manager running.
* @method Phaser.Input#boot
@@ -727,99 +684,73 @@ Phaser.Input.prototype = {
},
/**
- * This will return the local coordinates of the specified displayObject for this InteractionData
- *
- * @method getLocalPosition
- * @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
- * @return {Point} A point containing the coordinates of the InteractionData position relative to the DisplayObject
- */
- getLocalPosition: function (displayObject) {
+ * This will return the local coordinates of the specified displayObject based on the given Pointer.
+ * @method Phaser.Input#getLocalPosition
+ * @param {Phaser.Sprite|Phaser.Image} displayObject - The DisplayObject to get the local coordinates for.
+ * @param {Phaser.Pointer} pointer - The Pointer to use in the check against the displayObject.
+ * @return {Phaser.Point} A point containing the coordinates of the Pointer position relative to the DisplayObject.
+ */
+ getLocalPosition: function (displayObject, pointer, output) {
- var worldTransform = displayObject.worldTransform;
- var global = new Phaser.Point(this.x, this.y);
+ if (typeof output === 'undefined') { output = new Phaser.Point(); }
- // do a cheeky transform to get the mouse coords;
- var a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx,
- a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty,
- id = 1 / (a00 * a11 + a01 * -a10);
- // set the mouse coords...
- return new Phaser.Point(a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
- a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id);
+ var wt = displayObject.worldTransform;
+ var id = 1 / (wt.a * wt.d + wt.b * -wt.c);
+
+ return output.setTo(
+ wt.d * id * pointer.x + -wt.b * id * pointer.y + (wt.ty * wt.b - wt.tx * wt.d) * id,
+ wt.a * id * pointer.y + -wt.c * id * pointer.x + (-wt.ty * wt.a + wt.tx * wt.c) * id
+ );
+
},
/**
* Tests if the current mouse coordinates hit a sprite
*
* @method hitTest
- * @param item {DisplayObject} The displayObject to test for a hit
- * @param interactionData {InteractionData} The interactionData object to update in the case there is a hit
- * @private
+ * @param displayObject {DisplayObject} The displayObject to test for a hit
*/
- // hitTest: function (item, interactionData) {
- hitTest: function (item, pointer) {
+ hitTest: function (displayObject, pointer, localPoint) {
- // var global = interactionData.global;
- var global = new Phaser.Point(pointer.x, pointer.y);
+ if (!displayObject.worldVisible)
+ {
+ return false;
+ }
- if( !item.worldVisible )return false;
+ this.getLocalPosition(displayObject, pointer, this._localPoint);
- // temp fix for if the element is in a non visible
-
- var isSprite = (item instanceof PIXI.Sprite),
- worldTransform = item.worldTransform,
- a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx,
- a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty,
- id = 1 / (a00 * a11 + a01 * -a10),
- x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
- y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id;
-
- // interactionData.target = item;
-
- //a sprite or display object with a hit area defined
- if(item.hitArea && item.hitArea.contains) {
- if(item.hitArea.contains(x, y)) {
- console.log('AREA HIT!', x, y);
- //if(isSprite)
- // interactionData.target = item;
+ localPoint.copyFrom(this._localPoint);
+ if (displayObject.hitArea && displayObject.hitArea.contains)
+ {
+ if (displayObject.hitArea.contains(this._localPoint.x, this._localPoint.y))
+ {
return true;
}
return false;
}
- // a sprite with no hitarea defined
- else if(isSprite)
+ else if (displayObject instanceof PIXI.Sprite)
{
- var width = item.texture.frame.width,
- height = item.texture.frame.height,
- x1 = -width * item.anchor.x,
- y1;
+ var width = displayObject.texture.frame.width;
+ var height = displayObject.texture.frame.height;
+ var x1 = -width * displayObject.anchor.x;
- if(x > x1 && x < x1 + width)
+ if (this._localPoint.x > x1 && this._localPoint.x < x1 + width)
{
- y1 = -height * item.anchor.y;
+ var y1 = -height * displayObject.anchor.y;
- if(y > y1 && y < y1 + height)
+ if (this._localPoint.y > y1 && this._localPoint.y < y1 + height)
{
- // set the target property if a hit is true!
- // interactionData.target = item;
- console.log('HIT!', x, y, x1, y1);
return true;
}
}
}
- var length = item.children.length;
-
- for (var i = 0; i < length; i++)
+ for (var i = 0, len = displayObject.children.length; i < len; i++)
{
- var tempItem = item.children[i];
- // var hit = this.hitTest(tempItem, interactionData);
- var hit = this.hitTest(tempItem);
- if(hit)
+ if (this.hitTest(displayObject.children[i], pointer, localPoint))
{
- // hmm.. TODO SET CORRECT TARGET?
- // interactionData.target = item;
return true;
}
}
diff --git a/src/input/InputHandler.js b/src/input/InputHandler.js
index e39514d4..6f89756b 100644
--- a/src/input/InputHandler.js
+++ b/src/input/InputHandler.js
@@ -498,7 +498,7 @@ Phaser.InputHandler.prototype = {
}
// Need to pass it a temp point, in case we need it again for the pixel check
- if (this.game.input.hitTest(this.sprite, pointer))
+ if (this.game.input.hitTest(this.sprite, pointer, this._tempPoint))
{
return true;
}
From bf13c7b569e26ae4b7c6cf513cdb8c3b102434c8 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Fri, 7 Feb 2014 18:44:58 +0000
Subject: [PATCH 22/26] Updated Sprite to use the new smaller, leaner code.
Farewell insane cache objects and multiple point processing!
---
src/gameobjects/Image.js | 6 +-
src/gameobjects/Sprite.js | 907 +++++++++++---------------------------
src/input/InputHandler.js | 9 -
3 files changed, 251 insertions(+), 671 deletions(-)
diff --git a/src/gameobjects/Image.js b/src/gameobjects/Image.js
index bae88878..dc66d9c7 100644
--- a/src/gameobjects/Image.js
+++ b/src/gameobjects/Image.js
@@ -119,6 +119,7 @@ Phaser.Image.prototype.preUpdate = function() {
if (!this.exists || !this.parent.exists)
{
+ this.renderOrderID = -1;
return false;
}
@@ -363,9 +364,7 @@ Phaser.Image.prototype.destroy = function() {
};
/**
-* Resets the Sprite. This places the Sprite at the given x/y world coordinates and then
-* sets alive, exists, visible and renderable all to true. Also resets the outOfBounds state and health values.
-* If the Sprite has a physics body that too is reset.
+* Resets the Sprite. This places the Sprite at the given x/y world coordinates and then sets alive, exists, visible and renderable all to true.
*
* @method Phaser.Image#reset
* @memberof Phaser.Image
@@ -382,7 +381,6 @@ Phaser.Image.prototype.reset = function(x, y) {
this.exists = true;
this.visible = true;
this.renderable = true;
- this._outOfBoundsFired = false;
return this;
diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js
index 0b98feb1..42041330 100644
--- a/src/gameobjects/Sprite.js
+++ b/src/gameobjects/Sprite.js
@@ -38,17 +38,6 @@ Phaser.Sprite = function (game, x, y, key, frame) {
*/
this.exists = true;
- /**
- * @property {boolean} alive - This is a handy little var your game can use to determine if a sprite is alive or not, it doesn't effect rendering.
- * @default
- */
- this.alive = true;
-
- /**
- * @property {Phaser.Group|Phaser.Sprite} parent - The parent of this Sprite.
- */
- // this.group = null;
-
/**
* @property {string} name - The user defined name given to this Sprite.
* @default
@@ -59,21 +48,7 @@ Phaser.Sprite = function (game, x, y, key, frame) {
* @property {number} type - The const type of this object.
* @readonly
*/
- this.type = Phaser.SPRITE;
-
- /**
- * @property {number} renderOrderID - Used by the Renderer and Input Manager to control picking order.
- * @default
- */
- this.renderOrderID = -1;
-
- /**
- * If you would like the Sprite to have a lifespan once 'born' you can set this to a positive value. Handy for particles, bullets, etc.
- * The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called.
- * @property {number} lifespan - The lifespan of the Sprite (in ms) before it will be killed.
- * @default
- */
- this.lifespan = 0;
+ this.type = Phaser.IMAGE;
/**
* @property {Phaser.Events} events - The Events you can subscribe to that are dispatched when certain things happen on this Sprite or its components.
@@ -85,105 +60,28 @@ Phaser.Sprite = function (game, x, y, key, frame) {
*/
this.animations = new Phaser.AnimationManager(this);
- /**
- * @property {Phaser.InputHandler} input - The Input Handler Component.
- */
- this.input = new Phaser.InputHandler(this);
-
/**
* @property {string|Phaser.RenderTexture|Phaser.BitmapData|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, BitmapData or PIXI.Texture.
*/
this.key = key;
/**
- * @property {Phaser.Frame} currentFrame - A reference to the currently displayed frame.
+ * @property {number} _frame - Internal cache var.
+ * @private
*/
- this.currentFrame = null;
-
- if (key instanceof Phaser.RenderTexture)
- {
- PIXI.Sprite.call(this, key);
-
- this.currentFrame = this.game.cache.getTextureFrame(key.name);
- }
- else if (key instanceof Phaser.BitmapData)
- {
- PIXI.Sprite.call(this, key.texture, key.textureFrame);
-
- this.currentFrame = key.textureFrame;
- }
- else if (key instanceof PIXI.Texture)
- {
- PIXI.Sprite.call(this, key);
-
- this.currentFrame = frame;
- }
- else
- {
- if (key === null || typeof key === 'undefined')
- {
- key = '__default';
- this.key = key;
- }
- else if (typeof key === 'string' && this.game.cache.checkImageKey(key) === false)
- {
- key = '__missing';
- this.key = key;
- }
-
- PIXI.Sprite.call(this, PIXI.TextureCache[key]);
-
- if (this.game.cache.isSpriteSheet(key))
- {
- this.animations.loadFrameData(this.game.cache.getFrameData(key));
-
- if (frame !== null)
- {
- if (typeof frame === 'string')
- {
- this.frameName = frame;
- }
- else
- {
- this.frame = frame;
- }
- }
- }
- else
- {
- this.currentFrame = this.game.cache.getFrame(key);
- }
- }
+ this._frame = 0;
/**
- * The rectangular area from the texture that will be rendered.
- * @property {Phaser.Rectangle} textureRegion
+ * @property {string} _frameName - Internal cache var.
+ * @private
*/
- this.textureRegion = new Phaser.Rectangle(this.texture.frame.x, this.texture.frame.y, this.texture.frame.width, this.texture.frame.height);
+ this._frameName = '';
- /**
- * The anchor sets the origin point of the texture.
- * The default is 0,0 this means the textures origin is the top left
- * Setting than anchor to 0.5,0.5 means the textures origin is centered
- * Setting the anchor to 1,1 would mean the textures origin points will be the bottom right
- *
- * @property {Phaser.Point} anchor - The anchor around which rotation and scaling takes place.
- */
- // this.anchor = new Phaser.Point();
+ PIXI.Sprite.call(this, PIXI.TextureCache['__default']);
- // this.position.x = x;
- // this.position.y = y;
-
- /**
- * @property {number} x - The x coordinate in world space of this Sprite.
- */
- this.x = x;
-
- /**
- * @property {number} y - The y coordinate in world space of this Sprite.
- */
- this.y = y;
+ this.loadTexture(key, frame);
+ this.position.set(x, y);
/**
* @property {Phaser.Point} world - The world coordinates of this Sprite. This differs from the x/y coordinates which are relative to the Sprites container.
@@ -193,6 +91,7 @@ Phaser.Sprite = function (game, x, y, key, frame) {
/**
* Should this Sprite be automatically culled if out of range of the camera?
* A culled sprite has its renderable property set to 'false'.
+ * Be advised this is quite an expensive operation, as it has to calculate the bounds of the object every frame, so only enable it if you really need it.
*
* @property {boolean} autoCull - A flag indicating if the Sprite should be automatically camera culled or not.
* @default
@@ -200,118 +99,18 @@ Phaser.Sprite = function (game, x, y, key, frame) {
this.autoCull = false;
/**
- * @property {Phaser.Point} scale - The scale of the Sprite when rendered. By default it's set to 1 (no scale). You can modify it via scale.x or scale.y or scale.setTo(x, y). A value of 1 means no change to the scale, 0.5 means "half the size", 2 means "twice the size", etc.
+ * A Sprite that is fixed to the camera uses its x/y coordinates as offsets from the top left of the camera.
+ * Note that if this Image is a child of a display object that has changed its position then the offset will be calculated from that.
+ * @property {boolean} fixedToCamera - Fixes this Sprite to the Camera.
+ * @default
*/
- // this.scale = new Phaser.Point(1, 1);
+ this.fixedToCamera = false;
/**
- * @property {object} _cache - A mini cache for storing all of the calculated values.
- * @private
+ * @property {Phaser.InputHandler|null} input - The Input Handler for this object. Needs to be enabled with image.inputEnabled = true before you can use it.
*/
- this._cache = {
+ this.input = null;
- fresh: true,
- dirty: false,
-
- // Transform cache
- a00: -1,
- a01: -1,
- a02: -1,
- a10: -1,
- a11: -1,
- a12: -1,
- id: -1,
-
- // Input specific transform cache
- i01: -1,
- i10: -1,
- idi: -1,
-
- // Bounds check
- left: null,
- right: null,
- top: null,
- bottom: null,
-
- // delta cache
- prevX: x,
- prevY: y,
-
- // The previous calculated position
- x: -1,
- y: -1,
-
- // The actual scale values based on the worldTransform
- scaleX: 1,
- scaleY: 1,
-
- // The width/height of the image, based on the un-modified frame size multiplied by the final calculated scale size
- width: this.currentFrame.sourceSizeW,
- height: this.currentFrame.sourceSizeH,
-
- // The actual width/height of the image if from a trimmed atlas, multiplied by the final calculated scale size
- halfWidth: Math.floor(this.currentFrame.sourceSizeW / 2),
- halfHeight: Math.floor(this.currentFrame.sourceSizeH / 2),
-
- // The width/height of the image, based on the un-modified frame size multiplied by the final calculated scale size
- calcWidth: -1,
- calcHeight: -1,
-
- // The current frame details
- // frameID: this.currentFrame.uuid, frameWidth: this.currentFrame.width, frameHeight: this.currentFrame.height,
- frameID: -1,
- frameWidth: this.currentFrame.width,
- frameHeight: this.currentFrame.height,
-
- // If this sprite visible to the camera (regardless of being set to visible or not)
- cameraVisible: true,
-
- // Crop cache
- cropX: 0,
- cropY: 0,
- cropWidth: this.currentFrame.sourceSizeW,
- cropHeight: this.currentFrame.sourceSizeH
-
- };
-
- /**
- * @property {Phaser.Point} offset - Corner point defaults. Should not typically be modified.
- */
- this.offset = new Phaser.Point();
-
- /**
- * @property {Phaser.Point} center - A Point containing the center coordinate of the Sprite. Takes rotation and scale into account.
- */
- this.center = new Phaser.Point(x + Math.floor(this._cache.width / 2), y + Math.floor(this._cache.height / 2));
-
- /**
- * @property {Phaser.Point} topLeft - A Point containing the top left coordinate of the Sprite. Takes rotation and scale into account.
- */
- this.topLeft = new Phaser.Point(x, y);
-
- /**
- * @property {Phaser.Point} topRight - A Point containing the top right coordinate of the Sprite. Takes rotation and scale into account.
- */
- this.topRight = new Phaser.Point(x + this._cache.width, y);
-
- /**
- * @property {Phaser.Point} bottomRight - A Point containing the bottom right coordinate of the Sprite. Takes rotation and scale into account.
- */
- this.bottomRight = new Phaser.Point(x + this._cache.width, y + this._cache.height);
-
- /**
- * @property {Phaser.Point} bottomLeft - A Point containing the bottom left coordinate of the Sprite. Takes rotation and scale into account.
- */
- this.bottomLeft = new Phaser.Point(x, y + this._cache.height);
-
- /**
- * This Rectangle object fully encompasses the Sprite and is updated in real-time.
- * The bounds is the full bounding area after rotation and scale have been taken into account. It should not be modified directly.
- * It's used for Camera culling and physics body alignment.
- * @property {Phaser.Rectangle} bounds
- */
- this.bounds = new Phaser.Rectangle(x, y, this._cache.width, this._cache.height);
-
/**
* @property {Phaser.Physics.Arcade.Body} body - By default Sprites have a Phaser.Physics Body attached to them. You can operate physics actions via this property, or null it to skip all physics updates.
*/
@@ -323,15 +122,12 @@ Phaser.Sprite = function (game, x, y, key, frame) {
this.health = 1;
/**
- * @property {boolean} inWorld - This value is set to true if the Sprite is positioned within the World, otherwise false.
- */
- this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds);
-
- /**
- * @property {number} inWorldThreshold - A threshold value applied to the inWorld check. If you don't want a Sprite to be considered "out of the world" until at least 100px away for example then set it to 100.
+ * If you would like the Sprite to have a lifespan once 'born' you can set this to a positive value. Handy for particles, bullets, etc.
+ * The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called.
+ * @property {number} lifespan - The lifespan of the Sprite (in ms) before it will be killed.
* @default
*/
- this.inWorldThreshold = 0;
+ this.lifespan = 0;
/**
* @property {boolean} outOfBoundsKill - If true the Sprite is killed as soon as Sprite.inWorld is false.
@@ -339,72 +135,43 @@ Phaser.Sprite = function (game, x, y, key, frame) {
*/
this.outOfBoundsKill = false;
- /**
- * @property {boolean} _outOfBoundsFired - Internal flag.
- * @private
- * @default
- */
- this._outOfBoundsFired = false;
-
- /**
- * A Sprite 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 Sprite to the Camera.
- * @default
- */
- this.fixedToCamera = false;
-
- /**
- * @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(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.
- * The crop is only applied if you have set Sprite.cropEnabled to true.
- * @property {Phaser.Rectangle} crop - The crop Rectangle applied to the Sprite texture before rendering.
- * @default
- */
- this.crop = new Phaser.Rectangle(0, 0, this._cache.width, this._cache.height);
-
- /**
- * @property {boolean} cropEnabled - If true the Sprite.crop property is used to crop the texture before render. Set to false to disable.
- * @default
- */
- this.cropEnabled = false;
-
/**
* @property {boolean} debug - Handy flag to use with Game.enableStep
* @default
*/
this.debug = false;
- this.updateCache();
- this.updateBounds();
+ /**
+ * @property {boolean} _outOfBoundsFired - Internal flag.
+ * @private
+ */
+ this._outOfBoundsFired = false;
/**
- * @property {Phaser.Point} pivot - The pivot point of the displayObject that it rotates around.
+ * @property {array} _cache - A small cache for previous step values. 0 = x, 1 = y, 2 = rotation, 3 = renderID, 4 = fresh? (0 = no, 1 = yes)
+ * @private
*/
+ this._cache = [0, 0, 0, 0];
};
-// Needed to keep the PIXI.Sprite constructor in the prototype chain (as the core pixi renderer uses an instanceof check sadly)
Phaser.Sprite.prototype = Object.create(PIXI.Sprite.prototype);
-Phaser.Sprite.prototype.constructor = Phaser.Sprite;
+Phaser.Sprite.prototype.constructor = Phaser.Image;
/**
-* Automatically called by World.preUpdate. Handles cache updates, lifespan checks, animation updates and physics updates.
+* Automatically called by World.preUpdate.
*
-* @method Phaser.Sprite#preUpdate
-* @memberof Phaser.Sprite
+* @method Phaser.Image#preUpdate
+* @memberof Phaser.Image
*/
Phaser.Sprite.prototype.preUpdate = function() {
- if (this._cache.fresh)
+ if (this._cache[4])
{
this.world.setTo(this.parent.position.x + this.position.x, this.parent.position.y + this.position.y);
this.worldTransform[2] = this.world.x;
this.worldTransform[5] = this.world.y;
- this._cache.fresh = false;
+ this._cache[4] = 0;
if (this.body)
{
@@ -417,11 +184,13 @@ Phaser.Sprite.prototype.preUpdate = function() {
return;
}
- if (!this.exists || (this.group && !this.group.exists))
+ this._cache[0] = this.world.x;
+ this._cache[1] = this.world.y;
+ this._cache[2] = this.rotation;
+
+ if (!this.exists || !this.parent.exists)
{
this.renderOrderID = -1;
-
- // Skip children if not exists
return false;
}
@@ -436,175 +205,30 @@ Phaser.Sprite.prototype.preUpdate = function() {
}
}
- this._cache.dirty = false;
-
- if (this.visible)
+ if (this.autoCull)
{
- this.renderOrderID = this.game.world.currentRenderOrderID++;
- }
-
- this.updateCache();
-
- this.updateAnimation();
-
- this.updateCrop();
-
- // Re-run the camera visibility check
- if (this._cache.dirty || this.world.x !== this._cache.prevX || this.world.y !== this._cache.prevY)
- {
- this.updateBounds();
- }
-
- if (this.body)
- {
- this.body.preUpdate();
- }
-
- return true;
-
-};
-
-/**
-* Internal function called by preUpdate.
-*
-* @method Phaser.Sprite#updateCache
-* @memberof Phaser.Sprite
-*/
-Phaser.Sprite.prototype.updateCache = function() {
-
- this._cache.prevX = this.world.x;
- this._cache.prevY = this.world.y;
-
- if (this.fixedToCamera)
- {
- this.x = this.game.camera.view.x + this.cameraOffset.x;
- this.y = this.game.camera.view.y + this.cameraOffset.y;
+ // Won't get rendered but will still get its transform updated
+ this.renderable = this.game.world.camera.screenView.intersects(this.getBounds());
}
this.world.setTo(this.game.camera.x + this.worldTransform[2], this.game.camera.y + this.worldTransform[5]);
- if (this.worldTransform[1] != this._cache.i01 || this.worldTransform[3] != this._cache.i10 || this.worldTransform[0] != this._cache.a00 || this.worldTransform[41] != this._cache.a11)
+ if (this.visible)
{
- this._cache.a00 = this.worldTransform[0]; // scaleX a |a c tx|
- this._cache.a01 = this.worldTransform[1]; // skewY c |b d ty|
- this._cache.a10 = this.worldTransform[3]; // skewX b |0 0 1|
- this._cache.a11 = this.worldTransform[4]; // scaleY d
-
- this._cache.i01 = this.worldTransform[1]; // skewY c (remains non-modified for input checks)
- this._cache.i10 = this.worldTransform[3]; // skewX b (remains non-modified for input checks)
-
- this._cache.scaleX = Math.sqrt((this._cache.a00 * this._cache.a00) + (this._cache.a01 * this._cache.a01)); // round this off a bit?
- this._cache.scaleY = Math.sqrt((this._cache.a10 * this._cache.a10) + (this._cache.a11 * this._cache.a11)); // round this off a bit?
-
- 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 = true;
+ this._cache[3] = this.game.world.currentRenderOrderID++;
}
- this._cache.a02 = this.worldTransform[2]; // translateX tx
- this._cache.a12 = this.worldTransform[5]; // translateY ty
+ this.animations.update();
-};
-
-/**
-* Internal function called by preUpdate.
-*
-* @method Phaser.Sprite#updateAnimation
-* @memberof Phaser.Sprite
-*/
-Phaser.Sprite.prototype.updateAnimation = function() {
-
- if (this.animations.update() || (this.currentFrame && this.currentFrame.uuid != this._cache.frameID))
+ if (!this.inWorld && Phaser.Rectangle.intersects(this.getBounds(), this.game.world.bounds, this.inWorldThreshold))
{
- 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 = true;
- }
-
-};
-
-/**
-* Internal function called by preUpdate.
-*
-* @method Phaser.Sprite#updateCrop
-* @memberof Phaser.Sprite
-*/
-Phaser.Sprite.prototype.updateCrop = function() {
-
- // This only runs if crop is enabled
- if (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 = true;
-
- PIXI.Texture.frameUpdates.push(this.texture);
- }
-
-};
-
-/**
-* Internal function called by preUpdate.
-*
-* @method Phaser.Sprite#updateBounds
-* @memberof Phaser.Sprite
-*/
-Phaser.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 = Phaser.Math.min(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
- this._cache.right = Phaser.Math.max(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
- this._cache.top = Phaser.Math.min(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y);
- this._cache.bottom = Phaser.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 = true;
-
- if (this.inWorld === false)
- {
- // Sprite WAS out of the screen, is it still?
- this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds, this.inWorldThreshold);
-
- if (this.inWorld)
- {
- // It's back again, reset the OOB check
- this._outOfBoundsFired = false;
- }
+ // It's back again, reset the OOB check
+ this._outOfBoundsFired = false;
}
else
{
// Sprite WAS in the screen, has it now left?
- this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds, this.inWorldThreshold);
+ this.inWorld = Phaser.Rectangle.intersects(this.getBounds(), this.game.world.bounds, this.inWorldThreshold);
if (this.inWorld === false)
{
@@ -618,7 +242,7 @@ Phaser.Sprite.prototype.updateBounds = function() {
}
}
- this._cache.cameraVisible = Phaser.Rectangle.intersects(this.game.world.camera.screenView, this.bounds, 0);
+ this._cache.cameraVisible = Phaser.Rectangle.intersects(this.game.world.camera.screenView, this.getBounds(), 0);
if (this.autoCull)
{
@@ -626,67 +250,20 @@ Phaser.Sprite.prototype.updateBounds = function() {
this.renderable = this._cache.cameraVisible;
}
-};
+ if (this.body)
+ {
+ this.body.preUpdate();
+ }
-/**
-* Gets the local position of a coordinate relative to the Sprite, factoring in rotation and scale.
-* Mostly only used internally.
-*
-* @method Phaser.Sprite#getLocalPosition
-* @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 - y coordinate within the Sprite to translate.
-* @return {Phaser.Point} The translated point.
-*/
-Phaser.Sprite.prototype.getLocalPosition = function(p, x, y) {
-
- p.x = ((this._cache.a11 * this._cache.id * x + -this._cache.a01 * this._cache.id * y + (this._cache.a12 * this._cache.a01 - this._cache.a02 * this._cache.a11) * this._cache.id) * this.scale.x) + this._cache.a02;
- p.y = ((this._cache.a00 * this._cache.id * y + -this._cache.a10 * this._cache.id * x + (-this._cache.a12 * this._cache.a00 + this._cache.a02 * this._cache.a10) * this._cache.id) * this.scale.y) + this._cache.a12;
-
- return p;
-
-};
-
-/**
-* Gets the local unmodified position of a coordinate relative to the Sprite, factoring in rotation and scale.
-* Mostly only used internally by the Input Manager, but also useful for custom hit detection.
-*
-* @method Phaser.Sprite#getLocalUnmodifiedPosition
-* @memberof Phaser.Sprite
-* @param {Phaser.Point} p - The Point object to store the results in.
-* @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) {
-
- p.x = (this._cache.a11 * this._cache.idi * gx + -this._cache.i01 * this._cache.idi * gy + (this._cache.a12 * this._cache.i01 - this._cache.a02 * this._cache.a11) * this._cache.idi) + (this.anchor.x * this._cache.width);
- p.y = (this._cache.a00 * this._cache.idi * gy + -this._cache.i10 * this._cache.idi * gx + (-this._cache.a12 * this._cache.a00 + this._cache.a02 * this._cache.i10) * this._cache.idi) + (this.anchor.y * this._cache.height);
-
- return p;
-
-};
-
-/**
-* Resets the Sprite.crop value back to the frame dimensions.
-*
-* @method Phaser.Sprite#resetCrop
-* @memberof Phaser.Sprite
-*/
-Phaser.Sprite.prototype.resetCrop = function() {
-
- this.crop = new Phaser.Rectangle(0, 0, this._cache.width, this._cache.height);
- this.texture.setFrame(this.crop);
- this.cropEnabled = false;
+ return true;
};
/**
* Internal function called by the World postUpdate cycle.
*
-* @method Phaser.Sprite#postUpdate
-* @memberof Phaser.Sprite
+* @method Phaser.Image#postUpdate
+* @memberof Phaser.Image
*/
Phaser.Sprite.prototype.postUpdate = function() {
@@ -704,17 +281,9 @@ Phaser.Sprite.prototype.postUpdate = function() {
if (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.position.x = this.game.camera.view.x + this.x;
+ this.position.y = this.game.camera.view.y + this.y;
}
- else
- {
- this._cache.x = this.x;
- this._cache.y = this.y;
- }
-
- this.position.x = this._cache.x;
- this.position.y = this._cache.y;
}
};
@@ -723,55 +292,62 @@ Phaser.Sprite.prototype.postUpdate = function() {
* Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
* This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
*
-* @method Phaser.Sprite#loadTexture
-* @memberof Phaser.Sprite
+* @method Phaser.Image#loadTexture
+* @memberof Phaser.Image
* @param {string|Phaser.RenderTexture|Phaser.BitmapData|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, BitmapData 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.Sprite.prototype.loadTexture = function (key, frame) {
- this.key = key;
+ frame = frame || 0;
if (key instanceof Phaser.RenderTexture)
{
- this.currentFrame = this.game.cache.getTextureFrame(key.name);
+ this.key = key.key;
+ this.setTexture(key);
}
else if (key instanceof Phaser.BitmapData)
{
+ this.key = key.key;
this.setTexture(key.texture);
- this.currentFrame = key.textureFrame;
}
else if (key instanceof PIXI.Texture)
{
- this.currentFrame = frame;
+ this.key = key;
+ this.setTexture(key);
}
else
{
- if (typeof key === 'undefined' || this.game.cache.checkImageKey(key) === false)
+ if (key === null || typeof key === 'undefined')
{
- key = '__default';
- this.key = key;
+ this.key = '__default';
+ this.setTexture(PIXI.TextureCache[this.key]);
+ }
+ else if (typeof key === 'string' && !this.game.cache.checkImageKey(key))
+ {
+ this.key = '__missing';
+ this.setTexture(PIXI.TextureCache[this.key]);
}
if (this.game.cache.isSpriteSheet(key))
{
+ this.key = key;
+
+ // var frameData = this.game.cache.getFrameData(key);
this.animations.loadFrameData(this.game.cache.getFrameData(key));
- if (typeof frame !== 'undefined')
+ if (typeof frame === 'string')
{
- if (typeof frame === 'string')
- {
- this.frameName = frame;
- }
- else
- {
- this.frame = frame;
- }
+ this.frameName = frame;
+ }
+ else
+ {
+ this.frame = frame;
}
}
else
{
- this.currentFrame = this.game.cache.getFrame(key);
+ this.key = key;
this.setTexture(PIXI.TextureCache[key]);
}
}
@@ -779,29 +355,49 @@ Phaser.Sprite.prototype.loadTexture = function (key, frame) {
};
/**
-* Moves the sprite so its center is located on the given x and y coordinates.
-* Doesn't change the anchor point of the sprite.
-*
-* @method Phaser.Sprite#centerOn
-* @memberof Phaser.Sprite
-* @param {number} x - The x coordinate (in world space) to position the Sprite at.
-* @param {number} y - The y coordinate (in world space) to position the Sprite at.
-* @return (Phaser.Sprite) This instance.
+* Crop allows you to crop the texture used to display this Image.
+* Cropping takes place from the top-left of the Image and can be modified in real-time by providing an updated rectangle object.
+*
+* @method Phaser.Image#crop
+* @memberof Phaser.Image
+* @param {Phaser.Rectangle} rect - The Rectangle to crop the Image to. Pass null or no parameters to clear a previously set crop rectangle.
*/
-Phaser.Sprite.prototype.centerOn = function(x, y) {
+Phaser.Sprite.prototype.crop = function(rect) {
- if (this.fixedToCamera)
+ if (typeof rect === 'undefined' || rect === null)
{
- this.cameraOffset.x = x + (this.cameraOffset.x - this.center.x);
- this.cameraOffset.y = y + (this.cameraOffset.y - this.center.y);
+ // Clear any crop that may be set
+ if (this.texture.hasOwnProperty('sourceWidth'))
+ {
+ this.texture.setFrame(new Phaser.Rectangle(0, 0, this.texture.sourceWidth, this.texture.sourceHeight));
+ }
}
else
{
- this.x = x + (this.x - this.center.x);
- this.y = y + (this.y - this.center.y);
- }
+ // Do we need to clone the PIXI.Texture object?
+ if (this.texture instanceof PIXI.Texture)
+ {
+ // Yup, let's rock it ...
+ var local = {};
- return this;
+ Phaser.Utils.extend(true, local, this.texture);
+
+ local.sourceWidth = local.width;
+ local.sourceHeight = local.height;
+ local.frame = rect;
+ local.width = rect.width;
+ local.height = rect.height;
+
+ this.texture = local;
+
+ this.texture.updateFrame = true;
+ PIXI.Texture.frameUpdates.push(this.texture);
+ }
+ else
+ {
+ this.texture.setFrame(rect);
+ }
+ }
};
@@ -877,16 +473,16 @@ Phaser.Sprite.prototype.destroy = function() {
this.parent.remove(this);
}
- if (this.input)
- {
- this.input.destroy();
- }
-
if (this.events)
{
this.events.destroy();
}
+ if (this.input)
+ {
+ this.input.destroy();
+ }
+
if (this.animations)
{
this.animations.destroy();
@@ -946,11 +542,9 @@ Phaser.Sprite.prototype.reset = function(x, y, health) {
if (typeof health === 'undefined') { health = 1; }
- // this.x = x;
- // this.y = y;
this.world.setTo(x, y);
- this.position.x = this.x;
- this.position.y = this.y;
+ this.position.x = x;
+ this.position.y = y;
this.alive = true;
this.exists = true;
this.visible = true;
@@ -976,15 +570,18 @@ Phaser.Sprite.prototype.reset = function(x, y, health) {
* @memberof Phaser.Sprite
* @return (Phaser.Sprite) This instance.
*/
-Phaser.Sprite.prototype.bringToTop = function() {
+Phaser.Sprite.prototype.bringToTop = function(child) {
- if (this.parent)
+ if (typeof child === 'undefined')
{
- this.parent.bringToTop(this);
+ if (this.parent)
+ {
+ this.parent.bringToTop(this);
+ }
}
else
{
- this.game.world.bringToTop(this);
+
}
return this;
@@ -1012,47 +609,111 @@ 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.
-*
-* @method Phaser.Sprite#deltaX
-* @memberof Phaser.Sprite
-* @return {number} The delta value. Positive if the motion was to the right, negative if to the left.
-*/
-Phaser.Sprite.prototype.deltaX = function () {
-
- return this.world.x - this._cache.prevX;
-
-};
-
-/**
-* Returns the delta x value. The difference between Sprite.y now and in the previous step.
-*
-* @method Phaser.Sprite#deltaY
-* @memberof Phaser.Sprite
-* @return {number} The delta value. Positive if the motion was downwards, negative if upwards.
-*/
-Phaser.Sprite.prototype.deltaY = 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.
-* If you wish to work in radians instead of degrees use the property Sprite.rotation instead.
-* @name Phaser.Sprite#angle
-* @property {number} angle - Gets or sets the Sprites angle of rotation in degrees.
+* If you wish to work in radians instead of degrees use the property Sprite.rotation instead. Working in radians is also a little faster as it doesn't have to convert the angle.
+*
+* @name Phaser.Image#angle
+* @property {number} angle - The angle of this Image in degrees.
*/
-Object.defineProperty(Phaser.Sprite.prototype, 'angle', {
+Object.defineProperty(Phaser.Sprite.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));
+
+ }
+
+});
+
+/**
+* Returns the delta x value. The difference between world.x now and in the previous step.
+*
+* @name Phaser.Image#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[0];
+
+ }
+
+});
+
+/**
+* Returns the delta y value. The difference between world.y now and in the previous step.
+*
+* @name Phaser.Image#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[1];
+
+ }
+
+});
+
+/**
+* Returns the delta z value. The difference between rotation now and in the previous step.
+*
+* @name Phaser.Image#deltaZ
+* @property {number} deltaZ - The delta value.
+* @readonly
+*/
+Object.defineProperty(Phaser.Sprite.prototype, "deltaZ", {
+
+ get: function() {
+
+ return this.rotation - this._cache[2];
+
+ }
+
+});
+
+/**
+* Checks if the Image bounds are within the game world, otherwise false if fully outside of it.
+*
+* @name Phaser.Image#inWorld
+* @property {boolean} inWorld - True if the Image bounds is within the game world, even if only partially. Otherwise false if fully outside of it.
+* @readonly
+*/
+Object.defineProperty(Phaser.Sprite.prototype, "inWorld", {
+
+ get: function() {
+
+ return this.game.world.bounds.intersects(this.getBounds());
+
+ }
+
+});
+
+/**
+* Checks if the Image bounds are within the game camera, otherwise false if fully outside of it.
+*
+* @name Phaser.Image#inCamera
+* @property {boolean} inCamera - True if the Image bounds is within the game camera, even if only partially. Otherwise false if fully outside of it.
+* @readonly
+*/
+Object.defineProperty(Phaser.Sprite.prototype, "inCamera", {
+
+ get: function() {
+
+ return this.game.world.camera.screenView.intersects(this.getBounds());
+
}
});
@@ -1062,7 +723,7 @@ Object.defineProperty(Phaser.Sprite.prototype, 'angle', {
* @property {number} frame - Gets or sets the current frame index and updates the Texture Cache for display.
*/
Object.defineProperty(Phaser.Sprite.prototype, "frame", {
-
+
get: function () {
return this.animations.frame;
},
@@ -1078,7 +739,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "frame", {
* @property {string} frameName - Gets or sets the current frame name and updates the Texture Cache for display.
*/
Object.defineProperty(Phaser.Sprite.prototype, "frameName", {
-
+
get: function () {
return this.animations.frameName;
},
@@ -1090,102 +751,32 @@ Object.defineProperty(Phaser.Sprite.prototype, "frameName", {
});
/**
-* @name Phaser.Sprite#inCamera
-* @property {boolean} inCamera - Is this sprite visible to the camera or not?
+* @name Phaser.Image#renderOrderID
+* @property {number} renderOrderID - The render order ID, reset every frame.
* @readonly
*/
-Object.defineProperty(Phaser.Sprite.prototype, "inCamera", {
-
- get: function () {
- return this._cache.cameraVisible;
+Object.defineProperty(Phaser.Sprite.prototype, "renderOrderID", {
+
+ get: function() {
+
+ return this._cache[3];
+
}
});
/**
-* @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.
+* By default an Image won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is
+* activated for this object and it will then start to process click/touch events and more.
*
-* @name Phaser.Sprite#width
-* @property {number} width - The width of the Sprite in pixels.
-*/
-// Object.defineProperty(Phaser.Sprite.prototype, 'width', {
-
-// get: function() {
-// return this.scale.x * this.currentFrame.width;
-// },
-
-// set: function(value) {
-
-// this.scale.x = value / this.currentFrame.width;
-// this._cache.scaleX = value / this.currentFrame.width;
-// this._width = value;
-
-// }
-
-// });
-
-/**
-* The height 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.
-*
-* @name Phaser.Sprite#height
-* @property {number} height - The height of the Sprite in pixels.
-*/
-// Object.defineProperty(Phaser.Sprite.prototype, 'height', {
-
-// get: function() {
-// return this.scale.y * this.currentFrame.height;
-// },
-
-// set: function(value) {
-
-// this.scale.y = value / this.currentFrame.height;
-// this._cache.scaleY = value / this.currentFrame.height;
-// this._height = value;
-
-// }
-
-// });
-
-/**
-* 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.Sprite#inputEnabled
-* @property {boolean} inputEnabled - Set to true to allow this Sprite to receive input events, otherwise false.
+* @name Phaser.Image#inputEnabled
+* @property {boolean} inputEnabled - Set to true to allow this object to receive input events.
*/
Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", {
get: function () {
- return (this.input.enabled);
+ return (this.input && this.input.enabled);
},
@@ -1193,19 +784,19 @@ Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", {
if (value)
{
- if (this.input.enabled === false)
+ if (this.input === null)
{
+ this.input = new Phaser.InputHandler(this);
this.input.start();
}
}
else
{
- if (this.input.enabled)
+ if (this.input && this.input.enabled)
{
this.input.stop();
}
}
-
}
});
diff --git a/src/input/InputHandler.js b/src/input/InputHandler.js
index 6f89756b..c36b07e3 100644
--- a/src/input/InputHandler.js
+++ b/src/input/InputHandler.js
@@ -499,14 +499,6 @@ Phaser.InputHandler.prototype = {
// Need to pass it a temp point, in case we need it again for the pixel check
if (this.game.input.hitTest(this.sprite, pointer, this._tempPoint))
- {
- return true;
- }
-
- /*
- this.sprite.getLocalUnmodifiedPosition(this._tempPoint, pointer.x, pointer.y);
-
- if (this._tempPoint.x >= 0 && this._tempPoint.x <= this.sprite.currentFrame.width && this._tempPoint.y >= 0 && this._tempPoint.y <= this.sprite.currentFrame.height)
{
if (this.pixelPerfect)
{
@@ -517,7 +509,6 @@ Phaser.InputHandler.prototype = {
return true;
}
}
- */
return false;
From c4297878776dd9714e3d1973cb73a3b8b19075f8 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Fri, 7 Feb 2014 18:55:29 +0000
Subject: [PATCH 23/26] Button now extends Phaser.Image not Phaser.Sprite, all
the same functionality as before remains, just no animations or physics body.
---
README.md | 2 ++
examples/buttons/button scale.js | 18 +++++++++---------
src/gameobjects/Button.js | 12 +++++++-----
3 files changed, 18 insertions(+), 14 deletions(-)
diff --git a/README.md b/README.md
index 6092877b..3755ca57 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,8 @@ Significant API changes:
* Sprite.deltaX and deltaY swapped to functions: Sprite.deltaX() and Sprite.deltaY()
* Sprite.crop() now takes a Phaser.Rectangle instead of explicit parameters.
* PixiPatch no longer needed, all features that it patched are now native in Pixi :)
+* Removed: Sprite.offset, center, topLeft, topRight, bottomRight, bottomLeft and bounds as no longer needed internally. Use Sprite.getBounds() to derive them.
+* Button now extends Phaser.Image not Phaser.Sprite, all the same functionality as before remains, just no animations or physics body.
New features:
diff --git a/examples/buttons/button scale.js b/examples/buttons/button scale.js
index aa639e50..f6af47dc 100644
--- a/examples/buttons/button scale.js
+++ b/examples/buttons/button scale.js
@@ -78,17 +78,17 @@ function changeSky (button) {
function render () {
- game.debug.renderSpriteCorners(button1, false, true);
- game.debug.renderSpriteCorners(button2, false, true);
- game.debug.renderSpriteCorners(button3, false, true);
- game.debug.renderSpriteCorners(button4, false, true);
- game.debug.renderSpriteCorners(button5, false, true);
- game.debug.renderSpriteCorners(button6, false, true);
+ // game.debug.renderSpriteCorners(button1, false, true);
+ // game.debug.renderSpriteCorners(button2, false, true);
+ // game.debug.renderSpriteCorners(button3, false, true);
+ // game.debug.renderSpriteCorners(button4, false, true);
+ // game.debug.renderSpriteCorners(button5, false, true);
+ // game.debug.renderSpriteCorners(button6, false, true);
// game.debug.renderWorldTransformInfo(button1, 32, 132);
// game.debug.renderText('sx: ' + button3.scale.x + ' sy: ' + button3.scale.y + ' w: ' + button3.width + ' cw: ' + button3._cache.width, 32, 20);
- game.debug.renderText('ox: ' + game.stage.offset.x + ' oy: ' + game.stage.offset.y, 32, 20);
- game.debug.renderPoint(button3.input._tempPoint);
- game.debug.renderPoint(button6.input._tempPoint);
+ // game.debug.renderText('ox: ' + game.stage.offset.x + ' oy: ' + game.stage.offset.y, 32, 20);
+ // game.debug.renderPoint(button3.input._tempPoint);
+ // game.debug.renderPoint(button6.input._tempPoint);
}
diff --git a/src/gameobjects/Button.js b/src/gameobjects/Button.js
index ad153e26..2b84786e 100644
--- a/src/gameobjects/Button.js
+++ b/src/gameobjects/Button.js
@@ -17,6 +17,7 @@
* You can set a unique texture frame and Sound for any of these states.
*
* @constructor
+* @extends Phaser.Image
*
* @param {Phaser.Game} game Current game instance.
* @param {number} [x=0] - X position of the Button.
@@ -37,7 +38,7 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame,
callback = callback || null;
callbackContext = callbackContext || this;
- Phaser.Sprite.call(this, game, x, y, key, outFrame);
+ Phaser.Image.call(this, game, x, y, key, outFrame);
/**
* @property {number} type - The Phaser Object Type.
@@ -180,6 +181,10 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame,
*/
this.forceOut = false;
+ this.inputEnabled = true;
+
+ this.input.start(0, true);
+
this.setFrames(overFrame, outFrame, downFrame, upFrame);
if (callback !== null)
@@ -187,8 +192,6 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame,
this.onInputUp.add(callback, callbackContext);
}
- this.input.start(0, true);
-
// Redirect the input events to here so we can handle animation updates, etc
this.events.onInputOver.add(this.onInputOverHandler, this);
this.events.onInputOut.add(this.onInputOutHandler, this);
@@ -197,8 +200,7 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame,
};
-Phaser.Button.prototype = Object.create(Phaser.Sprite.prototype);
-Phaser.Button.prototype = Phaser.Utils.extend(true, Phaser.Button.prototype, Phaser.Sprite.prototype, PIXI.Sprite.prototype);
+Phaser.Button.prototype = Object.create(Phaser.Image.prototype);
Phaser.Button.prototype.constructor = Phaser.Button;
/**
From 67bd653eb476d9bbd586078b17c6674ad3add9b0 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Fri, 7 Feb 2014 19:44:14 +0000
Subject: [PATCH 24/26] Graphics updated and restored. Working through fixing
up Physics.
---
examples/physics/ship trail.js | 3 +++
src/gameobjects/Graphics.js | 49 +++++++++-------------------------
src/gameobjects/Sprite.js | 48 ++++++++++++++++++---------------
src/physics/arcade/Body.js | 10 ++++---
4 files changed, 47 insertions(+), 63 deletions(-)
diff --git a/examples/physics/ship trail.js b/examples/physics/ship trail.js
index 43f79c05..7e048a6d 100644
--- a/examples/physics/ship trail.js
+++ b/examples/physics/ship trail.js
@@ -22,6 +22,8 @@ function create() {
var bg = game.add.sprite(0, 0, bmd);
bg.body.moves = false;
+ game.enableStep();
+
game.physics.gravity.y = 100;
sprite = game.add.sprite(32, 450, 'arrow');
@@ -61,5 +63,6 @@ function update() {
function render() {
game.debug.renderBodyInfo(sprite, 16, 24);
+ game.debug.renderPhysicsBody(sprite.body);
}
diff --git a/src/gameobjects/Graphics.js b/src/gameobjects/Graphics.js
index 742abafc..d5777119 100644
--- a/src/gameobjects/Graphics.js
+++ b/src/gameobjects/Graphics.js
@@ -42,9 +42,9 @@ Phaser.Graphics.prototype.destroy = function() {
this.clear();
- if (this.group)
+ if (this.parent)
{
- this.group.remove(this);
+ this.parent.remove(this);
}
this.game = null;
@@ -53,6 +53,8 @@ Phaser.Graphics.prototype.destroy = function() {
/*
* Draws a {Phaser.Polygon} or a {PIXI.Polygon} filled
+*
+* @method Phaser.Sprite.prototype.drawPolygon
*/
Phaser.Graphics.prototype.drawPolygon = function (poly) {
@@ -67,38 +69,11 @@ Phaser.Graphics.prototype.drawPolygon = function (poly) {
}
-Object.defineProperty(Phaser.Graphics.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));
- }
-
-});
-
-Object.defineProperty(Phaser.Graphics.prototype, 'x', {
-
- get: function() {
- return this.position.x;
- },
-
- set: function(value) {
- this.position.x = value;
- }
-
-});
-
-Object.defineProperty(Phaser.Graphics.prototype, 'y', {
-
- get: function() {
- return this.position.y;
- },
-
- set: function(value) {
- this.position.y = value;
- }
-
-});
+/**
+* Indicates the rotation of the Button 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 rotation property instead. Working in radians is also a little faster as it doesn't have to convert the angle.
+*
+* @name Phaser.Button#angle
+* @property {number} angle - The angle of this Button in degrees.
+*/
diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js
index 42041330..988c07e7 100644
--- a/src/gameobjects/Sprite.js
+++ b/src/gameobjects/Sprite.js
@@ -48,7 +48,7 @@ Phaser.Sprite = function (game, x, y, key, frame) {
* @property {number} type - The const type of this object.
* @readonly
*/
- this.type = Phaser.IMAGE;
+ this.type = Phaser.SPRITE;
/**
* @property {Phaser.Events} events - The Events you can subscribe to that are dispatched when certain things happen on this Sprite or its components.
@@ -151,26 +151,30 @@ Phaser.Sprite = function (game, x, y, key, frame) {
* @property {array} _cache - A small cache for previous step values. 0 = x, 1 = y, 2 = rotation, 3 = renderID, 4 = fresh? (0 = no, 1 = yes)
* @private
*/
- this._cache = [0, 0, 0, 0];
+ this._cache = [0, 0, 0, 0, 1];
};
Phaser.Sprite.prototype = Object.create(PIXI.Sprite.prototype);
-Phaser.Sprite.prototype.constructor = Phaser.Image;
+Phaser.Sprite.prototype.constructor = Phaser.Sprite;
/**
* Automatically called by World.preUpdate.
*
-* @method Phaser.Image#preUpdate
-* @memberof Phaser.Image
+* @method Phaser.Sprite#preUpdate
+* @memberof Phaser.Sprite
*/
Phaser.Sprite.prototype.preUpdate = function() {
- if (this._cache[4])
+ if (this._cache[4] === 1)
{
+ console.log('sprite cache fresh');
this.world.setTo(this.parent.position.x + this.position.x, this.parent.position.y + this.position.y);
this.worldTransform[2] = this.world.x;
this.worldTransform[5] = this.world.y;
+ // this._cache[0] = this.world.x;
+ // this._cache[1] = this.world.y;
+ // this._cache[2] = this.rotation;
this._cache[4] = 0;
if (this.body)
@@ -262,8 +266,8 @@ Phaser.Sprite.prototype.preUpdate = function() {
/**
* Internal function called by the World postUpdate cycle.
*
-* @method Phaser.Image#postUpdate
-* @memberof Phaser.Image
+* @method Phaser.Sprite#postUpdate
+* @memberof Phaser.Sprite
*/
Phaser.Sprite.prototype.postUpdate = function() {
@@ -281,8 +285,8 @@ Phaser.Sprite.prototype.postUpdate = function() {
if (this.fixedToCamera)
{
- this.position.x = this.game.camera.view.x + this.x;
- this.position.y = this.game.camera.view.y + this.y;
+ // this.position.x = this.game.camera.view.x + this.x;
+ // this.position.y = this.game.camera.view.y + this.y;
}
}
@@ -292,8 +296,8 @@ Phaser.Sprite.prototype.postUpdate = function() {
* Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
* This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
*
-* @method Phaser.Image#loadTexture
-* @memberof Phaser.Image
+* @method Phaser.Sprite#loadTexture
+* @memberof Phaser.Sprite
* @param {string|Phaser.RenderTexture|Phaser.BitmapData|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, BitmapData 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.
*/
@@ -358,8 +362,8 @@ Phaser.Sprite.prototype.loadTexture = function (key, frame) {
* Crop allows you to crop the texture used to display this Image.
* Cropping takes place from the top-left of the Image and can be modified in real-time by providing an updated rectangle object.
*
-* @method Phaser.Image#crop
-* @memberof Phaser.Image
+* @method Phaser.Sprite#crop
+* @memberof Phaser.Sprite
* @param {Phaser.Rectangle} rect - The Rectangle to crop the Image to. Pass null or no parameters to clear a previously set crop rectangle.
*/
Phaser.Sprite.prototype.crop = function(rect) {
@@ -614,7 +618,7 @@ Phaser.Sprite.prototype.play = function (name, frameRate, loop, killOnComplete)
* 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. Working in radians is also a little faster as it doesn't have to convert the angle.
*
-* @name Phaser.Image#angle
+* @name Phaser.Sprite#angle
* @property {number} angle - The angle of this Image in degrees.
*/
Object.defineProperty(Phaser.Sprite.prototype, "angle", {
@@ -636,7 +640,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "angle", {
/**
* Returns the delta x value. The difference between world.x now and in the previous step.
*
-* @name Phaser.Image#deltaX
+* @name Phaser.Sprite#deltaX
* @property {number} deltaX - The delta value. Positive if the motion was to the right, negative if to the left.
* @readonly
*/
@@ -653,7 +657,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "deltaX", {
/**
* Returns the delta y value. The difference between world.y now and in the previous step.
*
-* @name Phaser.Image#deltaY
+* @name Phaser.Sprite#deltaY
* @property {number} deltaY - The delta value. Positive if the motion was downwards, negative if upwards.
* @readonly
*/
@@ -670,7 +674,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "deltaY", {
/**
* Returns the delta z value. The difference between rotation now and in the previous step.
*
-* @name Phaser.Image#deltaZ
+* @name Phaser.Sprite#deltaZ
* @property {number} deltaZ - The delta value.
* @readonly
*/
@@ -687,7 +691,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "deltaZ", {
/**
* Checks if the Image bounds are within the game world, otherwise false if fully outside of it.
*
-* @name Phaser.Image#inWorld
+* @name Phaser.Sprite#inWorld
* @property {boolean} inWorld - True if the Image bounds is within the game world, even if only partially. Otherwise false if fully outside of it.
* @readonly
*/
@@ -704,7 +708,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "inWorld", {
/**
* Checks if the Image bounds are within the game camera, otherwise false if fully outside of it.
*
-* @name Phaser.Image#inCamera
+* @name Phaser.Sprite#inCamera
* @property {boolean} inCamera - True if the Image bounds is within the game camera, even if only partially. Otherwise false if fully outside of it.
* @readonly
*/
@@ -751,7 +755,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "frameName", {
});
/**
-* @name Phaser.Image#renderOrderID
+* @name Phaser.Sprite#renderOrderID
* @property {number} renderOrderID - The render order ID, reset every frame.
* @readonly
*/
@@ -769,7 +773,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "renderOrderID", {
* By default an Image won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is
* activated for this object and it will then start to process click/touch events and more.
*
-* @name Phaser.Image#inputEnabled
+* @name Phaser.Sprite#inputEnabled
* @property {boolean} inputEnabled - Set to true to allow this object to receive input events.
*/
Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", {
diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js
index 437d0766..930ed22e 100644
--- a/src/physics/arcade/Body.js
+++ b/src/physics/arcade/Body.js
@@ -381,6 +381,8 @@ Phaser.Physics.Arcade.Body.prototype = {
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;
+ console.log('body pre', this.preX, this.preY, 'now', this.x, this.y);
+
// This covers any motion that happens during this frame, not since the last frame
this.preX = this.x;
this.preY = this.y;
@@ -889,7 +891,7 @@ Phaser.Physics.Arcade.Body.prototype = {
if (this.inContact(body))
{
- return false;
+ // return false;
}
this._distances[0] = body.right - this.x; // Distance of B to face on left side of A
@@ -949,10 +951,10 @@ Phaser.Physics.Arcade.Body.prototype = {
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)
- // {
+ 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;
From ee3f6d8e7ffc35e2808e74a694dd5da78e60ed8c Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Sat, 8 Feb 2014 07:24:22 +0000
Subject: [PATCH 25/26] Tilemap had the wrong @method signatures so most were
missing from the docs.
---
README.md | 1 +
docs/Animation.js.html | 36 +-
docs/AnimationManager.js.html | 40 +-
docs/AnimationParser.js.html | 66 +-
docs/ArcadePhysics.js.html | 70 +-
docs/BitmapData.js.html | 51 +-
docs/BitmapText.js.html | 36 +-
docs/Body.js.html | 73 +-
docs/Button.js.html | 48 +-
docs/Cache.js.html | 36 +-
docs/Camera.js.html | 36 +-
docs/Canvas.js.html | 36 +-
docs/Circle.js.html | 61 +-
docs/Color.js.html | 36 +-
docs/DOMSprite.js.html | 36 +-
docs/Debug.js.html | 55 +-
docs/Device.js.html | 36 +-
docs/Easing.js.html | 36 +-
docs/Emitter.js.html | 40 +-
docs/Events.js.html | 36 +-
docs/Filter.js.html | 36 +-
docs/Frame.js.html | 58 +-
docs/FrameData.js.html | 42 +-
docs/Game.js.html | 37 +-
docs/GameObjectFactory.js.html | 117 +-
docs/Gamepad.js.html | 36 +-
docs/GamepadButton.js.html | 36 +-
docs/Graphics.js.html | 85 +-
docs/Group.js.html | 2439 ++-
docs/Image.js.html | 1144 ++
docs/Input.js.html | 658 +-
docs/InputHandler.js.html | 47 +-
docs/Key.js.html | 36 +-
docs/Keyboard.js.html | 36 +-
docs/Line.js.html | 36 +-
docs/LinkedList.js.html | 36 +-
docs/Loader.js.html | 36 +-
docs/LoaderParser.js.html | 36 +-
docs/MSPointer.js.html | 36 +-
docs/Math.js.html | 36 +-
docs/Mouse.js.html | 36 +-
docs/Net.js.html | 36 +-
docs/Particles.js.html | 36 +-
docs/Phaser.Animation.html | 36 +-
docs/Phaser.AnimationManager.html | 43 +-
docs/Phaser.AnimationParser.html | 40 +-
docs/Phaser.BitmapData.html | 259 +-
docs/Phaser.BitmapText.html | 36 +-
docs/Phaser.Button.html | 3161 +++-
docs/Phaser.Cache.html | 36 +-
docs/Phaser.Camera.html | 36 +-
docs/Phaser.Canvas.html | 36 +-
docs/Phaser.Circle.html | 72 +-
docs/Phaser.Color.html | 36 +-
docs/Phaser.DOMSprite.html | 36 +-
docs/Phaser.Device.html | 36 +-
docs/Phaser.Easing.Back.html | 36 +-
docs/Phaser.Easing.Bounce.html | 36 +-
docs/Phaser.Easing.Circular.html | 36 +-
docs/Phaser.Easing.Cubic.html | 36 +-
docs/Phaser.Easing.Elastic.html | 36 +-
docs/Phaser.Easing.Exponential.html | 36 +-
docs/Phaser.Easing.Linear.html | 36 +-
docs/Phaser.Easing.Quadratic.html | 36 +-
docs/Phaser.Easing.Quartic.html | 36 +-
docs/Phaser.Easing.Quintic.html | 36 +-
docs/Phaser.Easing.Sinusoidal.html | 36 +-
docs/Phaser.Easing.html | 36 +-
docs/Phaser.Events.html | 36 +-
docs/Phaser.Filter.html | 36 +-
docs/Phaser.Frame.html | 189 +-
docs/Phaser.FrameData.html | 36 +-
docs/Phaser.Game.html | 54 +-
docs/Phaser.GameObjectFactory.html | 836 +-
docs/Phaser.Gamepad.html | 36 +-
docs/Phaser.GamepadButton.html | 36 +-
docs/Phaser.Graphics.html | 36 +-
docs/Phaser.Group.html | 521 +-
docs/Phaser.Image.html | 3807 +++++
docs/Phaser.Input.html | 553 +-
docs/Phaser.InputHandler.html | 72 +-
docs/Phaser.Key.html | 36 +-
docs/Phaser.Keyboard.html | 36 +-
docs/Phaser.Line.html | 36 +-
docs/Phaser.LinkedList.html | 36 +-
docs/Phaser.Loader.html | 36 +-
docs/Phaser.LoaderParser.html | 36 +-
docs/Phaser.MSPointer.html | 36 +-
docs/Phaser.Math.html | 36 +-
docs/Phaser.Mouse.html | 36 +-
docs/Phaser.Net.html | 36 +-
docs/Phaser.Particles.Arcade.Emitter.html | 539 +-
docs/Phaser.Particles.html | 36 +-
docs/Phaser.Physics.Arcade.Body.html | 110 +-
docs/Phaser.Physics.Arcade.html | 78 +-
docs/Phaser.Physics.html | 36 +-
docs/Phaser.Plugin.html | 36 +-
docs/Phaser.PluginManager.html | 36 +-
docs/Phaser.Point.html | 248 +-
docs/Phaser.Pointer.html | 36 +-
docs/Phaser.Polygon.html | 36 +-
docs/Phaser.QuadTree.html | 36 +-
docs/Phaser.RandomDataGenerator.html | 36 +-
docs/Phaser.Rectangle.html | 406 +-
docs/Phaser.RenderTexture.html | 2285 ++-
docs/Phaser.RequestAnimationFrame.html | 36 +-
docs/Phaser.Signal.html | 36 +-
docs/Phaser.SinglePad.html | 36 +-
docs/Phaser.Sound.html | 36 +-
docs/Phaser.SoundManager.html | 36 +-
docs/Phaser.Sprite.html | 15678 +++++++++++++++++++-
docs/Phaser.Stage.html | 36 +-
docs/Phaser.StageScaleMode.html | 36 +-
docs/Phaser.State.html | 36 +-
docs/Phaser.StateManager.html | 36 +-
docs/Phaser.Text.html | 36 +-
docs/Phaser.Tile.html | 36 +-
docs/Phaser.TileSprite.html | 3802 ++++-
docs/Phaser.Tilemap.html | 4776 +++++-
docs/Phaser.TilemapLayer.html | 36 +-
docs/Phaser.TilemapParser.html | 36 +-
docs/Phaser.Tileset.html | 3802 +----
docs/Phaser.Time.html | 36 +-
docs/Phaser.Timer.html | 52 +-
docs/Phaser.TimerEvent.html | 138 +-
docs/Phaser.Touch.html | 36 +-
docs/Phaser.Tween.html | 36 +-
docs/Phaser.TweenManager.html | 36 +-
docs/Phaser.Utils.Debug.html | 95 +-
docs/Phaser.Utils.html | 36 +-
docs/Phaser.World.html | 692 +-
docs/Phaser.html | 45 +-
docs/Phaser.js.html | 40 +-
docs/Plugin.js.html | 36 +-
docs/PluginManager.js.html | 36 +-
docs/Point.js.html | 71 +-
docs/Pointer.js.html | 36 +-
docs/Polygon.js.html | 36 +-
docs/QuadTree.js.html | 36 +-
docs/RandomDataGenerator.js.html | 36 +-
docs/Rectangle.js.html | 488 +-
docs/RenderTexture.js.html | 348 +-
docs/RequestAnimationFrame.js.html | 36 +-
docs/SAT.js.html | 36 +-
docs/Signal.js.html | 36 +-
docs/SignalBinding.html | 36 +-
docs/SignalBinding.js.html | 36 +-
docs/SinglePad.js.html | 36 +-
docs/Sound.js.html | 36 +-
docs/SoundManager.js.html | 36 +-
docs/Sprite.js.html | 894 +-
docs/Stage.js.html | 51 +-
docs/StageScaleMode.js.html | 36 +-
docs/State.js.html | 36 +-
docs/StateManager.js.html | 36 +-
docs/Text.js.html | 36 +-
docs/Tile.js.html | 36 +-
docs/TileSprite.js.html | 36 +-
docs/Tilemap.js.html | 114 +-
docs/TilemapLayer.js.html | 36 +-
docs/TilemapParser.js.html | 36 +-
docs/Tileset.js.html | 36 +-
docs/Time.js.html | 36 +-
docs/Timer.js.html | 82 +-
docs/TimerEvent.js.html | 42 +-
docs/Touch.js.html | 36 +-
docs/Tween.js.html | 36 +-
docs/TweenManager.js.html | 36 +-
docs/Utils.js.html | 96 +-
docs/World.js.html | 125 +-
docs/classes.list.html | 45 +-
docs/global.html | 581 +-
docs/index.html | 233 +-
docs/namespaces.list.html | 45 +-
src/tilemap/Tilemap.js | 78 +-
175 files changed, 44668 insertions(+), 10218 deletions(-)
create mode 100644 docs/Image.js.html
create mode 100644 docs/Phaser.Image.html
diff --git a/README.md b/README.md
index 3755ca57..24d9d041 100644
--- a/README.md
+++ b/README.md
@@ -100,6 +100,7 @@ Bug Fixes:
* Added TimerEvent.pendingDelete and checks in Timer.update, so that removing an event in a callback no longer throws an exception (thanks georgiee)
* Fixed TypeScript defs on lines 1741-1748 (thanks wombatbuddy)
* Previously if you used Sprite.crop() it would crop all Sprites using the same base image. It now takes a local copy of the texture data and crops just that.
+* Tilemap had the wrong @method signatures so most were missing from the docs.
You can view the Change Log for all previous versions at https://github.com/photonstorm/phaser/changelog.md
diff --git a/docs/Animation.js.html b/docs/Animation.js.html
index b367005b..a908f303 100644
--- a/docs/Animation.js.html
+++ b/docs/Animation.js.html
@@ -182,6 +182,10 @@
Group
+
@@ -909,7 +943,7 @@ Phaser.Animation.generateFrameNames = function (prefix, start, stop, suffix, zer
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/AnimationManager.js.html b/docs/AnimationManager.js.html
index 7361a183..a8154b53 100644
--- a/docs/AnimationManager.js.html
+++ b/docs/AnimationManager.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -683,7 +717,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) {
@@ -695,7 +729,7 @@ Phaser.AnimationManager.prototype = {
}
}
- return false;
+ return null;
},
@@ -865,7 +899,7 @@ Object.defineProperty(Phaser.AnimationManager.prototype, 'frameName', {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/AnimationParser.js.html b/docs/AnimationParser.js.html
index 63062ca5..a840213d 100644
--- a/docs/AnimationParser.js.html
+++ b/docs/AnimationParser.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -434,13 +468,14 @@
*
* @constructor
* @param {Phaser.Game} game - A reference to the currently running game.
-* @param {number} [width=256] - The width of the BitmapData in pixels.
-* @param {number} [height=256] - The height of the BitmapData in pixels.
+* @param {string} key - Internal Phaser reference key for the render texture.
+* @param {number} [width=100] - The width of the BitmapData in pixels.
+* @param {number} [height=100] - The height of the BitmapData in pixels.
*/
-Phaser.BitmapData = function (game, width, height) {
+Phaser.BitmapData = function (game, key, width, height) {
- if (typeof width === 'undefined') { width = 256; }
- if (typeof height === 'undefined') { height = 256; }
+ if (typeof width === 'undefined') { width = 100; }
+ if (typeof height === 'undefined') { height = 100; }
/**
* @property {Phaser.Game} game - A reference to the currently running game.
@@ -448,9 +483,9 @@ Phaser.BitmapData = function (game, width, height) {
this.game = game;
/**
- * @property {string} name - The name of the BitmapData.
+ * @property {string} key - The key of the BitmapData in the Cache, if stored there.
*/
- this.name = '';
+ this.key = key;
/**
* @property {number} width - The width of the BitmapData in pixels.
@@ -1556,7 +1591,7 @@ Phaser.BitmapData.prototype.de = Phaser.BitmapData.prototype.ellipse;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/BitmapText.js.html b/docs/BitmapText.js.html
index 3f69ce4e..ceb2e4b4 100644
--- a/docs/BitmapText.js.html
+++ b/docs/BitmapText.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -669,7 +703,7 @@ Object.defineProperty(Phaser.BitmapText.prototype, 'y', {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Body.js.html b/docs/Body.js.html
index 0168e9ab..0d4fb667 100644
--- a/docs/Body.js.html
+++ b/docs/Body.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1285,7 +1319,7 @@ Phaser.Cache.prototype.constructor = Phaser.Cache;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Camera.js.html b/docs/Camera.js.html
index c91ddc80..d6988af3 100644
--- a/docs/Camera.js.html
+++ b/docs/Camera.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -853,7 +887,7 @@ Object.defineProperty(Phaser.Camera.prototype, "height", {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Canvas.js.html b/docs/Canvas.js.html
index a5a6e341..76fbb8ea 100644
--- a/docs/Canvas.js.html
+++ b/docs/Canvas.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -722,7 +756,7 @@ Phaser.Canvas = {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Circle.js.html b/docs/Circle.js.html
index b66a23cb..1c24a00e 100644
--- a/docs/Circle.js.html
+++ b/docs/Circle.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -787,7 +821,7 @@ Phaser.Color = {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/DOMSprite.js.html b/docs/DOMSprite.js.html
index 9bd6f200..ddbe9e15 100644
--- a/docs/DOMSprite.js.html
+++ b/docs/DOMSprite.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -524,7 +558,7 @@ Phaser.DOMSprite = function (game, element, x, y, style) {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Debug.js.html b/docs/Debug.js.html
index 3db78003..bddeb2ae 100644
--- a/docs/Debug.js.html
+++ b/docs/Debug.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1115,7 +1149,7 @@ Phaser.Device.prototype.constructor = Phaser.Device;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Easing.js.html b/docs/Easing.js.html
index 4c9ee5bf..16d187ee 100644
--- a/docs/Easing.js.html
+++ b/docs/Easing.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -999,7 +1033,7 @@ Phaser.Easing = {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Emitter.js.html b/docs/Emitter.js.html
index f12e2643..ee21431b 100644
--- a/docs/Emitter.js.html
+++ b/docs/Emitter.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -518,7 +552,7 @@ Phaser.Events.prototype.constructor = Phaser.Events;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Filter.js.html b/docs/Filter.js.html
index b187003d..1fd36302 100644
--- a/docs/Filter.js.html
+++ b/docs/Filter.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -595,7 +629,7 @@ Object.defineProperty(Phaser.Filter.prototype, 'height', {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Frame.js.html b/docs/Frame.js.html
index 56b5e93c..f72b2198 100644
--- a/docs/Frame.js.html
+++ b/docs/Frame.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -456,6 +490,26 @@ Phaser.GameObjectFactory.prototype = {
},
+ /**
+ * Create a new `Image` object. An Image is a light-weight object you can use to display anything that doesn't need physics or animation.
+ * It can still rotate, scale, crop and receive input events. This makes it perfect for logos, backgrounds, simple buttons and other non-Sprite graphics.
+ *
+ * @method Phaser.GameObjectFactory#image
+ * @param {number} x - X position of the image.
+ * @param {number} y - Y position of the image.
+ * @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.
+ */
+ image: function (x, y, key, frame, group) {
+
+ if (typeof group === 'undefined') { group = this.world; }
+
+ return group.add(new Phaser.Image(this.game, x, y, key, frame));
+
+ },
+
/**
* Create a new Sprite with specific position and sprite sheet key.
*
@@ -475,24 +529,6 @@ Phaser.GameObjectFactory.prototype = {
},
- /**
- * 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
- * @param {Phaser.Group} group - The Group to add this child to.
- * @param {number} x - X position of the new sprite.
- * @param {number} y - Y position of the new sprite.
- * @param {string|RenderTexture} [key] - The image key as defined in the Game.Cache to use as the texture for this sprite OR a RenderTexture.
- * @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.
- * @returns {Phaser.Sprite} the newly created sprite object.
- */
- child: function (group, x, y, key, frame) {
-
- return group.create(x, y, key, frame);
-
- },
-
/**
* Create a tween object for a specific object. The object can be any JavaScript object or Phaser object such as Sprite.
*
@@ -686,32 +722,51 @@ Phaser.GameObjectFactory.prototype = {
* A dynamic initially blank canvas to which images can be drawn.
*
* @method Phaser.GameObjectFactory#renderTexture
- * @param {string} key - Asset key for the render texture.
- * @param {number} width - the width of the render texture.
- * @param {number} height - the height of the render texture.
- * @return {Phaser.RenderTexture} The newly created renderTexture object.
+ * @param {number} [width=100] - the width of the RenderTexture.
+ * @param {number} [height=100] - the height of the RenderTexture.
+ * @param {string} [key=''] - Asset key for the RenderTexture when stored in the Cache (see addToCache parameter).
+ * @param {boolean} [addToCache=false] - Should this RenderTexture be added to the Game.Cache? If so you can retrieve it with Cache.getTexture(key)
+ * @return {Phaser.RenderTexture} The newly created RenderTexture object.
*/
- renderTexture: function (key, width, height) {
+ renderTexture: function (width, height, key, addToCache) {
- var texture = new Phaser.RenderTexture(this.game, key, width, height);
+ if (typeof addToCache === 'undefined') { addToCache = false; }
+ if (typeof key === 'undefined' || key === '') { key = this.game.rnd.uuid(); }
- this.game.cache.addRenderTexture(key, texture);
+ var texture = new Phaser.RenderTexture(this.game, width, height, key);
+
+ if (addToCache)
+ {
+ this.game.cache.addRenderTexture(key, texture);
+ }
return texture;
},
/**
- * Experimental: A BitmapData object which can be manipulated and drawn to like a traditional Canvas object and used to texture Sprites.
+ * 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.
- * @param {number} [height=256] - The height of the BitmapData in pixels.
+ * @param {number} [width=100] - The width of the BitmapData in pixels.
+ * @param {number} [height=100] - The height of the BitmapData in pixels.
+ * @param {string} [key=''] - Asset key for the BitmapData when stored in the Cache (see addToCache parameter).
+ * @param {boolean} [addToCache=false] - Should this BitmapData be added to the Game.Cache? If so you can retrieve it with Cache.getBitmapData(key)
* @return {Phaser.BitmapData} The newly created BitmapData object.
*/
- bitmapData: function (width, height) {
+ bitmapData: function (width, height, addToCache) {
- return new Phaser.BitmapData(this.game, width, height);
+ if (typeof addToCache === 'undefined') { addToCache = false; }
+ if (typeof key === 'undefined' || key === '') { key = this.game.rnd.uuid(); }
+
+ var texture = new Phaser.BitmapData(this.game, key, width, height);
+
+ if (addToCache)
+ {
+ this.game.cache.addBitmapData(key, texture);
+ }
+
+ return texture;
},
@@ -759,7 +814,7 @@ Phaser.GameObjectFactory.prototype.constructor = Phaser.GameObjectFactory;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Gamepad.js.html b/docs/Gamepad.js.html
index 54da0f92..245e1a69 100644
--- a/docs/Gamepad.js.html
+++ b/docs/Gamepad.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1014,7 +1048,7 @@ Phaser.Gamepad.XBOX360_STICK_RIGHT_Y = 3;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/GamepadButton.js.html b/docs/GamepadButton.js.html
index e4982105..55529636 100644
--- a/docs/GamepadButton.js.html
+++ b/docs/GamepadButton.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -611,7 +645,7 @@ Phaser.GamepadButton.prototype.constructor = Phaser.GamepadButton;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Graphics.js.html b/docs/Graphics.js.html
index 4c11d8b7..02ec9f9b 100644
--- a/docs/Graphics.js.html
+++ b/docs/Graphics.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -459,9 +493,9 @@ Phaser.Graphics.prototype.destroy = function() {
this.clear();
- if (this.group)
+ if (this.parent)
{
- this.group.remove(this);
+ this.parent.remove(this);
}
this.game = null;
@@ -470,6 +504,8 @@ Phaser.Graphics.prototype.destroy = function() {
/*
* Draws a {Phaser.Polygon} or a {PIXI.Polygon} filled
+*
+* @method Phaser.Sprite.prototype.drawPolygon
*/
Phaser.Graphics.prototype.drawPolygon = function (poly) {
@@ -484,41 +520,14 @@ Phaser.Graphics.prototype.drawPolygon = function (poly) {
}
-Object.defineProperty(Phaser.Graphics.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));
- }
-
-});
-
-Object.defineProperty(Phaser.Graphics.prototype, 'x', {
-
- get: function() {
- return this.position.x;
- },
-
- set: function(value) {
- this.position.x = value;
- }
-
-});
-
-Object.defineProperty(Phaser.Graphics.prototype, 'y', {
-
- get: function() {
- return this.position.y;
- },
-
- set: function(value) {
- this.position.y = value;
- }
-
-});
+/**
+* Indicates the rotation of the Button 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 rotation property instead. Working in radians is also a little faster as it doesn't have to convert the angle.
+*
+* @name Phaser.Button#angle
+* @property {number} angle - The angle of this Button in degrees.
+*/
@@ -540,7 +549,7 @@ Object.defineProperty(Phaser.Graphics.prototype, 'y', {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Group.js.html b/docs/Group.js.html
index 55d13f2c..48a7a8ed 100644
--- a/docs/Group.js.html
+++ b/docs/Group.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -427,9 +461,9 @@
* @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. If undefined it will use game.world.
+* @param {*} parent - The parent Group, DisplayObject or DisplayObjectContainer that this Group will be added to. If undefined or null 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).
+* @param {boolean} [useStage=false] - Should this Group be added to the World (default, false) or direct to the Stage (true).
*/
Phaser.Group = function (game, parent, name, useStage) {
@@ -438,7 +472,7 @@ Phaser.Group = function (game, parent, name, useStage) {
*/
this.game = game;
- if (typeof parent === 'undefined')
+ if (typeof parent === 'undefined' || parent === null)
{
parent = game.world;
}
@@ -448,38 +482,23 @@ Phaser.Group = function (game, parent, name, useStage) {
*/
this.name = name || 'group';
+ PIXI.DisplayObjectContainer.call(this);
+
if (typeof useStage === 'undefined')
{
- useStage = false;
- }
-
- if (useStage)
- {
- this._container = this.game.stage._stage;
- }
- else
- {
- this._container = new PIXI.DisplayObjectContainer();
- this._container.name = this.name;
-
if (parent)
{
- if (parent instanceof Phaser.Group)
- {
- parent._container.addChild(this._container);
- }
- else
- {
- parent.addChild(this._container);
- parent.updateTransform();
- }
+ parent.addChild(this);
}
else
{
- this.game.stage._stage.addChild(this._container);
- this.game.stage._stage.updateTransform();
+ this.game.stage._stage.addChild(this);
}
}
+ else
+ {
+ this.game.stage._stage.addChild(this);
+ }
/**
* @property {number} type - Internal Phaser Type value.
@@ -494,28 +513,24 @@ Phaser.Group = function (game, parent, name, useStage) {
this.alive = true;
/**
- * @property {boolean} exists - If exists is true the the Group is updated, otherwise it is skipped.
+ * @property {boolean} exists - If exists is true the Group is updated, otherwise it is skipped.
* @default
*/
this.exists = true;
/**
- * @property {Phaser.Group} group - The parent Group of this Group, if a child of another.
+ * @property {Phaser.Group|Phaser.Sprite} parent - The parent of this Group.
*/
- this.group = null;
-
- // Replaces the PIXI.Point with a slightly more flexible one.
- this._container.scale = new Phaser.Point(1, 1);
+ // this.group = null;
/**
- * @property {Phaser.Point} scale - The scane of the Group container.
+ * @property {Phaser.Point} scale - The scale of the Group container.
*/
- this.scale = this._container.scale;
+ this.scale = new Phaser.Point(1, 1);
/**
* @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.
@@ -524,8 +539,13 @@ Phaser.Group = function (game, parent, name, useStage) {
*/
this.cursor = null;
+ this._cursorIndex = 0;
+
};
+Phaser.Group.prototype = Object.create(PIXI.DisplayObjectContainer.prototype);
+Phaser.Group.prototype.constructor = Phaser.Group;
+
/**
* @constant
* @type {number}
@@ -556,1324 +576,970 @@ Phaser.Group.SORT_ASCENDING = -1;
*/
Phaser.Group.SORT_DESCENDING = 1;
-Phaser.Group.prototype = {
+// PIXI.DisplayObjectContainer.prototype.addChildAt = function(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 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.
- *
- * @see Phaser.Group#create
- * @see Phaser.Group#addAt
- * @method Phaser.Group#add
- * @param {*} child - An instance of Phaser.Sprite, Phaser.Button or any other display object..
- * @return {*} The child that was added to the Group.
- */
- add: function (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.
+*
+* @see Phaser.Group#create
+* @see Phaser.Group#addAt
+* @method Phaser.Group#add
+* @param {*} child - An instance of Phaser.Sprite, Phaser.Button or any other display object..
+* @return {*} The child that was added to the Group.
+*/
+Phaser.Group.prototype.add = function (child) {
- if (child.group !== this)
- {
- if (child.type && child.type === Phaser.GROUP)
- {
- child.group = this;
-
- this._container.addChild(child._container);
-
- child._container.updateTransform();
- }
- else
- {
- child.group = this;
-
- this._container.addChild(child);
-
- child.updateTransform();
-
- if (child.events)
- {
- child.events.onAddedToGroup.dispatch(child, this);
- }
- }
-
- if (this.cursor === null)
- {
- this.cursor = child;
- }
- }
-
- return 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 added to the Group at the location specified by the index value, this allows you to control child ordering.
- *
- * @method Phaser.Group#addAt
- * @param {*} child - An instance of Phaser.Sprite, Phaser.Button or any other display object..
- * @param {number} index - The index within the Group to insert the child to.
- * @return {*} The child that was added to the Group.
- */
- addAt: function (child, index) {
-
- if (child.group !== this)
- {
- if (child.type && child.type === Phaser.GROUP)
- {
- child.group = this;
-
- this._container.addChildAt(child._container, index);
-
- child._container.updateTransform();
- }
- else
- {
- child.group = this;
-
- this._container.addChildAt(child, index);
-
- child.updateTransform();
-
- if (child.events)
- {
- child.events.onAddedToGroup.dispatch(child, this);
- }
- }
-
- if (this.cursor === null)
- {
- this.cursor = child;
- }
- }
-
- return child;
-
- },
-
- /**
- * Returns the child found at the given index within this Group.
- *
- * @method Phaser.Group#getAt
- * @param {number} index - The index to return the child from.
- * @return {*} The child that was found at the given index.
- */
- getAt: function (index) {
-
- return this._container.getChildAt(index);
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#create
- * @param {number} x - The x coordinate to display the newly created Sprite at. The value is in relation to the Group.x point.
- * @param {number} y - The y coordinate to display the newly created Sprite at. The value is in relation to the Group.y point.
- * @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.
- * @return {Phaser.Sprite} The child that was created.
- */
- create: function (x, y, key, frame, exists) {
-
- if (typeof exists === 'undefined') { exists = true; }
-
- var child = new Phaser.Sprite(this.game, x, y, key, frame);
-
- child.group = this;
- child.exists = exists;
- child.visible = exists;
- child.alive = exists;
-
- this._container.addChild(child);
-
- child.updateTransform();
+ if (child.parent !== this)
+ {
+ this.addChild(child);
if (child.events)
{
child.events.onAddedToGroup.dispatch(child, this);
}
-
- if (this.cursor === null)
- {
- this.cursor = child;
- }
-
- return child;
-
- },
-
- /**
- * 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)
- *
- * @method Phaser.Group#createMultiple
- * @param {number} quantity - The number of Sprites to create.
- * @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=false] - The default exists state of the Sprite.
- */
- createMultiple: function (quantity, key, frame, exists) {
-
- if (typeof exists === 'undefined') { exists = false; }
-
- for (var i = 0; i < quantity; i++)
- {
- var child = new Phaser.Sprite(this.game, 0, 0, key, frame);
-
- child.group = this;
- child.exists = exists;
- child.visible = exists;
- child.alive = exists;
-
- this._container.addChild(child);
-
- child.updateTransform();
-
- if (child.events)
- {
- child.events.onAddedToGroup.dispatch(child, this);
- }
-
- if (this.cursor === null)
- {
- this.cursor = child;
- }
-
- }
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#next
- */
- next: function () {
-
- if (this.cursor)
- {
- // Wrap the cursor?
- if (this.cursor == this._container.last)
- {
- this.cursor = this._container._iNext;
- }
- else
- {
- this.cursor = this.cursor._iNext;
- }
- }
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#previous
- */
- previous: function () {
-
- if (this.cursor)
- {
- // Wrap the cursor?
- if (this.cursor == this._container._iNext)
- {
- this.cursor = this._container.last;
- }
- else
- {
- this.cursor = this.cursor._iPrev;
- }
- }
-
- },
-
- /**
- * Internal test.
- *
- * @method Phaser.Group#childTest
- */
- childTest: function (prefix, child) {
-
- var s = prefix + ' next: ';
-
- if (child._iNext)
- {
- s = s + child._iNext.name;
- }
- else
- {
- s = s + '-null-';
- }
-
- s = s + ' ' + prefix + ' prev: ';
-
- if (child._iPrev)
- {
- s = s + child._iPrev.name;
- }
- else
- {
- s = s + '-null-';
- }
-
- console.log(s);
-
- },
-
- /**
- * Internal test.
- *
- * @method Phaser.Group#swapIndex
- */
- swapIndex: function (index1, index2) {
-
- var child1 = this.getAt(index1);
- var child2 = this.getAt(index2);
-
- this.swap(child1, child2);
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#swap
- * @param {*} child1 - The first child to swap.
- * @param {*} child2 - The second child to swap.
- * @return {boolean} True if the swap was successful, otherwise false.
- */
- swap: function (child1, child2) {
-
- if (child1 === child2 || !child1.parent || !child2.parent || child1.group !== this || child2.group !== this)
- {
- return false;
- }
-
- // Cache the values
- var child1Prev = child1._iPrev;
- var child1Next = child1._iNext;
- var child2Prev = child2._iPrev;
- var child2Next = child2._iNext;
-
- var endNode = this._container.last._iNext;
- var currentNode = this.game.stage._stage;
-
- do
- {
- if (currentNode !== child1 && currentNode !== child2)
- {
- if (currentNode.first === child1)
- {
- currentNode.first = child2;
- }
- else if (currentNode.first === child2)
- {
- currentNode.first = child1;
- }
-
- if (currentNode.last === child1)
- {
- currentNode.last = child2;
- }
- else if (currentNode.last === child2)
- {
- currentNode.last = child1;
- }
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != endNode)
-
- if (child1._iNext == child2)
- {
- // This is a downward (A to B) neighbour swap
- child1._iNext = child2Next;
- child1._iPrev = child2;
- child2._iNext = child1;
- child2._iPrev = child1Prev;
-
- if (child1Prev) { child1Prev._iNext = child2; }
- if (child2Next) { child2Next._iPrev = child1; }
-
- if (child1.__renderGroup)
- {
- child1.__renderGroup.updateTexture(child1);
- }
-
- if (child2.__renderGroup)
- {
- child2.__renderGroup.updateTexture(child2);
- }
-
- return true;
- }
- else if (child2._iNext == child1)
- {
- // This is an upward (B to A) neighbour swap
- child1._iNext = child2;
- child1._iPrev = child2Prev;
- child2._iNext = child1Next;
- child2._iPrev = child1;
-
- if (child2Prev) { child2Prev._iNext = child1; }
- if (child1Next) { child1Next._iPrev = child2; }
-
- if (child1.__renderGroup)
- {
- child1.__renderGroup.updateTexture(child1);
- }
-
- if (child2.__renderGroup)
- {
- child2.__renderGroup.updateTexture(child2);
- }
-
- return true;
- }
- else
- {
- // Children are far apart
- child1._iNext = child2Next;
- child1._iPrev = child2Prev;
- child2._iNext = child1Next;
- child2._iPrev = child1Prev;
-
- if (child1Prev) { child1Prev._iNext = child2; }
- if (child1Next) { child1Next._iPrev = child2; }
- if (child2Prev) { child2Prev._iNext = child1; }
- if (child2Next) { child2Next._iPrev = child1; }
-
- if (child1.__renderGroup)
- {
- child1.__renderGroup.updateTexture(child1);
- }
-
- if (child2.__renderGroup)
- {
- child2.__renderGroup.updateTexture(child2);
- }
-
- return true;
- }
-
- return false;
-
- },
-
- /**
- * Brings the given child to the top of this Group so it renders above all other children.
- *
- * @method Phaser.Group#bringToTop
- * @param {*} child - The child to bring to the top of this Group.
- * @return {*} The child that was moved.
- */
- bringToTop: function (child) {
-
- if (child.group === this)
- {
- this.remove(child);
- this.add(child);
- }
-
- return child;
-
- },
-
- /**
- * Get the index position of the given child in this Group.
- *
- * @method Phaser.Group#getIndex
- * @param {*} child - The child to get the index for.
- * @return {number} The index of the child or -1 if it's not a member of this Group.
- */
- getIndex: function (child) {
-
- return this._container.children.indexOf(child);
-
- },
-
- /**
- * Replaces a child of this Group with the given newChild. The newChild cannot be a member of this Group.
- *
- * @method Phaser.Group#replace
- * @param {*} oldChild - The child in this Group that will be replaced.
- * @param {*} newChild - The child to be inserted into this group.
- */
- replace: function (oldChild, newChild) {
-
- if (!this._container.first._iNext)
- {
- return;
- }
-
- var index = this.getIndex(oldChild);
-
- if (index != -1)
- {
- if (newChild.parent !== undefined)
- {
- newChild.events.onRemovedFromGroup.dispatch(newChild, this);
- newChild.parent.removeChild(newChild);
- }
-
- this._container.removeChild(oldChild);
- this._container.addChildAt(newChild, index);
-
- newChild.events.onAddedToGroup.dispatch(newChild, this);
- newChild.updateTransform();
-
- if (this.cursor == oldChild)
- {
- this.cursor = this._container._iNext;
- }
- }
-
- },
-
- /**
- * Sets the given property to the given value on the child. The operation controls the assignment of the value.
- *
- * @method Phaser.Group#setProperty
- * @param {*} child - The child to set the property value on.
- * @param {array} key - An array of strings that make up the property that will be set.
- * @param {*} value - The value that will be set.
- * @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.
- */
- setProperty: function (child, key, value, operation) {
-
- operation = operation || 0;
-
- // As ugly as this approach looks, and although it's limited to a depth of only 4, it's extremely fast.
- // Much faster than a for loop or object iteration. There are no checks, so if the key isn't valid then it'll fail
- // but as you are likely to call this from inner loops that have to perform well, I'll take that trade off.
-
- // 0 = Equals
- // 1 = Add
- // 2 = Subtract
- // 3 = Multiply
- // 4 = Divide
-
- var len = key.length;
-
- if (len == 1)
- {
- if (operation === 0) { child[key[0]] = value; }
- else if (operation == 1) { child[key[0]] += value; }
- else if (operation == 2) { child[key[0]] -= value; }
- else if (operation == 3) { child[key[0]] *= value; }
- else if (operation == 4) { child[key[0]] /= value; }
- }
- else if (len == 2)
- {
- if (operation === 0) { child[key[0]][key[1]] = value; }
- else if (operation == 1) { child[key[0]][key[1]] += value; }
- else if (operation == 2) { child[key[0]][key[1]] -= value; }
- else if (operation == 3) { child[key[0]][key[1]] *= value; }
- else if (operation == 4) { child[key[0]][key[1]] /= value; }
- }
- else if (len == 3)
- {
- if (operation === 0) { child[key[0]][key[1]][key[2]] = value; }
- else if (operation == 1) { child[key[0]][key[1]][key[2]] += value; }
- else if (operation == 2) { child[key[0]][key[1]][key[2]] -= value; }
- else if (operation == 3) { child[key[0]][key[1]][key[2]] *= value; }
- else if (operation == 4) { child[key[0]][key[1]][key[2]] /= value; }
- }
- else if (len == 4)
- {
- if (operation === 0) { child[key[0]][key[1]][key[2]][key[3]] = value; }
- else if (operation == 1) { child[key[0]][key[1]][key[2]][key[3]] += value; }
- else if (operation == 2) { child[key[0]][key[1]][key[2]][key[3]] -= value; }
- else if (operation == 3) { child[key[0]][key[1]][key[2]][key[3]] *= value; }
- else if (operation == 4) { child[key[0]][key[1]][key[2]][key[3]] /= value; }
- }
-
- // TODO - Deep property scane
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#setAll
- * @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 only children with alive=true will be updated.
- * @param {boolean} [checkVisible=false] - If set then only children with visible=true will be updated.
- * @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.
- */
- setAll: function (key, value, checkAlive, checkVisible, operation) {
-
- key = key.split('.');
-
- if (typeof checkAlive === 'undefined') { checkAlive = false; }
- if (typeof checkVisible === 'undefined') { checkVisible = false; }
-
- operation = operation || 0;
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if ((checkAlive === false || (checkAlive && currentNode.alive)) && (checkVisible === false || (checkVisible && currentNode.visible)))
- {
- this.setProperty(currentNode, key, value, operation);
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext)
- }
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#addAll
- * @param {string} property - The property to increment, for example 'body.velocity.x' or 'angle'.
- * @param {number} amount - The amount to increment the property by. If child.x = 10 then addAll('x', 40) would make child.x = 50.
- * @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
- * @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
- */
- addAll: function (property, amount, checkAlive, checkVisible) {
-
- this.setAll(property, amount, checkAlive, checkVisible, 1);
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#subAll
- * @param {string} property - The property to decrement, for example 'body.velocity.x' or 'angle'.
- * @param {number} amount - The amount to subtract from the property. If child.x = 50 then subAll('x', 40) would make child.x = 10.
- * @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
- * @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
- */
- subAll: function (property, amount, checkAlive, checkVisible) {
-
- this.setAll(property, amount, checkAlive, checkVisible, 2);
-
- },
-
- /**
- * Multiplies the given property by the amount on all children in this Group.
- * Group.multiplyAll('x', 2) will x2 the child.x value.
- *
- * @method Phaser.Group#multiplyAll
- * @param {string} property - The property to multiply, for example 'body.velocity.x' or 'angle'.
- * @param {number} amount - The amount to multiply the property by. If child.x = 10 then multiplyAll('x', 2) would make child.x = 20.
- * @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
- * @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
- */
- multiplyAll: function (property, amount, checkAlive, checkVisible) {
-
- this.setAll(property, amount, checkAlive, checkVisible, 3);
-
- },
-
- /**
- * Divides the given property by the amount on all children in this Group.
- * Group.divideAll('x', 2) will half the child.x value.
- *
- * @method Phaser.Group#divideAll
- * @param {string} property - The property to divide, for example 'body.velocity.x' or 'angle'.
- * @param {number} amount - The amount to divide the property by. If child.x = 100 then divideAll('x', 2) would make child.x = 50.
- * @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
- * @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
- */
- divideAll: function (property, amount, checkAlive, checkVisible) {
-
- this.setAll(property, amount, checkAlive, checkVisible, 4);
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#callAllExists
- * @param {function} callback - The function that exists on the children that will be called.
- * @param {boolean} existsValue - Only children with exists=existsValue will be called.
- * @param {...*} parameter - Additional parameters that will be passed to the callback.
- */
- callAllExists: function (callback, existsValue) {
-
- var args = Array.prototype.splice.call(arguments, 2);
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.exists == existsValue && currentNode[callback])
- {
- currentNode[callback].apply(currentNode, args);
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext)
-
- }
-
- },
-
- /**
- * 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.
- * @param {array} callback - The array of function names.
- * @param {number} length - The size of the array (pre-calculated in callAll).
- * @protected
- */
- callbackFromArray: function (child, callback, length) {
-
- // Kinda looks like a Christmas tree
-
- if (length == 1)
- {
- if (child[callback[0]])
- {
- return child[callback[0]];
- }
- }
- else if (length == 2)
- {
- if (child[callback[0]][callback[1]])
- {
- return child[callback[0]][callback[1]];
- }
- }
- else if (length == 3)
- {
- if (child[callback[0]][callback[1]][callback[2]])
- {
- return child[callback[0]][callback[1]][callback[2]];
- }
- }
- else if (length == 4)
- {
- if (child[callback[0]][callback[1]][callback[2]][callback[3]])
- {
- return child[callback[0]][callback[1]][callback[2]][callback[3]];
- }
- }
- else
- {
- if (child[callback])
- {
- return child[callback];
- }
- }
-
- return false;
-
- },
-
- /**
- * 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.
- *
- * @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=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) {
-
- if (typeof method === 'undefined')
- {
- return;
- }
-
- // Extract the method into an array
- method = method.split('.');
-
- var methodLength = method.length;
-
- if (typeof context === 'undefined')
- {
- context = null;
- }
- else
- {
- // Extract the context into an array
- if (typeof context === 'string')
- {
- context = context.split('.');
- var contextLength = context.length;
- }
- }
-
- var args = Array.prototype.splice.call(arguments, 2);
- var callback = null;
- var callbackContext = null;
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var child = this._container.first._iNext;
-
- do
- {
- callback = this.callbackFromArray(child, method, methodLength);
-
- if (context && callback)
- {
- callbackContext = this.callbackFromArray(child, context, contextLength);
-
- if (callback)
- {
- callback.apply(callbackContext, args);
- }
- }
- else if (callback)
- {
- callback.apply(child, args);
- }
-
- child = child._iNext;
- }
- while (child != this._container.last._iNext)
-
- }
-
- },
-
- /**
- * 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.
- * @param {Object} callbackContext - The context in which the function should be called (usually 'this').
- * @param {boolean} checkExists - If set only children with exists=true will be passed to the callback, otherwise all children will be passed.
- */
- forEach: function (callback, callbackContext, checkExists) {
-
- if (typeof checkExists === 'undefined')
- {
- checkExists = false;
- }
-
- var args = Array.prototype.splice.call(arguments, 3);
- args.unshift(null);
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (checkExists === false || (checkExists && currentNode.exists))
- {
- args[0] = currentNode;
- callback.apply(callbackContext, args);
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
-
- }
-
- },
-
- /**
- * 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)
- *
- * @method Phaser.Group#forEachAlive
- * @param {function} callback - The function that will be called. 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').
- */
- forEachExists: function (callback, callbackContext) {
-
- var args = Array.prototype.splice.call(arguments, 2);
- args.unshift(null);
-
- this.iterate('exists', true, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
-
- },
-
- /**
- * 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)
- *
- * @method Phaser.Group#forEachAlive
- * @param {function} callback - The function that will be called. 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').
- */
- forEachAlive: function (callback, callbackContext) {
-
- var args = Array.prototype.splice.call(arguments, 2);
- args.unshift(null);
-
- this.iterate('alive', true, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
-
- },
-
- /**
- * 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)
- *
- * @method Phaser.Group#forEachDead
- * @param {function} callback - The function that will be called. 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').
- */
- forEachDead: function (callback, callbackContext) {
-
- var args = Array.prototype.splice.call(arguments, 2);
- args.unshift(null);
-
- this.iterate('alive', false, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
-
- },
-
- /**
- * 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()`.
- *
- * @method Phaser.Group#sort
- * @param {string} [index='y'] - The `string` name of the property you want to sort on.
- * @param {number} [order=Phaser.Group.SORT_ASCENDING] - The `Group` constant that defines the sort order. Possible values are Phaser.Group.SORT_ASCENDING and Phaser.Group.SORT_DESCENDING.
- */
- sort: function (index, order) {
-
- if (typeof index === 'undefined') { index = 'y'; }
- if (typeof order === 'undefined') { order = Phaser.Group.SORT_ASCENDING; }
-
- var swapped;
- var temp;
-
- do {
-
- swapped = false;
-
- for (var i = 0, len = this._container.children.length - 1; i < len; i++)
- {
- if (order == Phaser.Group.SORT_ASCENDING)
- {
- if (this._container.children[i][index] > this._container.children[i + 1][index])
- {
- this.swap(this.getAt(i), this.getAt(i + 1));
- temp = this._container.children[i];
- this._container.children[i] = this._container.children[i + 1];
- this._container.children[i + 1] = temp;
- swapped = true;
- }
- }
- else
- {
- if (this._container.children[i][index] < this._container.children[i + 1][index])
- {
- this.swap(this.getAt(i), this.getAt(i + 1));
- temp = this._container.children[i];
- this._container.children[i] = this._container.children[i + 1];
- this._container.children[i + 1] = temp;
- swapped = true;
- }
- }
- }
- } while (swapped);
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#iterate
- * @param {string} key - The child property to check, i.e. 'exists', 'alive', 'health'
- * @param {any} value - If child.key === this value it will be considered a match. Note that a strict comparison is used.
- * @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)
- {
- return 0;
- }
-
- if (typeof callback === 'undefined')
- {
- callback = false;
- }
-
- var total = 0;
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode[key] === value)
- {
- total++;
-
- if (callback)
- {
- args[0] = currentNode;
- callback.apply(callbackContext, args);
- }
-
- if (returnType === Phaser.Group.RETURN_CHILD)
- {
- return currentNode;
- }
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
-
- if (returnType === Phaser.Group.RETURN_TOTAL)
- {
- return total;
- }
- else if (returnType === Phaser.Group.RETURN_CHILD)
- {
- return null;
- }
-
- },
-
- /**
- * Call this function to retrieve the first object with exists == (the given state) in the Group.
- *
- * @method Phaser.Group#getFirstExists
- * @param {boolean} state - True or false.
- * @return {Any} The first child, or null if none found.
- */
- getFirstExists: function (state) {
-
- if (typeof state !== 'boolean')
- {
- state = true;
- }
-
- return this.iterate('exists', state, Phaser.Group.RETURN_CHILD);
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#getFirstAlive
- * @return {Any} The first alive child, or null if none found.
- */
- getFirstAlive: function () {
-
- return this.iterate('alive', true, Phaser.Group.RETURN_CHILD);
-
- },
-
- /**
- * 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.
- *
- * @method Phaser.Group#getFirstDead
- * @return {Any} The first dead child, or null if none found.
- */
- getFirstDead: function () {
-
- return this.iterate('alive', false, Phaser.Group.RETURN_CHILD);
-
- },
-
- /**
- * 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.
- */
- countLiving: function () {
-
- return this.iterate('alive', true, Phaser.Group.RETURN_TOTAL);
-
- },
-
- /**
- * 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.
- */
- countDead: function () {
-
- return this.iterate('alive', false, Phaser.Group.RETURN_TOTAL);
-
- },
-
- /**
- * Returns a member at random from the group.
- *
- * @method Phaser.Group#getRandom
- * @param {number} startIndex - Optional offset off the front of the array. Default value is 0, or the beginning of the array.
- * @param {number} length - Optional restriction on the number of values you want to randomly select from.
- * @return {Any} A random child of this Group.
- */
- getRandom: function (startIndex, length) {
-
- if (this._container.children.length === 0)
- {
- return null;
- }
-
- startIndex = startIndex || 0;
- length = length || this._container.children.length;
-
- return this.game.math.getRandom(this._container.children, startIndex, length);
-
- },
-
- /**
- * Removes the given child from this Group and sets its group property to null.
- *
- * @method Phaser.Group#remove
- * @param {Any} child - The child to remove.
- * @return {boolean} true if the child was removed from this Group, otherwise false.
- */
- remove: function (child) {
-
- if (child.group !== this)
- {
- return false;
- }
+ }
+
+ if (this.cursor === null)
+ {
+ this.cursor = child;
+ }
+
+ return 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 added to the Group at the location specified by the index value, this allows you to control child ordering.
+*
+* @method Phaser.Group#addAt
+* @param {*} child - An instance of Phaser.Sprite, Phaser.Button or any other display object..
+* @param {number} index - The index within the Group to insert the child to.
+* @return {*} The child that was added to the Group.
+*/
+Phaser.Group.prototype.addAt = function (child, index) {
+
+ if (child.parent !== this)
+ {
+ this.addChildAt(child, index);
if (child.events)
{
- child.events.onRemovedFromGroup.dispatch(child, this);
+ child.events.onAddedToGroup.dispatch(child, this);
}
+ }
- // Check it's actually in the container
- if (child.parent === this._container)
+ if (this.cursor === null)
+ {
+ this.cursor = child;
+ }
+
+ return child;
+
+}
+
+/**
+* Returns the child found at the given index within this Group.
+*
+* @method Phaser.Group#getAt
+* @param {number} index - The index to return the child from.
+* @return {*} The child that was found at the given index.
+*/
+Phaser.Group.prototype.getAt = function (index) {
+
+ return this.getChildAt(index);
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#create
+* @param {number} x - The x coordinate to display the newly created Sprite at. The value is in relation to the Group.x point.
+* @param {number} y - The y coordinate to display the newly created Sprite at. The value is in relation to the Group.y point.
+* @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.
+* @return {Phaser.Sprite} The child that was created.
+*/
+Phaser.Group.prototype.create = function (x, y, key, frame, exists) {
+
+ if (typeof exists === 'undefined') { exists = true; }
+
+ var child = new Phaser.Sprite(this.game, x, y, key, frame);
+
+ child.exists = exists;
+ child.visible = exists;
+ child.alive = exists;
+
+ this.addChild(child);
+
+ if (child.events)
+ {
+ child.events.onAddedToGroup.dispatch(child, this);
+ }
+
+ if (this.cursor === null)
+ {
+ this.cursor = child;
+ }
+
+ return child;
+
+}
+
+/**
+* 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)
+*
+* @method Phaser.Group#createMultiple
+* @param {number} quantity - The number of Sprites to create.
+* @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=false] - The default exists state of the Sprite.
+*/
+Phaser.Group.prototype.createMultiple = function (quantity, key, frame, exists) {
+
+ if (typeof exists === 'undefined') { exists = false; }
+
+ for (var i = 0; i < quantity; i++)
+ {
+ this.create(0, 0, key, frame, exists);
+ }
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#next
+*/
+Phaser.Group.prototype.next = function () {
+
+ if (this.cursor)
+ {
+ // Wrap the cursor?
+ if (this._cursorIndex === this.children.length)
{
- this._container.removeChild(child);
- }
-
- if (this.cursor == child)
- {
- if (this._container._iNext)
- {
- this.cursor = this._container._iNext;
- }
- else
- {
- this.cursor = null;
- }
- }
-
- child.group = null;
-
- return true;
-
- },
-
- /**
- * Removes all children from this Group, setting all group properties to null.
- * The Group container remains on the display list.
- *
- * @method Phaser.Group#removeAll
- */
- removeAll: function () {
-
- if (this._container.children.length === 0)
- {
- return;
- }
-
- do
- {
- if (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;
-
- },
-
- /**
- * Removes all children from this Group whos index falls beteen the given startIndex and endIndex values.
- *
- * @method Phaser.Group#removeBetween
- * @param {number} startIndex - The index to start removing children from.
- * @param {number} endIndex - The index to stop removing children from. Must be higher than startIndex and less than the length of the Group.
- */
- removeBetween: function (startIndex, endIndex) {
-
- if (this._container.children.length === 0)
- {
- return;
- }
-
- if (startIndex > endIndex || startIndex < 0 || endIndex > this._container.children.length)
- {
- return false;
- }
-
- for (var i = startIndex; i < endIndex; i++)
- {
- var child = this._container.children[i];
- child.events.onRemovedFromGroup.dispatch(child, this);
- this._container.removeChild(child);
-
- if (this.cursor == child)
- {
- if (this._container._iNext)
- {
- this.cursor = this._container._iNext;
- }
- else
- {
- this.cursor = null;
- }
- }
- }
-
- },
-
- /**
- * 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 (destroyChildren) {
-
- 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);
- }
+ this._cursorIndex = 0;
}
else
{
- this.removeAll();
+ this._cursorIndex++;
}
-
- this._container.parent.removeChild(this._container);
-
- this._container = null;
-
- this.game = null;
-
- this.exists = false;
-
- this.cursor = null;
-
- },
-
- validate: function () {
-
- var testObject = this.game.stage._stage.last._iNext;
- var displayObject = this.game.stage._stage;
- var nextObject = null;
- var prevObject = null;
- var count = 0;
-
- do
- {
- if (count > 0)
- {
- // check next
- if (displayObject !== nextObject)
- {
- console.log('check next fail');
- return false;
- }
-
- // check previous
- if (displayObject._iPrev !== prevObject)
- {
- console.log('check previous fail');
- return false;
- }
- }
-
- // Set the next object
- nextObject = displayObject._iNext;
- prevObject = displayObject;
-
- displayObject = displayObject._iNext;
-
- count++;
-
- }
- while(displayObject != testObject)
-
- return true;
+ this.cursor = this.children[this._cursorIndex];
}
-};
+}
-Phaser.Group.prototype.constructor = Phaser.Group;
+/**
+* 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.
+*
+* @method Phaser.Group#previous
+*/
+Phaser.Group.prototype.previous = function () {
+
+ if (this.cursor)
+ {
+ // Wrap the cursor?
+ if (this._cursorIndex === 0)
+ {
+ this._cursorIndex = this.children.length - 1;
+ }
+ else
+ {
+ this._cursorIndex--;
+ }
+
+ this.cursor = this.children[this._cursorIndex];
+ }
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#swap
+* @param {*} child1 - The first child to swap.
+* @param {*} child2 - The second child to swap.
+*/
+Phaser.Group.prototype.swap = function (child1, child2) {
+
+ return this.swapChildren(child1, child2);
+
+}
+
+/**
+* Brings the given child to the top of this Group so it renders above all other children.
+*
+* @method Phaser.Group#bringToTop
+* @param {*} child - The child to bring to the top of this Group.
+* @return {*} The child that was moved.
+*/
+Phaser.Group.prototype.bringToTop = function (child) {
+
+ if (child.parent === this)
+ {
+ this.remove(child);
+ this.add(child);
+ }
+
+ return child;
+
+}
+
+/**
+* Get the index position of the given child in this Group.
+*
+* @method Phaser.Group#getIndex
+* @param {*} child - The child to get the index for.
+* @return {number} The index of the child or -1 if it's not a member of this Group.
+*/
+Phaser.Group.prototype.getIndex = function (child) {
+
+ return this.children.indexOf(child);
+
+}
+
+/**
+* Replaces a child of this Group with the given newChild. The newChild cannot be a member of this Group.
+*
+* @method Phaser.Group#replace
+* @param {*} oldChild - The child in this Group that will be replaced.
+* @param {*} newChild - The child to be inserted into this group.
+*/
+Phaser.Group.prototype.replace = function (oldChild, newChild) {
+
+ var index = this.getIndex(oldChild);
+
+ if (index !== -1)
+ {
+ if (newChild.parent !== undefined)
+ {
+ newChild.events.onRemovedFromGroup.dispatch(newChild, this);
+ newChild.parent.removeChild(newChild);
+ }
+
+ this.removeChild(oldChild);
+ this.addChildAt(newChild, index);
+
+ newChild.events.onAddedToGroup.dispatch(newChild, this);
+
+ if (this.cursor === oldChild)
+ {
+ this.cursor = newChild;
+ }
+ }
+
+}
+
+/**
+* Sets the given property to the given value on the child. The operation controls the assignment of the value.
+*
+* @method Phaser.Group#setProperty
+* @param {*} child - The child to set the property value on.
+* @param {array} key - An array of strings that make up the property that will be set.
+* @param {*} value - The value that will be set.
+* @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.
+*/
+Phaser.Group.prototype.setProperty = function (child, key, value, operation) {
+
+ operation = operation || 0;
+
+ // As ugly as this approach looks, and although it's limited to a depth of only 4, it's extremely fast.
+ // Much faster than a for loop or object iteration. There are no checks, so if the key isn't valid then it'll fail
+ // but as you are likely to call this from inner loops that have to perform well, I'll take that trade off.
+
+ // 0 = Equals
+ // 1 = Add
+ // 2 = Subtract
+ // 3 = Multiply
+ // 4 = Divide
+
+ var len = key.length;
+
+ if (len == 1)
+ {
+ if (operation === 0) { child[key[0]] = value; }
+ else if (operation == 1) { child[key[0]] += value; }
+ else if (operation == 2) { child[key[0]] -= value; }
+ else if (operation == 3) { child[key[0]] *= value; }
+ else if (operation == 4) { child[key[0]] /= value; }
+ }
+ else if (len == 2)
+ {
+ if (operation === 0) { child[key[0]][key[1]] = value; }
+ else if (operation == 1) { child[key[0]][key[1]] += value; }
+ else if (operation == 2) { child[key[0]][key[1]] -= value; }
+ else if (operation == 3) { child[key[0]][key[1]] *= value; }
+ else if (operation == 4) { child[key[0]][key[1]] /= value; }
+ }
+ else if (len == 3)
+ {
+ if (operation === 0) { child[key[0]][key[1]][key[2]] = value; }
+ else if (operation == 1) { child[key[0]][key[1]][key[2]] += value; }
+ else if (operation == 2) { child[key[0]][key[1]][key[2]] -= value; }
+ else if (operation == 3) { child[key[0]][key[1]][key[2]] *= value; }
+ else if (operation == 4) { child[key[0]][key[1]][key[2]] /= value; }
+ }
+ else if (len == 4)
+ {
+ if (operation === 0) { child[key[0]][key[1]][key[2]][key[3]] = value; }
+ else if (operation == 1) { child[key[0]][key[1]][key[2]][key[3]] += value; }
+ else if (operation == 2) { child[key[0]][key[1]][key[2]][key[3]] -= value; }
+ else if (operation == 3) { child[key[0]][key[1]][key[2]][key[3]] *= value; }
+ else if (operation == 4) { child[key[0]][key[1]][key[2]][key[3]] /= value; }
+ }
+
+}
+
+/**
+* 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.
+*/
+Phaser.Group.prototype.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.
+*
+* @method Phaser.Group#setAll
+* @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 only children with alive=true will be updated.
+* @param {boolean} [checkVisible=false] - If set then only children with visible=true will be updated.
+* @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.
+*/
+Phaser.Group.prototype.setAll = function (key, value, checkAlive, checkVisible, operation) {
+
+ key = key.split('.');
+
+ if (typeof checkAlive === 'undefined') { checkAlive = false; }
+ if (typeof checkVisible === 'undefined') { checkVisible = false; }
+
+ operation = operation || 0;
+
+ for (var i = 0, len = this.children.length; i < len; i++)
+ {
+ if ((!checkAlive || (checkAlive && this.children[i].alive)) && (!checkVisible || (checkVisible && this.children[i].visible)))
+ {
+ this.setProperty(this.children[i], key, value, operation);
+ }
+ }
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#addAll
+* @param {string} property - The property to increment, for example 'body.velocity.x' or 'angle'.
+* @param {number} amount - The amount to increment the property by. If child.x = 10 then addAll('x', 40) would make child.x = 50.
+* @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
+* @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
+*/
+Phaser.Group.prototype.addAll = function (property, amount, checkAlive, checkVisible) {
+
+ this.setAll(property, amount, checkAlive, checkVisible, 1);
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#subAll
+* @param {string} property - The property to decrement, for example 'body.velocity.x' or 'angle'.
+* @param {number} amount - The amount to subtract from the property. If child.x = 50 then subAll('x', 40) would make child.x = 10.
+* @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
+* @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
+*/
+Phaser.Group.prototype.subAll = function (property, amount, checkAlive, checkVisible) {
+
+ this.setAll(property, amount, checkAlive, checkVisible, 2);
+
+}
+
+/**
+* Multiplies the given property by the amount on all children in this Group.
+* Group.multiplyAll('x', 2) will x2 the child.x value.
+*
+* @method Phaser.Group#multiplyAll
+* @param {string} property - The property to multiply, for example 'body.velocity.x' or 'angle'.
+* @param {number} amount - The amount to multiply the property by. If child.x = 10 then multiplyAll('x', 2) would make child.x = 20.
+* @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
+* @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
+*/
+Phaser.Group.prototype.multiplyAll = function (property, amount, checkAlive, checkVisible) {
+
+ this.setAll(property, amount, checkAlive, checkVisible, 3);
+
+}
+
+/**
+* Divides the given property by the amount on all children in this Group.
+* Group.divideAll('x', 2) will half the child.x value.
+*
+* @method Phaser.Group#divideAll
+* @param {string} property - The property to divide, for example 'body.velocity.x' or 'angle'.
+* @param {number} amount - The amount to divide the property by. If child.x = 100 then divideAll('x', 2) would make child.x = 50.
+* @param {boolean} checkAlive - If true the property will only be changed if the child is alive.
+* @param {boolean} checkVisible - If true the property will only be changed if the child is visible.
+*/
+Phaser.Group.prototype.divideAll = function (property, amount, checkAlive, checkVisible) {
+
+ this.setAll(property, amount, checkAlive, checkVisible, 4);
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#callAllExists
+* @param {function} callback - The function that exists on the children that will be called.
+* @param {boolean} existsValue - Only children with exists=existsValue will be called.
+* @param {...*} parameter - Additional parameters that will be passed to the callback.
+*/
+Phaser.Group.prototype.callAllExists = function (callback, existsValue) {
+
+ var args = Array.prototype.splice.call(arguments, 2);
+
+ for (var i = 0, len = this.children.length; i < len; i++)
+ {
+ if (this.children[i].exists === existsValue && this.children[i][callback])
+ {
+ this.children[i][callback].apply(this.children[i], args);
+ }
+ }
+
+}
+
+/**
+* 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.
+* @param {array} callback - The array of function names.
+* @param {number} length - The size of the array (pre-calculated in callAll).
+* @protected
+*/
+Phaser.Group.prototype.callbackFromArray = function (child, callback, length) {
+
+ // Kinda looks like a Christmas tree
+
+ if (length == 1)
+ {
+ if (child[callback[0]])
+ {
+ return child[callback[0]];
+ }
+ }
+ else if (length == 2)
+ {
+ if (child[callback[0]][callback[1]])
+ {
+ return child[callback[0]][callback[1]];
+ }
+ }
+ else if (length == 3)
+ {
+ if (child[callback[0]][callback[1]][callback[2]])
+ {
+ return child[callback[0]][callback[1]][callback[2]];
+ }
+ }
+ else if (length == 4)
+ {
+ if (child[callback[0]][callback[1]][callback[2]][callback[3]])
+ {
+ return child[callback[0]][callback[1]][callback[2]][callback[3]];
+ }
+ }
+ else
+ {
+ if (child[callback])
+ {
+ return child[callback];
+ }
+ }
+
+ return false;
+
+}
+
+/**
+* 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.
+*
+* @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=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.
+*/
+Phaser.Group.prototype.callAll = function (method, context) {
+
+ if (typeof method === 'undefined')
+ {
+ return;
+ }
+
+ // Extract the method into an array
+ method = method.split('.');
+
+ var methodLength = method.length;
+
+ if (typeof context === 'undefined')
+ {
+ context = null;
+ }
+ else
+ {
+ // Extract the context into an array
+ if (typeof context === 'string')
+ {
+ context = context.split('.');
+ var contextLength = context.length;
+ }
+ }
+
+ var args = Array.prototype.splice.call(arguments, 2);
+ var callback = null;
+ var callbackContext = null;
+
+ for (var i = 0, len = this.children.length; i < len; i++)
+ {
+ callback = this.callbackFromArray(this.children[i], method, methodLength);
+
+ if (context && callback)
+ {
+ callbackContext = this.callbackFromArray(this.children[i], context, contextLength);
+
+ if (callback)
+ {
+ callback.apply(callbackContext, args);
+ }
+ }
+ else if (callback)
+ {
+ callback.apply(this.children[i], args);
+ }
+ }
+
+}
+
+/**
+* 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.
+* @param {Object} callbackContext - The context in which the function should be called (usually 'this').
+* @param {boolean} checkExists - If set only children with exists=true will be passed to the callback, otherwise all children will be passed.
+*/
+Phaser.Group.prototype.forEach = function (callback, callbackContext, checkExists) {
+
+ if (typeof checkExists === 'undefined')
+ {
+ checkExists = false;
+ }
+
+ var args = Array.prototype.splice.call(arguments, 3);
+ args.unshift(null);
+
+ for (var i = 0, len = this.children.length; i < len; i++)
+ {
+ if (!checkExists || (checkExists && this.children[i].exists))
+ {
+ args[0] = this.children[i];
+ callback.apply(callbackContext, args);
+ }
+ }
+
+}
+
+/**
+* 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)
+*
+* @method Phaser.Group#forEachAlive
+* @param {function} callback - The function that will be called. 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').
+*/
+Phaser.Group.prototype.forEachExists = function (callback, callbackContext) {
+
+ var args = Array.prototype.splice.call(arguments, 2);
+ args.unshift(null);
+
+ this.iterate('exists', true, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
+
+}
+
+/**
+* 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)
+*
+* @method Phaser.Group#forEachAlive
+* @param {function} callback - The function that will be called. 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').
+*/
+Phaser.Group.prototype.forEachAlive = function (callback, callbackContext) {
+
+ var args = Array.prototype.splice.call(arguments, 2);
+ args.unshift(null);
+
+ this.iterate('alive', true, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
+
+}
+
+/**
+* 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)
+*
+* @method Phaser.Group#forEachDead
+* @param {function} callback - The function that will be called. 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').
+*/
+Phaser.Group.prototype.forEachDead = function (callback, callbackContext) {
+
+ var args = Array.prototype.splice.call(arguments, 2);
+ args.unshift(null);
+
+ this.iterate('alive', false, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
+
+}
+
+/**
+* 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()`.
+*
+* @method Phaser.Group#sort
+* @param {string} [index='y'] - The `string` name of the property you want to sort on.
+* @param {number} [order=Phaser.Group.SORT_ASCENDING] - The `Group` constant that defines the sort order. Possible values are Phaser.Group.SORT_ASCENDING and Phaser.Group.SORT_DESCENDING.
+*/
+Phaser.Group.prototype.sort = function (index, order) {
+
+ if (typeof index === 'undefined') { index = 'y'; }
+ if (typeof order === 'undefined') { order = Phaser.Group.SORT_ASCENDING; }
+
+
+}
+
+Phaser.Group.prototype.sortHandler = function (a, b) {
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#iterate
+* @param {string} key - The child property to check, i.e. 'exists', 'alive', 'health'
+* @param {any} value - If child.key === this value it will be considered a match. Note that a strict comparison is used.
+* @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.
+*/
+Phaser.Group.prototype.iterate = function (key, value, returnType, callback, callbackContext, args) {
+
+ if (returnType === Phaser.Group.RETURN_TOTAL && this.children.length === 0)
+ {
+ return 0;
+ }
+
+ if (typeof callback === 'undefined')
+ {
+ callback = false;
+ }
+
+ var total = 0;
+
+ for (var i = 0, len = this.children.length; i < len; i++)
+ {
+ if (this.children[i][key] === value)
+ {
+ total++;
+
+ if (callback)
+ {
+ args[0] = this.children[i];
+ callback.apply(callbackContext, args);
+ }
+
+ if (returnType === Phaser.Group.RETURN_CHILD)
+ {
+ return this.children[i];
+ }
+ }
+ }
+
+ if (returnType === Phaser.Group.RETURN_TOTAL)
+ {
+ return total;
+ }
+ else if (returnType === Phaser.Group.RETURN_CHILD)
+ {
+ return null;
+ }
+
+}
+
+/**
+* Call this function to retrieve the first object with exists == (the given state) in the Group.
+*
+* @method Phaser.Group#getFirstExists
+* @param {boolean} state - True or false.
+* @return {Any} The first child, or null if none found.
+*/
+Phaser.Group.prototype.getFirstExists = function (state) {
+
+ if (typeof state !== 'boolean')
+ {
+ state = true;
+ }
+
+ return this.iterate('exists', state, Phaser.Group.RETURN_CHILD);
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#getFirstAlive
+* @return {Any} The first alive child, or null if none found.
+*/
+Phaser.Group.prototype.getFirstAlive = function () {
+
+ return this.iterate('alive', true, Phaser.Group.RETURN_CHILD);
+
+}
+
+/**
+* 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.
+*
+* @method Phaser.Group#getFirstDead
+* @return {Any} The first dead child, or null if none found.
+*/
+Phaser.Group.prototype.getFirstDead = function () {
+
+ return this.iterate('alive', false, Phaser.Group.RETURN_CHILD);
+
+}
+
+/**
+* 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.
+*/
+Phaser.Group.prototype.countLiving = function () {
+
+ return this.iterate('alive', true, Phaser.Group.RETURN_TOTAL);
+
+}
+
+/**
+* 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.
+*/
+Phaser.Group.prototype.countDead = function () {
+
+ return this.iterate('alive', false, Phaser.Group.RETURN_TOTAL);
+
+}
+
+/**
+* Returns a member at random from the group.
+*
+* @method Phaser.Group#getRandom
+* @param {number} startIndex - Optional offset off the front of the array. Default value is 0, or the beginning of the array.
+* @param {number} length - Optional restriction on the number of values you want to randomly select from.
+* @return {Any} A random child of this Group.
+*/
+Phaser.Group.prototype.getRandom = function (startIndex, length) {
+
+ if (this.children.length === 0)
+ {
+ return null;
+ }
+
+ startIndex = startIndex || 0;
+ length = length || this.children.length;
+
+ return this.game.math.getRandom(this.children, startIndex, length);
+
+}
+
+/**
+* Removes the given child from this Group and sets its group property to null.
+*
+* @method Phaser.Group#remove
+* @param {Any} child - The child to remove.
+* @return {boolean} true if the child was removed from this Group, otherwise false.
+*/
+Phaser.Group.prototype.remove = function (child) {
+
+ if (this.children.length === 0)
+ {
+ return;
+ }
+
+ if (child.events)
+ {
+ child.events.onRemovedFromGroup.dispatch(child, this);
+ }
+
+ this.removeChild(child);
+
+ if (this.cursor === child)
+ {
+ this.next();
+ }
+
+ return true;
+
+}
+
+/**
+* Removes all children from this Group, setting all group properties to null.
+* The Group container remains on the display list.
+*
+* @method Phaser.Group#removeAll
+*/
+Phaser.Group.prototype.removeAll = function () {
+
+ if (this.children.length === 0)
+ {
+ return;
+ }
+
+ do
+ {
+ if (this.children[0].events)
+ {
+ this.children[0].events.onRemovedFromGroup.dispatch(this.children[0], this);
+ }
+
+ this.removeChild(this.children[0]);
+ }
+ while (this.children.length > 0);
+
+ this.cursor = null;
+
+}
+
+/**
+* Removes all children from this Group whos index falls beteen the given startIndex and endIndex values.
+*
+* @method Phaser.Group#removeBetween
+* @param {number} startIndex - The index to start removing children from.
+* @param {number} endIndex - The index to stop removing children from. Must be higher than startIndex and less than the length of the Group.
+*/
+Phaser.Group.prototype.removeBetween = function (startIndex, endIndex) {
+
+ if (this.children.length === 0)
+ {
+ return;
+ }
+
+ if (startIndex > endIndex || startIndex < 0 || endIndex > this.children.length)
+ {
+ return false;
+ }
+
+ for (var i = startIndex; i < endIndex; i++)
+ {
+ if (this.children[i].events)
+ {
+ this.children[i].events.onRemovedFromGroup.dispatch(this.children[i], this);
+ }
+
+ this.removeChild(this.children[i]);
+
+ if (this.cursor === child)
+ {
+ this.cursor = null;
+ }
+ }
+
+}
+
+/**
+* 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?
+*/
+Phaser.Group.prototype.destroy = function (destroyChildren) {
+
+ if (typeof destroyChildren === 'undefined') { destroyChildren = false; }
+
+ if (destroyChildren)
+ {
+ if (this.children.length > 0)
+ {
+ do
+ {
+ if (this.children[0].group)
+ {
+ this.children[0].destroy();
+ }
+ }
+ while (this.children.length > 0);
+ }
+ }
+ else
+ {
+ this.removeAll();
+ }
+
+ this.parent.removeChild(this);
+
+ this.game = null;
+
+ this.exists = false;
+
+ this.cursor = null;
+
+}
/**
* @name Phaser.Group#total
@@ -1884,14 +1550,7 @@ Object.defineProperty(Phaser.Group.prototype, "total", {
get: function () {
- if (this._container)
- {
- return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
- }
- else
- {
- return 0;
- }
+ return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
}
@@ -1906,55 +1565,12 @@ Object.defineProperty(Phaser.Group.prototype, "length", {
get: function () {
- if (this._container)
- {
- return this._container.children.length;
- }
- else
- {
- return 0;
- }
+ return this.children.length;
}
});
-/**
-* 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.
-* @name Phaser.Group#x
-* @property {number} x - The x coordinate of the Group container.
-*/
-Object.defineProperty(Phaser.Group.prototype, "x", {
-
- get: function () {
- return this._container.position.x;
- },
-
- set: function (value) {
- this._container.position.x = value;
- }
-
-});
-
-/**
-* 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.
-* @name Phaser.Group#y
-* @property {number} y - The y coordinate of the Group container.
-*/
-Object.defineProperty(Phaser.Group.prototype, "y", {
-
- get: function () {
- return this._container.position.y;
- },
-
- set: function (value) {
- this._container.position.y = value;
- }
-
-});
-
/**
* 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.
@@ -1964,64 +1580,47 @@ Object.defineProperty(Phaser.Group.prototype, "y", {
Object.defineProperty(Phaser.Group.prototype, "angle", {
get: function() {
- return Phaser.Math.radToDeg(this._container.rotation);
+ return Phaser.Math.radToDeg(this.rotation);
},
set: function(value) {
- this._container.rotation = Phaser.Math.degToRad(value);
+ this.rotation = Phaser.Math.degToRad(value);
}
});
+// Documentation stubs
+
+/**
+* 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.
+* @name Phaser.Group#x
+* @property {number} x - The x coordinate of the Group container.
+*/
+
+/**
+* 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.
+* @name Phaser.Group#y
+* @property {number} y - The y coordinate of the Group container.
+*/
+
/**
* 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.
* @name Phaser.Group#rotation
* @property {number} rotation - The angle of rotation given in radians.
*/
-Object.defineProperty(Phaser.Group.prototype, "rotation", {
-
- get: function () {
- return this._container.rotation;
- },
-
- set: function (value) {
- this._container.rotation = value;
- }
-
-});
/**
* @name Phaser.Group#visible
* @property {boolean} visible - The visible state of the Group. Non-visible Groups and all of their children are not rendered.
*/
-Object.defineProperty(Phaser.Group.prototype, "visible", {
-
- get: function () {
- return this._container.visible;
- },
-
- set: function (value) {
- this._container.visible = value;
- }
-
-});
/**
* @name Phaser.Group#alpha
* @property {number} alpha - The alpha value of the Group container.
*/
-Object.defineProperty(Phaser.Group.prototype, "alpha", {
-
- get: function () {
- return this._container.alpha;
- },
-
- set: function (value) {
- this._container.alpha = value;
- }
-
-});
@@ -2043,7 +1642,7 @@ Object.defineProperty(Phaser.Group.prototype, "alpha", {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Image.js.html b/docs/Image.js.html
new file mode 100644
index 00000000..30345ec0
--- /dev/null
+++ b/docs/Image.js.html
@@ -0,0 +1,1144 @@
+
+
+
+
+
+ Phaser Source: gameobjects/Image.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}
+*/
+
+/**
+* @class Phaser.Image
+*
+* @classdesc Create a new `Image` object. An Image is a light-weight object you can use to display anything that doesn't need physics or animation.
+* It can still rotate, scale, crop and receive input events. This makes it perfect for logos, backgrounds, simple buttons and other non-Sprite graphics.
+*
+* @constructor
+* @param {Phaser.Game} game - A reference to the currently running game.
+* @param {number} x - The x coordinate of the Imaget. The coordinate is relative to any parent container this Image may be in.
+* @param {number} y - The y coordinate of the Image. The coordinate is relative to any parent container this Image may be in.
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|PIXI.Texture} key - The texture used by the Image during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture, BitmapData or PIXI.Texture.
+* @param {string|number} frame - If this Image 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.Image = function (game, x, y, key, frame) {
+
+ x = x || 0;
+ y = y || 0;
+ key = key || null;
+ frame = frame || null;
+
+ /**
+ * @property {Phaser.Game} game - A reference to the currently running Game.
+ */
+ this.game = game;
+
+ /**
+ * @property {boolean} exists - If exists = false then the Sprite isn't updated by the core game loop or physics subsystem at all.
+ * @default
+ */
+ this.exists = true;
+
+ /**
+ * @property {string} name - The user defined name given to this Sprite.
+ * @default
+ */
+ this.name = '';
+
+ /**
+ * @property {number} type - The const type of this object.
+ * @readonly
+ */
+ this.type = Phaser.IMAGE;
+
+ /**
+ * @property {Phaser.Events} events - The Events you can subscribe to that are dispatched when certain things happen on this Sprite or its components.
+ */
+ this.events = new Phaser.Events(this);
+
+ /**
+ * @property {string|Phaser.RenderTexture|Phaser.BitmapData|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, BitmapData or PIXI.Texture.
+ */
+ this.key = key;
+
+ this._frame = 0;
+ this._frameName = '';
+
+ PIXI.Sprite.call(this, PIXI.TextureCache['__default']);
+
+ this.loadTexture(key, frame);
+
+ this.position.set(x, y);
+
+ /**
+ * @property {Phaser.Point} world - The world coordinates of this Sprite. This differs from the x/y coordinates which are relative to the Sprites container.
+ */
+ this.world = new Phaser.Point(x, y);
+
+ /**
+ * Should this Sprite be automatically culled if out of range of the camera?
+ * A culled sprite has its renderable property set to 'false'.
+ * Be advised this is quite an expensive operation, as it has to calculate the bounds of the object every frame, so only enable it if you really need it.
+ *
+ * @property {boolean} autoCull - A flag indicating if the Sprite should be automatically camera culled or not.
+ * @default
+ */
+ this.autoCull = false;
+
+ /**
+ * A Sprite that is fixed to the camera uses its x/y coordinates as offsets from the top left of the camera.
+ * Note that if this Image is a child of a display object that has changed its position then the offset will be calculated from that.
+ * @property {boolean} fixedToCamera - Fixes this Sprite to the Camera.
+ * @default
+ */
+ this.fixedToCamera = false;
+
+ /**
+ * @property {Phaser.InputHandler|null} input - The Input Handler for this object. Needs to be enabled with image.inputEnabled = true before you can use it.
+ */
+ this.input = null;
+
+ /**
+ * @property {array} _cache - A small cache for previous step values. 0 = x, 1 = y, 2 = rotation, 3 = renderID
+ * @private
+ */
+ this._cache = [0, 0, 0, 0];
+
+};
+
+Phaser.Image.prototype = Object.create(PIXI.Sprite.prototype);
+Phaser.Image.prototype.constructor = Phaser.Image;
+
+/**
+* Automatically called by World.preUpdate.
+*
+* @method Phaser.Image#preUpdate
+* @memberof Phaser.Image
+*/
+Phaser.Image.prototype.preUpdate = function() {
+
+ this._cache[0] = this.world.x;
+ this._cache[1] = this.world.y;
+ this._cache[2] = this.rotation;
+
+ if (!this.exists || !this.parent.exists)
+ {
+ this.renderOrderID = -1;
+ return false;
+ }
+
+ if (this.autoCull)
+ {
+ // Won't get rendered but will still get its transform updated
+ this.renderable = this.game.world.camera.screenView.intersects(this.getBounds());
+ }
+
+ this.world.setTo(this.game.camera.x + this.worldTransform[2], this.game.camera.y + this.worldTransform[5]);
+
+ if (this.visible)
+ {
+ this._cache[3] = this.game.world.currentRenderOrderID++;
+ }
+
+ return true;
+
+};
+
+/**
+* Internal function called by the World postUpdate cycle.
+*
+* @method Phaser.Image#postUpdate
+* @memberof Phaser.Image
+*/
+Phaser.Image.prototype.postUpdate = function() {
+
+ if (this.key instanceof Phaser.BitmapData && this.key._dirty)
+ {
+ this.key.render();
+ }
+
+ if (this.fixedToCamera)
+ {
+ this.position.x = this.game.camera.view.x + this.x;
+ this.position.y = this.game.camera.view.y + this.y;
+ }
+
+};
+
+/**
+* Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
+* This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
+*
+* @method Phaser.Image#loadTexture
+* @memberof Phaser.Image
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|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, BitmapData 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.Image.prototype.loadTexture = function (key, frame) {
+
+ frame = frame || 0;
+
+ if (key instanceof Phaser.RenderTexture)
+ {
+ this.key = key.key;
+ this.setTexture(key);
+ }
+ else if (key instanceof Phaser.BitmapData)
+ {
+ this.key = key.key;
+ this.setTexture(key.texture);
+ }
+ else if (key instanceof PIXI.Texture)
+ {
+ this.key = key;
+ this.setTexture(key);
+ }
+ else
+ {
+ if (key === null || typeof key === 'undefined')
+ {
+ this.key = '__default';
+ this.setTexture(PIXI.TextureCache[this.key]);
+ }
+ else if (typeof key === 'string' && !this.game.cache.checkImageKey(key))
+ {
+ this.key = '__missing';
+ this.setTexture(PIXI.TextureCache[this.key]);
+ }
+
+ if (this.game.cache.isSpriteSheet(key))
+ {
+ this.key = key;
+
+ var frameData = this.game.cache.getFrameData(key);
+
+ if (typeof frame === 'string')
+ {
+ this._frame = 0;
+ this._frameName = frame;
+ this.setTexture(PIXI.TextureCache[frameData.getFrameByName(frame).uuid]);
+ }
+ else
+ {
+ this._frame = frame;
+ this._frameName = '';
+ this.setTexture(PIXI.TextureCache[frameData.getFrame(frame).uuid]);
+ }
+ }
+ else
+ {
+ this.key = key;
+ this.setTexture(PIXI.TextureCache[key]);
+ }
+ }
+
+};
+
+/**
+* Crop allows you to crop the texture used to display this Image.
+* Cropping takes place from the top-left of the Image and can be modified in real-time by providing an updated rectangle object.
+*
+* @method Phaser.Image#crop
+* @memberof Phaser.Image
+* @param {Phaser.Rectangle} rect - The Rectangle to crop the Image to. Pass null or no parameters to clear a previously set crop rectangle.
+*/
+Phaser.Image.prototype.crop = function(rect) {
+
+ if (typeof rect === 'undefined' || rect === null)
+ {
+ // Clear any crop that may be set
+ if (this.texture.hasOwnProperty('sourceWidth'))
+ {
+ this.texture.setFrame(new Phaser.Rectangle(0, 0, this.texture.sourceWidth, this.texture.sourceHeight));
+ }
+ }
+ else
+ {
+ // Do we need to clone the PIXI.Texture object?
+ if (this.texture instanceof PIXI.Texture)
+ {
+ // Yup, let's rock it ...
+ var local = {};
+
+ Phaser.Utils.extend(true, local, this.texture);
+
+ local.sourceWidth = local.width;
+ local.sourceHeight = local.height;
+ local.frame = rect;
+ local.width = rect.width;
+ local.height = rect.height;
+
+ this.texture = local;
+
+ this.texture.updateFrame = true;
+ PIXI.Texture.frameUpdates.push(this.texture);
+ }
+ else
+ {
+ this.texture.setFrame(rect);
+ }
+ }
+
+};
+
+/**
+* Brings a 'dead' Sprite back to life, optionally giving it the health value specified.
+* A resurrected Sprite has its alive, exists and visible properties all set to true.
+* It will dispatch the onRevived event, you can listen to Sprite.events.onRevived for the signal.
+*
+* @method Phaser.Image#revive
+* @memberof Phaser.Image
+* @return {Phaser.Image} This instance.
+*/
+Phaser.Image.prototype.revive = function() {
+
+ this.alive = true;
+ this.exists = true;
+ this.visible = true;
+
+ if (this.events)
+ {
+ this.events.onRevived.dispatch(this);
+ }
+
+ return this;
+
+};
+
+/**
+* Kills a Sprite. A killed Sprite has its alive, exists and visible properties all set to false.
+* It will dispatch the onKilled event, you can listen to Sprite.events.onKilled for the signal.
+* Note that killing a Sprite is a way for you to quickly recycle it in a Sprite pool, it doesn't free it up from memory.
+* If you don't need this Sprite any more you should call Sprite.destroy instead.
+*
+* @method Phaser.Image#kill
+* @memberof Phaser.Image
+* @return {Phaser.Image} This instance.
+*/
+Phaser.Image.prototype.kill = function() {
+
+ this.alive = false;
+ this.exists = false;
+ this.visible = false;
+
+ if (this.events)
+ {
+ this.events.onKilled.dispatch(this);
+ }
+
+ return this;
+
+};
+
+/**
+* Destroys the Sprite. This removes it from its parent group, destroys the input, event and animation handlers if present
+* and nulls its reference to game, freeing it up for garbage collection.
+*
+* @method Phaser.Image#destroy
+* @memberof Phaser.Image
+*/
+Phaser.Image.prototype.destroy = function() {
+
+ if (this.filters)
+ {
+ this.filters = null;
+ }
+
+ if (this.parent)
+ {
+ this.parent.remove(this);
+ }
+
+ if (this.events)
+ {
+ this.events.destroy();
+ }
+
+ if (this.input)
+ {
+ this.input.destroy();
+ }
+
+ this.alive = false;
+ this.exists = false;
+ this.visible = false;
+
+ this.game = null;
+
+};
+
+/**
+* Resets the Sprite. This places the Sprite at the given x/y world coordinates and then sets alive, exists, visible and renderable all to true.
+*
+* @method Phaser.Image#reset
+* @memberof Phaser.Image
+* @param {number} x - The x coordinate (in world space) to position the Sprite at.
+* @param {number} y - The y coordinate (in world space) to position the Sprite at.
+* @return {Phaser.Image} This instance.
+*/
+Phaser.Image.prototype.reset = function(x, y) {
+
+ this.world.setTo(x, y);
+ this.position.x = x;
+ this.position.y = y;
+ this.alive = true;
+ this.exists = true;
+ this.visible = true;
+ this.renderable = true;
+
+ return this;
+
+};
+
+/**
+* Brings the Sprite to the top of the display list it is a child of. Sprites that are members of a Phaser.Group are only
+* bought to the top of that Group, not the entire display list.
+*
+* @method Phaser.Image#bringToTop
+* @memberof Phaser.Image
+* @return {Phaser.Image} This instance.
+*/
+Phaser.Image.prototype.bringToTop = function(child) {
+
+ if (typeof child === 'undefined')
+ {
+ if (this.parent)
+ {
+ this.parent.bringToTop(this);
+ }
+ }
+ else
+ {
+
+ }
+
+ return this;
+
+};
+
+/**
+* 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. Working in radians is also a little faster as it doesn't have to convert the angle.
+*
+* @name Phaser.Image#angle
+* @property {number} angle - The angle of this Image in degrees.
+*/
+Object.defineProperty(Phaser.Image.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));
+
+ }
+
+});
+
+/**
+* Returns the delta x value. The difference between world.x now and in the previous step.
+*
+* @name Phaser.Image#deltaX
+* @property {number} deltaX - The delta value. Positive if the motion was to the right, negative if to the left.
+* @readonly
+*/
+Object.defineProperty(Phaser.Image.prototype, "deltaX", {
+
+ get: function() {
+
+ return this.world.x - this._cache[0];
+
+ }
+
+});
+
+/**
+* Returns the delta y value. The difference between world.y now and in the previous step.
+*
+* @name Phaser.Image#deltaY
+* @property {number} deltaY - The delta value. Positive if the motion was downwards, negative if upwards.
+* @readonly
+*/
+Object.defineProperty(Phaser.Image.prototype, "deltaY", {
+
+ get: function() {
+
+ return this.world.y - this._cache[1];
+
+ }
+
+});
+
+/**
+* Returns the delta z value. The difference between rotation now and in the previous step.
+*
+* @name Phaser.Image#deltaZ
+* @property {number} deltaZ - The delta value.
+* @readonly
+*/
+Object.defineProperty(Phaser.Image.prototype, "deltaZ", {
+
+ get: function() {
+
+ return this.rotation - this._cache[2];
+
+ }
+
+});
+
+/**
+* Checks if the Image bounds are within the game world, otherwise false if fully outside of it.
+*
+* @name Phaser.Image#inWorld
+* @property {boolean} inWorld - True if the Image bounds is within the game world, even if only partially. Otherwise false if fully outside of it.
+* @readonly
+*/
+Object.defineProperty(Phaser.Image.prototype, "inWorld", {
+
+ get: function() {
+
+ return this.game.world.bounds.intersects(this.getBounds());
+
+ }
+
+});
+
+/**
+* Checks if the Image bounds are within the game camera, otherwise false if fully outside of it.
+*
+* @name Phaser.Image#inCamera
+* @property {boolean} inCamera - True if the Image bounds is within the game camera, even if only partially. Otherwise false if fully outside of it.
+* @readonly
+*/
+Object.defineProperty(Phaser.Image.prototype, "inCamera", {
+
+ get: function() {
+
+ return this.game.world.camera.screenView.intersects(this.getBounds());
+
+ }
+
+});
+
+/**
+* @name Phaser.Image#frame
+* @property {number} frame - Gets or sets the current frame index and updates the Texture for display.
+*/
+Object.defineProperty(Phaser.Image.prototype, "frame", {
+
+ get: function() {
+
+ return this._frame;
+
+ },
+
+ set: function(value) {
+
+ if (value !== this.frame && this.game.cache.isSpriteSheet(this.key))
+ {
+ var frameData = this.game.cache.getFrameData(this.key);
+
+ if (frameData && value < frameData.total && frameData.getFrame(value))
+ {
+ this.setTexture(PIXI.TextureCache[frameData.getFrame(value).uuid]);
+ this._frame = value;
+ }
+ }
+
+ }
+
+});
+
+/**
+* @name Phaser.Image#frameName
+* @property {string} frameName - Gets or sets the current frame by name and updates the Texture for display.
+*/
+Object.defineProperty(Phaser.Image.prototype, "frameName", {
+
+ get: function() {
+
+ return this._frameName;
+
+ },
+
+ set: function(value) {
+
+ if (value !== this.frameName && this.game.cache.isSpriteSheet(this.key))
+ {
+ var frameData = this.game.cache.getFrameData(this.key);
+
+ if (frameData && frameData.getFrameByName(value))
+ {
+ this.setTexture(PIXI.TextureCache[frameData.getFrameByName(value).uuid]);
+ this._frameName = value;
+ }
+ }
+
+ }
+
+});
+
+/**
+* @name Phaser.Image#renderOrderID
+* @property {number} renderOrderID - The render order ID, reset every frame.
+* @readonly
+*/
+Object.defineProperty(Phaser.Image.prototype, "renderOrderID", {
+
+ get: function() {
+
+ return this._cache[3];
+
+ }
+
+});
+
+/**
+* By default an Image won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is
+* activated for this object and it will then start to process click/touch events and more.
+*
+* @name Phaser.Image#inputEnabled
+* @property {boolean} inputEnabled - Set to true to allow this object to receive input events.
+*/
+Object.defineProperty(Phaser.Image.prototype, "inputEnabled", {
+
+ get: function () {
+
+ return (this.input && this.input.enabled);
+
+ },
+
+ set: function (value) {
+
+ if (value)
+ {
+ if (this.input === null)
+ {
+ this.input = new Phaser.InputHandler(this);
+ this.input.start();
+ }
+ }
+ else
+ {
+ if (this.input && this.input.enabled)
+ {
+ this.input.stop();
+ }
+ }
+ }
+
+});
+
+
@@ -457,6 +491,257 @@ Phaser.Input = function (game) {
* @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;
+
+ /**
+ * @property {number} pollRate - How often should the input pointers be checked for updates? A value of 0 means every single frame (60fps); a value of 1 means every other frame (30fps) and so on.
+ * @default
+ */
+ this.pollRate = 0;
+
+ /**
+ * @property {number} _pollCounter - Internal var holding the current poll counter.
+ * @private
+ */
+ this._pollCounter = 0;
+
+ /**
+ * @property {Phaser.Point} _oldPosition - A point object representing the previous position of the Pointer.
+ * @private
+ */
+ this._oldPosition = null;
+
+ /**
+ * @property {number} _x - x coordinate of the most recent Pointer event
+ * @private
+ */
+ this._x = 0;
+
+ /**
+ * @property {number} _y - Y coordinate of the most recent Pointer event
+ * @private
+ */
+ this._y = 0;
+
+ /**
+ * You can disable all Input by setting Input.disabled = true. While set all new input related events will be ignored.
+ * If you need to disable just one type of input; for example mouse; use Input.mouse.disabled = true instead
+ * @property {boolean} disabled
+ * @default
+ */
+ this.disabled = false;
+
+ /**
+ * @property {number} multiInputOverride - Controls the expected behaviour when using a mouse and touch together on a multi-input device.
+ * @default
+ */
+ this.multiInputOverride = Phaser.Input.MOUSE_TOUCH_COMBINE;
+
+ /**
+ * @property {Phaser.Point} position - A point object representing the current position of the Pointer.
+ * @default
+ */
+ this.position = null;
+
+ /**
+ * @property {Phaser.Point} speed - A point object representing the speed of the Pointer. Only really useful in single Pointer games; otherwise see the Pointer objects directly.
+ */
+ this.speed = null;
+
+ /**
+ * A Circle object centered on the x/y screen coordinates of the Input.
+ * Default size of 44px (Apples recommended "finger tip" size) but can be changed to anything.
+ * @property {Phaser.Circle} circle
+ */
+ this.circle = null;
+
+ /**
+ * @property {Phaser.Point} scale - The scale by which all input coordinates are multiplied; calculated by the StageScaleMode. In an un-scaled game the values will be x = 1 and y = 1.
+ */
+ this.scale = null;
+
+ /**
+ * @property {number} maxPointers - The maximum number of Pointers allowed to be active at any one time. For lots of games it's useful to set this to 1.
+ * @default
+ */
+ this.maxPointers = 10;
+
+ /**
+ * @property {number} currentPointers - The current number of active Pointers.
+ * @default
+ */
+ this.currentPointers = 0;
+
+ /**
+ * @property {number} tapRate - The number of milliseconds that the Pointer has to be pressed down and then released to be considered a tap or click.
+ * @default
+ */
+ this.tapRate = 200;
+
+ /**
+ * @property {number} doubleTapRate - The number of milliseconds between taps of the same Pointer for it to be considered a double tap / click.
+ * @default
+ */
+ this.doubleTapRate = 300;
+
+ /**
+ * @property {number} holdRate - The number of milliseconds that the Pointer has to be pressed down for it to fire a onHold event.
+ * @default
+ */
+ this.holdRate = 2000;
+
+ /**
+ * @property {number} justPressedRate - The number of milliseconds below which the Pointer is considered justPressed.
+ * @default
+ */
+ this.justPressedRate = 200;
+
+ /**
+ * @property {number} justReleasedRate - The number of milliseconds below which the Pointer is considered justReleased .
+ * @default
+ */
+ this.justReleasedRate = 200;
+
+ /**
+ * Sets if the Pointer objects should record a history of x/y coordinates they have passed through.
+ * The history is cleared each time the Pointer is pressed down.
+ * The history is updated at the rate specified in Input.pollRate
+ * @property {boolean} recordPointerHistory
+ * @default
+ */
+ this.recordPointerHistory = false;
+
+ /**
+ * @property {number} recordRate - The rate in milliseconds at which the Pointer objects should update their tracking history.
+ * @default
+ */
+ this.recordRate = 100;
+
+ /**
+ * The total number of entries that can be recorded into the Pointer objects tracking history.
+ * If the Pointer is tracking one event every 100ms; then a trackLimit of 100 would store the last 10 seconds worth of history.
+ * @property {number} recordLimit
+ * @default
+ */
+ this.recordLimit = 100;
+
+ /**
+ * @property {Phaser.Pointer} pointer1 - A Pointer object.
+ */
+ this.pointer1 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer2 - A Pointer object.
+ */
+ this.pointer2 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer3 - A Pointer object.
+ */
+ this.pointer3 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer4 - A Pointer object.
+ */
+ this.pointer4 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer5 - A Pointer object.
+ */
+ this.pointer5 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer6 - A Pointer object.
+ */
+ this.pointer6 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer7 - A Pointer object.
+ */
+ this.pointer7 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer8 - A Pointer object.
+ */
+ this.pointer8 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer9 - A Pointer object.
+ */
+ this.pointer9 = null;
+
+ /**
+ * @property {Phaser.Pointer} pointer10 - A Pointer object.
+ */
+ this.pointer10 = null;
+
+ /**
+ * The most recently active Pointer object.
+ * When you've limited max pointers to 1 this will accurately be either the first finger touched or mouse.
+ * @property {Phaser.Pointer} activePointer
+ */
+ this.activePointer = null;
+
+ /**
+ * @property {Pointer} mousePointer - The mouse has its own unique Phaser.Pointer object which you can use if making a desktop specific game.
+ */
+ this.mousePointer = null;
+
+ /**
+ * @property {Phaser.Mouse} mouse - The Mouse Input manager.
+ */
+ this.mouse = null;
+
+ /**
+ * @property {Phaser.Keyboard} keyboard - The Keyboard Input manager.
+ */
+ this.keyboard = null;
+
+ /**
+ * @property {Phaser.Touch} touch - the Touch Input manager.
+ */
+ this.touch = null;
+
+ /**
+ * @property {Phaser.MSPointer} mspointer - The MSPointer Input manager.
+ */
+ this.mspointer = null;
+
+ /**
+ * @property {Phaser.Gamepad} gamepad - The Gamepad Input manager.
+ */
+ this.gamepad = null;
+
+ /**
+ * @property {Phaser.Signal} onDown - A Signal that is dispatched each time a pointer is pressed down.
+ */
+ this.onDown = null;
+
+ /**
+ * @property {Phaser.Signal} onUp - A Signal that is dispatched each time a pointer is released.
+ */
+ this.onUp = null;
+
+ /**
+ * @property {Phaser.Signal} onTap - A Signal that is dispatched each time a pointer is tapped.
+ */
+ this.onTap = null;
+
+ /**
+ * @property {Phaser.Signal} onHold - A Signal that is dispatched each time a pointer is held down.
+ */
+ this.onHold = null;
+
+ /**
+ * A linked list of interactive objects; the InputHandler components (belonging to Sprites) register themselves with this.
+ * @property {Phaser.LinkedList} interactiveItems
+ */
+ this.interactiveItems = new Phaser.LinkedList();
+
+ /**
+ * @property {Phaser.Point} _localPoint - Internal cache var.
+ * @private
+ */
+ this._localPoint = new Phaser.Point();
};
@@ -480,300 +765,6 @@ Phaser.Input.MOUSE_TOUCH_COMBINE = 2;
Phaser.Input.prototype = {
- /**
- * How often should the input pointers be checked for updates?
- * A value of 0 means every single frame (60fps), a value of 1 means every other frame (30fps) and so on.
- * @property {number} pollRate
- * @default
- */
- pollRate: 0,
-
- /**
- * @property {number} _pollCounter - Internal var holding the current poll counter.
- * @private
- * @default
- */
- _pollCounter: 0,
-
- /**
- * @property {Phaser.Point} _oldPosition - A point object representing the previous position of the Pointer.
- * @private
- * @default
- */
- _oldPosition: null,
-
- /**
- * @property {number} _x - x coordinate of the most recent Pointer event
- * @private
- * @default
- */
- _x: 0,
-
- /**
- * @property {number} _y - Y coordinate of the most recent Pointer event
- * @private
- * @default
- */
- _y: 0,
-
- /**
- * You can disable all Input by setting Input.disabled: true. While set all new input related events will be ignored.
- * If you need to disable just one type of input, for example mouse, use Input.mouse.disabled: true instead
- * @property {boolean} disabled
- * @default
- */
- disabled: false,
-
- /**
- * Controls the expected behaviour when using a mouse and touch together on a multi-input device.
- * @property {Description} multiInputOverride
- */
- multiInputOverride: Phaser.Input.MOUSE_TOUCH_COMBINE,
-
- /**
- * @property {Phaser.Point} position - A point object representing the current position of the Pointer.
- * @default
- */
- position: null,
-
- /**
- * A point object representing the speed of the Pointer. Only really useful in single Pointer games, otherwise see the Pointer objects directly.
- * @property {Phaser.Point} speed
- */
- speed: null,
-
- /**
- * A Circle object centered on the x/y screen coordinates of the Input.
- * Default size of 44px (Apples recommended "finger tip" size) but can be changed to anything.
- * @property {Phaser.Circle} circle
- */
- circle: null,
-
- /**
- * The scale by which all input coordinates are multiplied, calculated by the StageScaleMode.
- * In an un-scaled game the values will be x: 1 and y: 1.
- * @property {Phaser.Point} scale
- */
- scale: null,
-
- /**
- * The maximum number of Pointers allowed to be active at any one time.
- * For lots of games it's useful to set this to 1.
- * @property {number} maxPointers
- * @default
- */
- maxPointers: 10,
-
- /**
- * The current number of active Pointers.
- * @property {number} currentPointers
- * @default
- */
- currentPointers: 0,
-
- /**
- * The number of milliseconds that the Pointer has to be pressed down and then released to be considered a tap or clicke
- * @property {number} tapRate
- * @default
- */
- tapRate: 200,
-
- /**
- * The number of milliseconds between taps of the same Pointer for it to be considered a double tap / click
- * @property {number} doubleTapRate
- * @default
- */
- doubleTapRate: 300,
-
- /**
- * The number of milliseconds that the Pointer has to be pressed down for it to fire a onHold event
- * @property {number} holdRate
- * @default
- */
- holdRate: 2000,
-
- /**
- * The number of milliseconds below which the Pointer is considered justPressed
- * @property {number} justPressedRate
- * @default
- */
- justPressedRate: 200,
-
- /**
- * The number of milliseconds below which the Pointer is considered justReleased
- * @property {number} justReleasedRate
- * @default
- */
- justReleasedRate: 200,
-
- /**
- * Sets if the Pointer objects should record a history of x/y coordinates they have passed through.
- * The history is cleared each time the Pointer is pressed down.
- * The history is updated at the rate specified in Input.pollRate
- * @property {boolean} recordPointerHistory
- * @default
- */
- recordPointerHistory: false,
-
- /**
- * The rate in milliseconds at which the Pointer objects should update their tracking history
- * @property {number} recordRate
- * @default
- */
- recordRate: 100,
-
- /**
- * The total number of entries that can be recorded into the Pointer objects tracking history.
- * If the Pointer is tracking one event every 100ms, then a trackLimit of 100 would store the last 10 seconds worth of history.
- * @property {number} recordLimit
- * @default
- */
- recordLimit: 100,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer1
- */
- pointer1: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer2
- */
- pointer2: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer3
- */
- pointer3: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer4
- */
- pointer4: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer5
- */
- pointer5: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer6
- */
- pointer6: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer7
- */
- pointer7: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer8
- */
- pointer8: null,
-
- /**
- * A Pointer object
- * @property {Phaser.Pointer} pointer9
- */
- pointer9: null,
-
- /**
- * A Pointer object.
- * @property {Phaser.Pointer} pointer10
- */
- pointer10: null,
-
- /**
- * The most recently active Pointer object.
- * When you've limited max pointers to 1 this will accurately be either the first finger touched or mouse.
- * @property {Phaser.Pointer} activePointer
- * @default
- */
- activePointer: null,
-
- /**
- * The mouse has its own unique Phaser.Pointer object which you can use if making a desktop specific game.
- * @property {Pointer} mousePointer
- * @default
- */
- mousePointer: null,
-
- /**
- * The Mouse Input manager.
- * @property {Phaser.Mouse} mouse - The Mouse Input manager.
- * @default
- */
- mouse: null,
-
- /**
- * The Keyboard Input manager.
- * @property {Phaser.Keyboard} keyboard - The Keyboard Input manager.
- * @default
- */
- keyboard: null,
-
- /**
- * The Touch Input manager.
- * @property {Phaser.Touch} touch - the Touch Input manager.
- * @default
- */
- touch: null,
-
- /**
- * The MSPointer Input manager.
- * @property {Phaser.MSPointer} mspointer - The MSPointer Input manager.
- * @default
- */
- 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
- * @default
- */
- onDown: null,
-
- /**
- * A Signal that is dispatched each time a pointer is released.
- * @property {Phaser.Signal} onUp
- * @default
- */
- onUp: null,
-
- /**
- * A Signal that is dispatched each time a pointer is tapped.
- * @property {Phaser.Signal} onTap
- * @default
- */
- onTap: null,
-
- /**
- * A Signal that is dispatched each time a pointer is held down.
- * @property {Phaser.Signal} onHold
- * @default
- */
- onHold: null,
-
- /**
- * A linked list of interactive objects, the InputHandler components (belonging to Sprites) register themselves with this.
- * @property {Phaser.LinkedList} interactiveItems
- */
- interactiveItems: new Phaser.LinkedList(),
-
/**
* Starts the Input Manager running.
* @method Phaser.Input#boot
@@ -947,7 +938,7 @@ Phaser.Input.prototype = {
if (this.game.canvas.style.cursor !== 'none')
{
- this.game.canvas.style.cursor = 'default';
+ this.game.canvas.style.cursor = 'inherit';
}
if (hard === true)
@@ -1141,6 +1132,81 @@ Phaser.Input.prototype = {
return null;
+ },
+
+ /**
+ * This will return the local coordinates of the specified displayObject based on the given Pointer.
+ * @method Phaser.Input#getLocalPosition
+ * @param {Phaser.Sprite|Phaser.Image} displayObject - The DisplayObject to get the local coordinates for.
+ * @param {Phaser.Pointer} pointer - The Pointer to use in the check against the displayObject.
+ * @return {Phaser.Point} A point containing the coordinates of the Pointer position relative to the DisplayObject.
+ */
+ getLocalPosition: function (displayObject, pointer, output) {
+
+ if (typeof output === 'undefined') { output = new Phaser.Point(); }
+
+ var wt = displayObject.worldTransform;
+ var id = 1 / (wt.a * wt.d + wt.b * -wt.c);
+
+ return output.setTo(
+ wt.d * id * pointer.x + -wt.b * id * pointer.y + (wt.ty * wt.b - wt.tx * wt.d) * id,
+ wt.a * id * pointer.y + -wt.c * id * pointer.x + (-wt.ty * wt.a + wt.tx * wt.c) * id
+ );
+
+ },
+
+ /**
+ * Tests if the current mouse coordinates hit a sprite
+ *
+ * @method hitTest
+ * @param displayObject {DisplayObject} The displayObject to test for a hit
+ */
+ hitTest: function (displayObject, pointer, localPoint) {
+
+ if (!displayObject.worldVisible)
+ {
+ return false;
+ }
+
+ this.getLocalPosition(displayObject, pointer, this._localPoint);
+
+ localPoint.copyFrom(this._localPoint);
+
+ if (displayObject.hitArea && displayObject.hitArea.contains)
+ {
+ if (displayObject.hitArea.contains(this._localPoint.x, this._localPoint.y))
+ {
+ return true;
+ }
+
+ return false;
+ }
+ else if (displayObject instanceof PIXI.Sprite)
+ {
+ var width = displayObject.texture.frame.width;
+ var height = displayObject.texture.frame.height;
+ var x1 = -width * displayObject.anchor.x;
+
+ if (this._localPoint.x > x1 && this._localPoint.x < x1 + width)
+ {
+ var y1 = -height * displayObject.anchor.y;
+
+ if (this._localPoint.y > y1 && this._localPoint.y < y1 + height)
+ {
+ return true;
+ }
+ }
+ }
+
+ for (var i = 0, len = displayObject.children.length; i < len; i++)
+ {
+ if (this.hitTest(displayObject.children[i], pointer, localPoint))
+ {
+ return true;
+ }
+ }
+
+ return false;
}
};
@@ -1280,7 +1346,7 @@ Object.defineProperty(Phaser.Input.prototype, "worldY", {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/InputHandler.js.html b/docs/InputHandler.js.html
index 592d86d6..9e85cf47 100644
--- a/docs/InputHandler.js.html
+++ b/docs/InputHandler.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -609,7 +643,7 @@ Phaser.Key.prototype.constructor = Phaser.Key;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Keyboard.js.html b/docs/Keyboard.js.html
index 4b428a4c..ab68e49c 100644
--- a/docs/Keyboard.js.html
+++ b/docs/Keyboard.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -933,7 +967,7 @@ Phaser.Keyboard.NUM_LOCK = 144;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Line.js.html b/docs/Line.js.html
index aa41210f..5ffbda4c 100644
--- a/docs/Line.js.html
+++ b/docs/Line.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -700,7 +734,7 @@ Phaser.Line.intersects = function (a, b, asSegment, result) {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/LinkedList.js.html b/docs/LinkedList.js.html
index dce1bbe0..aecaa08d 100644
--- a/docs/LinkedList.js.html
+++ b/docs/LinkedList.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -592,7 +626,7 @@ Phaser.LinkedList.prototype.constructor = Phaser.LinkedList;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Loader.js.html b/docs/Loader.js.html
index 6dde3054..b2803dfe 100644
--- a/docs/Loader.js.html
+++ b/docs/Loader.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1749,7 +1783,7 @@ Phaser.Loader.prototype.constructor = Phaser.Loader;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/LoaderParser.js.html b/docs/LoaderParser.js.html
index bd280b4c..428cbb5f 100644
--- a/docs/LoaderParser.js.html
+++ b/docs/LoaderParser.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -518,7 +552,7 @@ Phaser.LoaderParser = {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/MSPointer.js.html b/docs/MSPointer.js.html
index 014729ff..44fa56e6 100644
--- a/docs/MSPointer.js.html
+++ b/docs/MSPointer.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -606,7 +640,7 @@ Phaser.MSPointer.prototype.constructor = Phaser.MSPointer;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Math.js.html b/docs/Math.js.html
index 166ea58e..4dd11bc1 100644
--- a/docs/Math.js.html
+++ b/docs/Math.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1755,7 +1789,7 @@ Phaser.Math = {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Mouse.js.html b/docs/Mouse.js.html
index c1518e11..ab41d38f 100644
--- a/docs/Mouse.js.html
+++ b/docs/Mouse.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -767,7 +801,7 @@ Phaser.Mouse.prototype.constructor = Phaser.Mouse;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Net.js.html b/docs/Net.js.html
index b9b79823..827ec5b7 100644
--- a/docs/Net.js.html
+++ b/docs/Net.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -602,7 +636,7 @@ Phaser.Net.prototype.constructor = Phaser.Net;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Particles.js.html b/docs/Particles.js.html
index 89d16184..ccee8cbf 100644
--- a/docs/Particles.js.html
+++ b/docs/Particles.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -517,7 +551,7 @@ Phaser.Particles.prototype.constructor = Phaser.Particles;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Animation.html b/docs/Phaser.Animation.html
index 3ea9c67e..85dddc8e 100644
--- a/docs/Phaser.Animation.html
+++ b/docs/Phaser.Animation.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -2912,7 +2946,7 @@ You could use this function to generate those by doing: Phaser.Animation.generat
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:25 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.AnimationManager.html b/docs/Phaser.AnimationManager.html
index 4609bb4a..6abdf7aa 100644
--- a/docs/Phaser.AnimationManager.html
+++ b/docs/Phaser.AnimationManager.html
@@ -182,6 +182,10 @@
Group
+
@@ -2962,7 +2993,7 @@ The currentAnim property of the AnimationManager is automatically set to the ani
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:25 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.AnimationParser.html b/docs/Phaser.AnimationParser.html
index ca5b0c11..fbea0e16 100644
--- a/docs/Phaser.AnimationParser.html
+++ b/docs/Phaser.AnimationParser.html
@@ -182,6 +182,10 @@
Group
+
@@ -1480,7 +1514,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:25 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.BitmapData.html b/docs/Phaser.BitmapData.html
index b1f396be..b4f4166d 100644
--- a/docs/Phaser.BitmapData.html
+++ b/docs/Phaser.BitmapData.html
@@ -182,6 +182,10 @@
Group
+
@@ -11939,7 +12008,7 @@ the stroke style and color in a single line of code like so:
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:25 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.BitmapText.html b/docs/Phaser.BitmapText.html
index 46ef4655..039748e8 100644
--- a/docs/Phaser.BitmapText.html
+++ b/docs/Phaser.BitmapText.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1907,7 +1941,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:25 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:42 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Button.html b/docs/Phaser.Button.html
index ac34735f..2dfbb336 100644
--- a/docs/Phaser.Button.html
+++ b/docs/Phaser.Button.html
@@ -182,6 +182,10 @@
Group
+
Indicates the rotation of the Button 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 rotation property instead. Working in radians is also a little faster as it doesn't have to convert the angle.
Should this Sprite be automatically culled if out of range of the camera?
+A culled sprite has its renderable property set to 'false'.
+Be advised this is quite an expensive operation, as it has to calculate the bounds of the object every frame, so only enable it if you really need it.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
autoCull
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+
+
A flag indicating if the Sprite should be automatically camera culled or not.
A Sprite that is fixed to the camera uses its x/y coordinates as offsets from the top left of the camera.
+Note that if this Image is a child of a display object that has changed its position then the offset will be calculated from that.
By default an Image won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is
+activated for this object and it will then start to process click/touch events and more.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
inputEnabled
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+
+
Set to true to allow this object to receive input events.
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, BitmapData or PIXI.Texture.
Brings the Sprite to the top of the display list it is a child of. Sprites that are members of a Phaser.Group are only
+bought to the top of that Group, not the entire display list.
Crop allows you to crop the texture used to display this Image.
+Cropping takes place from the top-left of the Image and can be modified in real-time by providing an updated rectangle object.
Destroys the Sprite. This removes it from its parent group, destroys the input, event and animation handlers if present
+and nulls its reference to game, freeing it up for garbage collection.
Kills a Sprite. A killed Sprite has its alive, exists and visible properties all set to false.
+It will dispatch the onKilled event, you can listen to Sprite.events.onKilled for the signal.
+Note that killing a Sprite is a way for you to quickly recycle it in a Sprite pool, it doesn't free it up from memory.
+If you don't need this Sprite any more you should call Sprite.destroy instead.
Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
+This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
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, BitmapData or PIXI.Texture.
+
+
+
+
+
+
+
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.
Brings a 'dead' Sprite back to life, optionally giving it the health value specified.
+A resurrected Sprite has its alive, exists and visible properties all set to true.
+It will dispatch the onRevived event, you can listen to Sprite.events.onRevived for the signal.
@@ -4511,7 +7614,7 @@ Call this function with no parameters at all to reset all sounds on this Button.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:26 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:42 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Cache.html b/docs/Phaser.Cache.html
index ac9a8804..83bec0aa 100644
--- a/docs/Phaser.Cache.html
+++ b/docs/Phaser.Cache.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -7052,7 +7086,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:26 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:42 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Camera.html b/docs/Phaser.Camera.html
index 9c78271a..c06156fd 100644
--- a/docs/Phaser.Camera.html
+++ b/docs/Phaser.Camera.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -3429,7 +3463,7 @@ without having to use game.camera.x and game.camera.y.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:26 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:42 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Canvas.html b/docs/Phaser.Canvas.html
index 06f8a7ad..8f38c7e4 100644
--- a/docs/Phaser.Canvas.html
+++ b/docs/Phaser.Canvas.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -2624,7 +2658,7 @@ patchy on earlier browsers, especially on mobile.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:26 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:42 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Circle.html b/docs/Phaser.Circle.html
index 9f4ff06b..d3acc07b 100644
--- a/docs/Phaser.Circle.html
+++ b/docs/Phaser.Circle.html
@@ -182,6 +182,10 @@
Group
+
@@ -4302,7 +4336,7 @@ This method checks the radius distances between the two Circle objects to see if
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:26 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:42 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Color.html b/docs/Phaser.Color.html
index 8db79737..c71e9133 100644
--- a/docs/Phaser.Color.html
+++ b/docs/Phaser.Color.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -3611,7 +3645,7 @@ Set the max value to restrict the maximum color used per channel.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:26 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:43 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.DOMSprite.html b/docs/Phaser.DOMSprite.html
index c7f3269d..a9785517 100644
--- a/docs/Phaser.DOMSprite.html
+++ b/docs/Phaser.DOMSprite.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1429,7 +1463,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:43 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Device.html b/docs/Phaser.Device.html
index 7d231d36..0203c6f8 100644
--- a/docs/Phaser.Device.html
+++ b/docs/Phaser.Device.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -6037,7 +6071,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:43 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Easing.Back.html b/docs/Phaser.Easing.Back.html
index 5cd5ceb8..acf5665a 100644
--- a/docs/Phaser.Easing.Back.html
+++ b/docs/Phaser.Easing.Back.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -963,7 +997,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:43 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Easing.Bounce.html b/docs/Phaser.Easing.Bounce.html
index 559da0c6..3e0a7762 100644
--- a/docs/Phaser.Easing.Bounce.html
+++ b/docs/Phaser.Easing.Bounce.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -963,7 +997,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:43 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Easing.Circular.html b/docs/Phaser.Easing.Circular.html
index 423e8058..1da13cea 100644
--- a/docs/Phaser.Easing.Circular.html
+++ b/docs/Phaser.Easing.Circular.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -963,7 +997,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:43 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Easing.Cubic.html b/docs/Phaser.Easing.Cubic.html
index 56b6e2f3..dadf57d3 100644
--- a/docs/Phaser.Easing.Cubic.html
+++ b/docs/Phaser.Easing.Cubic.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -963,7 +997,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:44 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Easing.Elastic.html b/docs/Phaser.Easing.Elastic.html
index 445528fa..dcb4f112 100644
--- a/docs/Phaser.Easing.Elastic.html
+++ b/docs/Phaser.Easing.Elastic.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -963,7 +997,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:44 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Easing.Exponential.html b/docs/Phaser.Easing.Exponential.html
index 2bec6a2d..848cfaf4 100644
--- a/docs/Phaser.Easing.Exponential.html
+++ b/docs/Phaser.Easing.Exponential.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -963,7 +997,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:44 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Easing.Linear.html b/docs/Phaser.Easing.Linear.html
index efd870b1..e0dd7635 100644
--- a/docs/Phaser.Easing.Linear.html
+++ b/docs/Phaser.Easing.Linear.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -681,7 +715,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:44 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Easing.Quadratic.html b/docs/Phaser.Easing.Quadratic.html
index 97dd1fb8..f622e7b6 100644
--- a/docs/Phaser.Easing.Quadratic.html
+++ b/docs/Phaser.Easing.Quadratic.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -963,7 +997,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:44 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Easing.Quartic.html b/docs/Phaser.Easing.Quartic.html
index d605c617..73952cb8 100644
--- a/docs/Phaser.Easing.Quartic.html
+++ b/docs/Phaser.Easing.Quartic.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -963,7 +997,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:44 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Easing.Quintic.html b/docs/Phaser.Easing.Quintic.html
index cae49a2f..740435a7 100644
--- a/docs/Phaser.Easing.Quintic.html
+++ b/docs/Phaser.Easing.Quintic.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -963,7 +997,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:44 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Easing.Sinusoidal.html b/docs/Phaser.Easing.Sinusoidal.html
index 876ace73..f84059e8 100644
--- a/docs/Phaser.Easing.Sinusoidal.html
+++ b/docs/Phaser.Easing.Sinusoidal.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -963,7 +997,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:44 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Easing.html b/docs/Phaser.Easing.html
index 76cf08c7..1181d42f 100644
--- a/docs/Phaser.Easing.html
+++ b/docs/Phaser.Easing.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -573,7 +607,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:27 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:43 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Events.html b/docs/Phaser.Events.html
index a3c813c2..070500c3 100644
--- a/docs/Phaser.Events.html
+++ b/docs/Phaser.Events.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -587,7 +621,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:45 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Filter.html b/docs/Phaser.Filter.html
index 20026212..b9c05442 100644
--- a/docs/Phaser.Filter.html
+++ b/docs/Phaser.Filter.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1872,7 +1906,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:45 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Frame.html b/docs/Phaser.Frame.html
index a7dd759c..dee7f5d7 100644
--- a/docs/Phaser.Frame.html
+++ b/docs/Phaser.Frame.html
@@ -182,6 +182,10 @@
Group
+
@@ -2948,7 +3135,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:45 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.FrameData.html b/docs/Phaser.FrameData.html
index e8a64653..03eab0de 100644
--- a/docs/Phaser.FrameData.html
+++ b/docs/Phaser.FrameData.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1895,7 +1929,7 @@ The frames are returned in the output array, or if none is provided in a new Arr
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:28 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:45 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Game.html b/docs/Phaser.Game.html
index 5290e6ce..5aa5199b 100644
--- a/docs/Phaser.Game.html
+++ b/docs/Phaser.Game.html
@@ -182,6 +182,10 @@
Group
+
@@ -5430,7 +5464,7 @@ This is extremely useful to hard to track down errors! Use the internal stepCoun
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:29 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:45 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.GameObjectFactory.html b/docs/Phaser.GameObjectFactory.html
index 336b5ec6..7870a0e4 100644
--- a/docs/Phaser.GameObjectFactory.html
+++ b/docs/Phaser.GameObjectFactory.html
@@ -182,6 +182,10 @@
Group
+
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.
The image key as defined in the Game.Cache to use as the texture for this sprite OR a RenderTexture.
-
-
-
-
-
-
-
frame
-
-
-
-
-
-string
-|
-
-number
-
-
-
-
-
-
-
-
- <optional>
-
-
-
-
-
-
-
-
-
-
-
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.
@@ -3242,7 +3068,8 @@ at set intervals, and fixes their positions and velocities accorindgly.
-
A dynamic initially blank canvas to which images can be drawn.
+
Create a new Image object. An Image is a light-weight object you can use to display anything that doesn't need physics or animation.
+It can still rotate, scale, crop and receive input events. This makes it perfect for logos, backgrounds, simple buttons and other non-Sprite graphics.
@@ -3264,6 +3091,8 @@ at set intervals, and fixes their positions and velocities accorindgly.
Type
+
Argument
+
@@ -3274,6 +3103,68 @@ at set intervals, and fixes their positions and velocities accorindgly.
+
+
+
x
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
X position of the image.
+
+
+
+
+
+
+
y
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Y position of the image.
+
+
+
+
key
@@ -3283,28 +3174,45 @@ at set intervals, and fixes their positions and velocities accorindgly.
string
+|
+
+Phaser.RenderTexture
+|
+
+PIXI.Texture
+
+
+
+
+
+
+
+
-
Asset key for the render texture.
+
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.
-
width
+
frame
+string
+|
+
number
@@ -3312,33 +3220,53 @@ at set intervals, and fixes their positions and velocities accorindgly.
+
+
+ <optional>
+
+
+
+
+
+
+
-
the width of the render texture.
+
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.
@@ -4905,7 +5111,7 @@ at set intervals, and fixes their positions and velocities accorindgly.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:29 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:45 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Gamepad.html b/docs/Phaser.Gamepad.html
index aeae4f64..71212853 100644
--- a/docs/Phaser.Gamepad.html
+++ b/docs/Phaser.Gamepad.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -3362,7 +3396,7 @@ This MUST be called manually before Phaser will start polling the Gamepad API.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:29 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:45 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.GamepadButton.html b/docs/Phaser.GamepadButton.html
index 8a741cdf..57a0aa0d 100644
--- a/docs/Phaser.GamepadButton.html
+++ b/docs/Phaser.GamepadButton.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -2540,7 +2574,7 @@ If the button is up it holds the duration of the previous down session.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:29 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:46 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Graphics.html b/docs/Phaser.Graphics.html
index 75ae9f33..70d2d789 100644
--- a/docs/Phaser.Graphics.html
+++ b/docs/Phaser.Graphics.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -739,7 +773,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:29 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:46 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Group.html b/docs/Phaser.Group.html
index 79bcc812..c8a44cf1 100644
--- a/docs/Phaser.Group.html
+++ b/docs/Phaser.Group.html
@@ -182,6 +182,10 @@
Group
+
@@ -9084,7 +8753,7 @@ You cannot swap a child with itself, or swap un-parented children, doing so will
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:29 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:46 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Image.html b/docs/Phaser.Image.html
new file mode 100644
index 00000000..37ef0e85
--- /dev/null
+++ b/docs/Phaser.Image.html
@@ -0,0 +1,3807 @@
+
+
+
+
+
+ Phaser Class: Image
+
+
+
+
+
+
+
+
+
+
+
Create a new Image object. An Image is a light-weight object you can use to display anything that doesn't need physics or animation.
+It can still rotate, scale, crop and receive input events. This makes it perfect for logos, backgrounds, simple buttons and other non-Sprite graphics.
The texture used by the Image during rendering. It can be a string which is a reference to the Cache entry, or an instance of a RenderTexture, BitmapData or PIXI.Texture.
+
+
+
+
+
+
+
frame
+
+
+
+
+
+string
+|
+
+number
+
+
+
+
+
+
+
+
+
+
If this Image 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.
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. Working in radians is also a little faster as it doesn't have to convert the angle.
Should this Sprite be automatically culled if out of range of the camera?
+A culled sprite has its renderable property set to 'false'.
+Be advised this is quite an expensive operation, as it has to calculate the bounds of the object every frame, so only enable it if you really need it.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
autoCull
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+
+
A flag indicating if the Sprite should be automatically camera culled or not.
A Sprite that is fixed to the camera uses its x/y coordinates as offsets from the top left of the camera.
+Note that if this Image is a child of a display object that has changed its position then the offset will be calculated from that.
By default an Image won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is
+activated for this object and it will then start to process click/touch events and more.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
inputEnabled
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+
+
Set to true to allow this object to receive input events.
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, BitmapData or PIXI.Texture.
Brings the Sprite to the top of the display list it is a child of. Sprites that are members of a Phaser.Group are only
+bought to the top of that Group, not the entire display list.
Crop allows you to crop the texture used to display this Image.
+Cropping takes place from the top-left of the Image and can be modified in real-time by providing an updated rectangle object.
Destroys the Sprite. This removes it from its parent group, destroys the input, event and animation handlers if present
+and nulls its reference to game, freeing it up for garbage collection.
Kills a Sprite. A killed Sprite has its alive, exists and visible properties all set to false.
+It will dispatch the onKilled event, you can listen to Sprite.events.onKilled for the signal.
+Note that killing a Sprite is a way for you to quickly recycle it in a Sprite pool, it doesn't free it up from memory.
+If you don't need this Sprite any more you should call Sprite.destroy instead.
Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
+This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
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, BitmapData or PIXI.Texture.
+
+
+
+
+
+
+
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.
Brings a 'dead' Sprite back to life, optionally giving it the health value specified.
+A resurrected Sprite has its alive, exists and visible properties all set to true.
+It will dispatch the onRevived event, you can listen to Sprite.events.onRevived for the signal.
@@ -1080,8 +1107,8 @@ Default size of 44px (Apples recommended "finger tip" size) but can be
-
You can disable all Input by setting Input.disabled: true. While set all new input related events will be ignored.
-If you need to disable just one type of input, for example mouse, use Input.mouse.disabled: true instead
+
You can disable all Input by setting Input.disabled = true. While set all new input related events will be ignored.
+If you need to disable just one type of input; for example mouse; use Input.mouse.disabled = true instead
@@ -1165,7 +1192,7 @@ If you need to disable just one type of input, for example mouse, use Input.mous
@@ -4606,11 +4505,6 @@ For lots of games it's useful to set this to 1.
-
-
How often should the input pointers be checked for updates?
-A value of 0 means every single frame (60fps), a value of 1 means every other frame (30fps) and so on.
-
-
@@ -4660,7 +4554,7 @@ A value of 0 means every single frame (60fps), a value of 1 means every other fr
-
+
How often should the input pointers be checked for updates? A value of 0 means every single frame (60fps); a value of 1 means every other frame (30fps) and so on.
@@ -4692,7 +4586,7 @@ A value of 0 means every single frame (60fps), a value of 1 means every other fr
@@ -4823,7 +4717,7 @@ A value of 0 means every single frame (60fps), a value of 1 means every other fr
The total number of entries that can be recorded into the Pointer objects tracking history.
-If the Pointer is tracking one event every 100ms, then a trackLimit of 100 would store the last 10 seconds worth of history.
+If the Pointer is tracking one event every 100ms; then a trackLimit of 100 would store the last 10 seconds worth of history.
@@ -4907,7 +4801,7 @@ If the Pointer is tracking one event every 100ms, then a trackLimit of 100 would
@@ -7648,7 +7685,7 @@ to only use if you've limited input to a single pointer (i.e. mouse or touch)
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:46 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.InputHandler.html b/docs/Phaser.InputHandler.html
index d9e43038..279238bb 100644
--- a/docs/Phaser.InputHandler.html
+++ b/docs/Phaser.InputHandler.html
@@ -182,6 +182,10 @@
Group
+
@@ -7651,7 +7685,7 @@ This value is only set when the pointer is over this Sprite.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:46 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Key.html b/docs/Phaser.Key.html
index 1f8e66e1..e7c81147 100644
--- a/docs/Phaser.Key.html
+++ b/docs/Phaser.Key.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -2530,7 +2564,7 @@ If the key is up it holds the duration of the previous down session.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:47 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Keyboard.html b/docs/Phaser.Keyboard.html
index 3e720486..38a54649 100644
--- a/docs/Phaser.Keyboard.html
+++ b/docs/Phaser.Keyboard.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -2957,7 +2991,7 @@ This is called automatically by Phaser.Input and should not normally be invoked
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:47 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Line.html b/docs/Phaser.Line.html
index 5f974cbf..78ac8afe 100644
--- a/docs/Phaser.Line.html
+++ b/docs/Phaser.Line.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -3053,7 +3087,7 @@ Returns the intersection segment of AB and EF as a Point, or null if there is no
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:47 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.LinkedList.html b/docs/Phaser.LinkedList.html
index 8f1018e0..e55a3b05 100644
--- a/docs/Phaser.LinkedList.html
+++ b/docs/Phaser.LinkedList.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1449,7 +1483,7 @@ The function must exist on the member.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:47 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Loader.html b/docs/Phaser.Loader.html
index eca96ed4..958fb0d5 100644
--- a/docs/Phaser.Loader.html
+++ b/docs/Phaser.Loader.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -7133,7 +7167,7 @@ This allows you to easily make loading bars for games.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:30 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:47 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.LoaderParser.html b/docs/Phaser.LoaderParser.html
index e5052246..0a8b82cc 100644
--- a/docs/Phaser.LoaderParser.html
+++ b/docs/Phaser.LoaderParser.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -681,7 +715,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:47 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.MSPointer.html b/docs/Phaser.MSPointer.html
index 1726c1aa..4ac95b71 100644
--- a/docs/Phaser.MSPointer.html
+++ b/docs/Phaser.MSPointer.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1399,7 +1433,7 @@ It will work only in Internet Explorer 10 and Windows Store or Windows Phone 8 a
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:48 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Math.html b/docs/Phaser.Math.html
index 41f67fbc..0ca5ab5e 100644
--- a/docs/Phaser.Math.html
+++ b/docs/Phaser.Math.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -11177,7 +11211,7 @@ Should be called whenever the angle is updated on the Sprite to stop it from goi
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:47 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Mouse.html b/docs/Phaser.Mouse.html
index 03806212..a37f803a 100644
--- a/docs/Phaser.Mouse.html
+++ b/docs/Phaser.Mouse.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -2716,7 +2750,7 @@ If the browser successfully enters a locked state the event Phaser.Mouse.pointer
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:48 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Net.html b/docs/Phaser.Net.html
index 5c69959d..b0d74dbb 100644
--- a/docs/Phaser.Net.html
+++ b/docs/Phaser.Net.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1343,7 +1377,7 @@ Optionally you can redirect to the new url, or just return it as a string.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:48 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Particles.Arcade.Emitter.html b/docs/Phaser.Particles.Arcade.Emitter.html
index bc65c282..b09f7512 100644
--- a/docs/Phaser.Particles.Arcade.Emitter.html
+++ b/docs/Phaser.Particles.Arcade.Emitter.html
@@ -182,6 +182,10 @@
Group
+
@@ -13276,7 +12943,7 @@ You cannot swap a child with itself, or swap un-parented children, doing so will
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:48 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Particles.html b/docs/Phaser.Particles.html
index 293c88e1..5c788d0f 100644
--- a/docs/Phaser.Particles.html
+++ b/docs/Phaser.Particles.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1232,7 +1266,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:31 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:48 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Physics.Arcade.Body.html b/docs/Phaser.Physics.Arcade.Body.html
index fb9cd106..9472bab6 100644
--- a/docs/Phaser.Physics.Arcade.Body.html
+++ b/docs/Phaser.Physics.Arcade.Body.html
@@ -182,6 +182,10 @@
Group
+
@@ -10114,7 +10148,7 @@ See also the Body.offset property.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:48 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Physics.Arcade.html b/docs/Phaser.Physics.Arcade.html
index b048804c..2d301976 100644
--- a/docs/Phaser.Physics.Arcade.html
+++ b/docs/Phaser.Physics.Arcade.html
@@ -182,6 +182,10 @@
Group
+
@@ -8063,7 +8097,7 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:48 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Physics.html b/docs/Phaser.Physics.html
index 9379c4c4..59c96ebd 100644
--- a/docs/Phaser.Physics.html
+++ b/docs/Phaser.Physics.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -539,7 +573,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:48 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Plugin.html b/docs/Phaser.Plugin.html
index 4816bc54..7d4db35b 100644
--- a/docs/Phaser.Plugin.html
+++ b/docs/Phaser.Plugin.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1906,7 +1940,7 @@ It is only called if active is set to true.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:49 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.PluginManager.html b/docs/Phaser.PluginManager.html
index 8e608895..4dfc6426 100644
--- a/docs/Phaser.PluginManager.html
+++ b/docs/Phaser.PluginManager.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1571,7 +1605,7 @@ It only calls plugins who have active=true.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:49 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Point.html b/docs/Phaser.Point.html
index 3290f887..4846788a 100644
--- a/docs/Phaser.Point.html
+++ b/docs/Phaser.Point.html
@@ -182,6 +182,10 @@
Group
+
@@ -5267,7 +5465,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:49 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Pointer.html b/docs/Phaser.Pointer.html
index 260e519c..70b8cd52 100644
--- a/docs/Phaser.Pointer.html
+++ b/docs/Phaser.Pointer.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -4354,7 +4388,7 @@ If you wish to check if the Pointer was released just once then see the Sprite.e
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:32 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:49 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Polygon.html b/docs/Phaser.Polygon.html
index 026558c8..7797450a 100644
--- a/docs/Phaser.Polygon.html
+++ b/docs/Phaser.Polygon.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -699,7 +733,7 @@ arguments passed can be flat x,y values e.g. new PIXI.Polygon(x,y, x,y, x,
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:49 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.QuadTree.html b/docs/Phaser.QuadTree.html
index 83f23cd6..c848fba7 100644
--- a/docs/Phaser.QuadTree.html
+++ b/docs/Phaser.QuadTree.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1620,7 +1654,7 @@ Split the node into 4 subnodes
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:49 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.RandomDataGenerator.html b/docs/Phaser.RandomDataGenerator.html
index 6e2c5b66..eb68cbd9 100644
--- a/docs/Phaser.RandomDataGenerator.html
+++ b/docs/Phaser.RandomDataGenerator.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -2037,7 +2071,7 @@ Random number generator from
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:49 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Rectangle.html b/docs/Phaser.Rectangle.html
index 0472e0e8..ced47c37 100644
--- a/docs/Phaser.Rectangle.html
+++ b/docs/Phaser.Rectangle.html
@@ -182,6 +182,10 @@
Group
+
@@ -7378,7 +7668,7 @@ This method checks the x, y, width, and height properties of the Rectangles.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:50 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.RenderTexture.html b/docs/Phaser.RenderTexture.html
index d3854fb4..631e8769 100644
--- a/docs/Phaser.RenderTexture.html
+++ b/docs/Phaser.RenderTexture.html
@@ -182,6 +182,10 @@
Group
+
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:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
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.
@@ -1980,7 +4243,7 @@ If the display object is a Group or has children it will draw all children as we
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:50 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.RequestAnimationFrame.html b/docs/Phaser.RequestAnimationFrame.html
index 724525ad..91a68ab3 100644
--- a/docs/Phaser.RequestAnimationFrame.html
+++ b/docs/Phaser.RequestAnimationFrame.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1303,7 +1337,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:50 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Signal.html b/docs/Phaser.Signal.html
index 176d68b9..28377b51 100644
--- a/docs/Phaser.Signal.html
+++ b/docs/Phaser.Signal.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -2288,7 +2322,7 @@ IMPORTANT: should be called only during signal dispatch, calling it before/after
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:50 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.SinglePad.html b/docs/Phaser.SinglePad.html
index 5452d373..f1abb223 100644
--- a/docs/Phaser.SinglePad.html
+++ b/docs/Phaser.SinglePad.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -3775,7 +3809,7 @@ analog trigger buttons on the XBOX 360 controller
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:33 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:50 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Sound.html b/docs/Phaser.Sound.html
index c8bf2e3f..f44b1490 100644
--- a/docs/Phaser.Sound.html
+++ b/docs/Phaser.Sound.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -5799,7 +5833,7 @@ This allows you to bundle multiple sounds together into a single audio file and
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:50 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.SoundManager.html b/docs/Phaser.SoundManager.html
index 4c50e2f2..1c61d2bf 100644
--- a/docs/Phaser.SoundManager.html
+++ b/docs/Phaser.SoundManager.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -2857,7 +2891,7 @@ Note: On Firefox 25+ on Linux if you have media.gstreamer disabled in about:conf
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:50 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Sprite.html b/docs/Phaser.Sprite.html
index 8338ac67..740daa40 100644
--- a/docs/Phaser.Sprite.html
+++ b/docs/Phaser.Sprite.html
@@ -182,6 +182,10 @@
Group
+
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.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
angle
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
Gets or sets the Sprites angle of rotation in degrees.
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. Working in radians is also a little faster as it doesn't have to convert the angle.
Should this Sprite be automatically culled if out of range of the camera?
+A culled sprite has its renderable property set to 'false'.
+Be advised this is quite an expensive operation, as it has to calculate the bounds of the object every frame, so only enable it if you really need it.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
autoCull
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+
+
A flag indicating if the Sprite should be automatically camera culled or not.
By default Sprites have a Phaser.Physics Body attached to them. You can operate physics actions via this property, or null it to skip all physics updates.
By default Sprites have a Phaser.Physics Body attached to them. You can operate physics actions via this property, or null it to skip all physics updates.
This Rectangle object fully encompasses the Sprite and is updated in real-time.
+The bounds is the full bounding area after rotation and scale have been taken into account. It should not be modified directly.
+It's used for Camera culling and physics body alignment.
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.
+The crop is only applied if you have set Sprite.cropEnabled to true.
A Sprite 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.
A Sprite that is fixed to the camera uses its x/y coordinates as offsets from the top left of the camera.
+Note that if this Image is a child of a display object that has changed its position then the offset will be calculated from that.
The height 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.
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.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
inputEnabled
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+
+
Set to true to allow this Sprite to receive input events, otherwise false.
By default an Image won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is
+activated for this object and it will then start to process click/touch events and more.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
inputEnabled
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+
+
Set to true to allow this object to receive input events.
A threshold value applied to the inWorld check. If you don't want a Sprite to be considered "out of the world" until at least 100px away for example then set it to 100.
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, BitmapData or PIXI.Texture.
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, BitmapData or PIXI.Texture.
If you would like the Sprite to have a lifespan once 'born' you can set this to a positive value. Handy for particles, bullets, etc.
+The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
lifespan
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
The lifespan of the Sprite (in ms) before it will be killed.
If you would like the Sprite to have a lifespan once 'born' you can set this to a positive value. Handy for particles, bullets, etc.
+The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
lifespan
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
The lifespan of the Sprite (in ms) before it will be killed.
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.
Brings the Sprite to the top of the display list it is a child of. Sprites that are members of a Phaser.Group are only
+bought to the top of that Group, not the entire display list.
Brings the Sprite to the top of the display list it is a child of. Sprites that are members of a Phaser.Group are only
+bought to the top of that Group, not the entire display list.
Crop allows you to crop the texture used to display this Image.
+Cropping takes place from the top-left of the Image and can be modified in real-time by providing an updated rectangle object.
Destroys the Sprite. This removes it from its parent group, destroys the input, event and animation handlers if present
+and nulls its reference to game, freeing it up for garbage collection.
Destroys the Sprite. This removes it from its parent group, destroys the input, event and animation handlers if present
+and nulls its reference to game, freeing it up for garbage collection.
Gets the local unmodified position of a coordinate relative to the Sprite, factoring in rotation and scale.
+Mostly only used internally by the Input Manager, but also useful for custom hit detection.
Kills a Sprite. A killed Sprite has its alive, exists and visible properties all set to false.
+It will dispatch the onKilled event, you can listen to Sprite.events.onKilled for the signal.
+Note that killing a Sprite is a way for you to quickly recycle it in a Sprite pool, it doesn't free it up from memory.
+If you don't need this Sprite any more you should call Sprite.destroy instead.
Kills a Sprite. A killed Sprite has its alive, exists and visible properties all set to false.
+It will dispatch the onKilled event, you can listen to Sprite.events.onKilled for the signal.
+Note that killing a Sprite is a way for you to quickly recycle it in a Sprite pool, it doesn't free it up from memory.
+If you don't need this Sprite any more you should call Sprite.destroy instead.
Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
+This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
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, BitmapData or PIXI.Texture.
+
+
+
+
+
+
+
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.
Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
+This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
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, BitmapData or PIXI.Texture.
+
+
+
+
+
+
+
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.
Play an animation based on the given key. The animation should previously have been added via sprite.animations.add()
+If the requested animation is already playing this request will be ignored. If you need to reset an already running animation do so directly on the Animation object itself.
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
name
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The name of the animation to be played, e.g. "fire", "walk", "jump".
+
+
+
+
+
+
+
frameRate
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ null
+
+
+
+
+
The framerate to play the animation at. The speed is given in frames per second. If not provided the previously set frameRate of the Animation is used.
+
+
+
+
+
+
+
loop
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
Should the animation be looped after playback. If not provided the previously set loop value of the Animation is used.
+
+
+
+
+
+
+
killOnComplete
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
If set to true when the animation completes (only happens if loop=false) the parent Sprite will be killed.
Play an animation based on the given key. The animation should previously have been added via sprite.animations.add()
+If the requested animation is already playing this request will be ignored. If you need to reset an already running animation do so directly on the Animation object itself.
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
name
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The name of the animation to be played, e.g. "fire", "walk", "jump".
+
+
+
+
+
+
+
frameRate
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ null
+
+
+
+
+
The framerate to play the animation at. The speed is given in frames per second. If not provided the previously set frameRate of the Animation is used.
+
+
+
+
+
+
+
loop
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
Should the animation be looped after playback. If not provided the previously set loop value of the Animation is used.
+
+
+
+
+
+
+
killOnComplete
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
If set to true when the animation completes (only happens if loop=false) the parent Sprite will be killed.
Resets the Sprite. This places the Sprite at the given x/y world coordinates and then
+sets alive, exists, visible and renderable all to true. Also resets the outOfBounds state and health values.
+If the Sprite has a physics body that too is reset.
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
x
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The x coordinate (in world space) to position the Sprite at.
+
+
+
+
+
+
+
y
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The y coordinate (in world space) to position the Sprite at.
Resets the Sprite. This places the Sprite at the given x/y world coordinates and then
+sets alive, exists, visible and renderable all to true. Also resets the outOfBounds state and health values.
+If the Sprite has a physics body that too is reset.
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
x
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The x coordinate (in world space) to position the Sprite at.
+
+
+
+
+
+
+
y
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The y coordinate (in world space) to position the Sprite at.
Brings a 'dead' Sprite back to life, optionally giving it the health value specified.
+A resurrected Sprite has its alive, exists and visible properties all set to true.
+It will dispatch the onRevived event, you can listen to Sprite.events.onRevived for the signal.
Brings a 'dead' Sprite back to life, optionally giving it the health value specified.
+A resurrected Sprite has its alive, exists and visible properties all set to true.
+It will dispatch the onRevived event, you can listen to Sprite.events.onRevived for the signal.
Create a new Sprite object. Sprites are the lifeblood of your game, used for nearly everything visual.
+
At its most basic a Sprite consists of a set of coordinates and a texture that is rendered to the canvas.
+They also contain additional properties allowing for physics motion (via Sprite.body), input handling (via Sprite.input),
+events (via Sprite.events), animation (via Sprite.animations), camera culling and more. Please see the Examples for use cases.
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.
+
+
+
+
+
+
+
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.
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
Source:
gameobjects/Sprite.js, line 23
@@ -756,116 +12188,7 @@ events (via Sprite.events), animation (via Sprite.animations), camera culling an
The anchor sets the origin point of the texture.
-The default is 0,0 this means the textures origin is the top left
-Setting than anchor to 0.5,0.5 means the textures origin is centered
-Setting the anchor to 1,1 would mean the textures origin points will be the bottom right
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. Working in radians is also a little faster as it doesn't have to convert the angle.
Should this Sprite be automatically culled if out of range of the camera?
+A culled sprite has its renderable property set to 'false'.
+Be advised this is quite an expensive operation, as it has to calculate the bounds of the object every frame, so only enable it if you really need it.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
autoCull
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+
+
A flag indicating if the Sprite should be automatically camera culled or not.
By default Sprites have a Phaser.Physics Body attached to them. You can operate physics actions via this property, or null it to skip all physics updates.
A Sprite that is fixed to the camera uses its x/y coordinates as offsets from the top left of the camera.
+Note that if this Image is a child of a display object that has changed its position then the offset will be calculated from that.
By default an Image won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is
+activated for this object and it will then start to process click/touch events and more.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
inputEnabled
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+
+
Set to true to allow this object to receive input events.
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, BitmapData or PIXI.Texture.
If you would like the Sprite to have a lifespan once 'born' you can set this to a positive value. Handy for particles, bullets, etc.
+The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
lifespan
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
The lifespan of the Sprite (in ms) before it will be killed.
@@ -4535,7 +17967,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
-
scale
+
<readonly> renderOrderID
@@ -4574,13 +18006,13 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
-
scale
+
renderOrderID
-Phaser.Point
+number
@@ -4590,7 +18022,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
-
The scale of the Sprite when rendered. By default it's set to 1 (no scale). You can modify it via scale.x or scale.y or scale.setTo(x, y). A value of 1 means no change to the scale, 0.5 means "half the size", 2 means "twice the size", etc.
+
The render order ID, reset every frame.
@@ -4619,7 +18051,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
Brings the Sprite to the top of the display list it is a child of. Sprites that are members of a Phaser.Group are only
+bought to the top of that Group, not the entire display list.
Crop allows you to crop the texture used to display this Image.
+Cropping takes place from the top-left of the Image and can be modified in real-time by providing an updated rectangle object.
Destroys the Sprite. This removes it from its parent group, destroys the input, event and animation handlers if present
+and nulls its reference to game, freeing it up for garbage collection.
Kills a Sprite. A killed Sprite has its alive, exists and visible properties all set to false.
+It will dispatch the onKilled event, you can listen to Sprite.events.onKilled for the signal.
+Note that killing a Sprite is a way for you to quickly recycle it in a Sprite pool, it doesn't free it up from memory.
+If you don't need this Sprite any more you should call Sprite.destroy instead.
Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
+This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
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, BitmapData or PIXI.Texture.
+
+
+
+
+
+
+
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.
Play an animation based on the given key. The animation should previously have been added via sprite.animations.add()
+If the requested animation is already playing this request will be ignored. If you need to reset an already running animation do so directly on the Animation object itself.
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
name
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The name of the animation to be played, e.g. "fire", "walk", "jump".
+
+
+
+
+
+
+
frameRate
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ null
+
+
+
+
+
The framerate to play the animation at. The speed is given in frames per second. If not provided the previously set frameRate of the Animation is used.
+
+
+
+
+
+
+
loop
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
Should the animation be looped after playback. If not provided the previously set loop value of the Animation is used.
+
+
+
+
+
+
+
killOnComplete
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
If set to true when the animation completes (only happens if loop=false) the parent Sprite will be killed.
Resets the Sprite. This places the Sprite at the given x/y world coordinates and then
+sets alive, exists, visible and renderable all to true. Also resets the outOfBounds state and health values.
+If the Sprite has a physics body that too is reset.
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
x
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The x coordinate (in world space) to position the Sprite at.
+
+
+
+
+
+
+
y
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The y coordinate (in world space) to position the Sprite at.
Brings a 'dead' Sprite back to life, optionally giving it the health value specified.
+A resurrected Sprite has its alive, exists and visible properties all set to true.
+It will dispatch the onRevived event, you can listen to Sprite.events.onRevived for the signal.
@@ -7941,7 +23253,7 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:50 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Stage.html b/docs/Phaser.Stage.html
index bace5b63..c3a06801 100644
--- a/docs/Phaser.Stage.html
+++ b/docs/Phaser.Stage.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1930,7 +1964,7 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:51 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.StageScaleMode.html b/docs/Phaser.StageScaleMode.html
index 72ea2c10..539c7496 100644
--- a/docs/Phaser.StageScaleMode.html
+++ b/docs/Phaser.StageScaleMode.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -4904,7 +4938,7 @@ Please note that this needs to be supported by the web browser and isn't the sam
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:51 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.State.html b/docs/Phaser.State.html
index d0a995ce..a7006252 100644
--- a/docs/Phaser.State.html
+++ b/docs/Phaser.State.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -2568,7 +2602,7 @@ If you need to use the loader, you may need to use them here.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:51 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.StateManager.html b/docs/Phaser.StateManager.html
index bd5daaaf..6c14776a 100644
--- a/docs/Phaser.StateManager.html
+++ b/docs/Phaser.StateManager.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -3254,7 +3288,7 @@ State must exist and have at least one callback function registered..
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:34 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:51 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Text.html b/docs/Phaser.Text.html
index ea84a034..6b00f9c5 100644
--- a/docs/Phaser.Text.html
+++ b/docs/Phaser.Text.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -2560,7 +2594,7 @@ If you wish to work in radians instead of degrees use the property Sprite.rotati
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:51 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Tile.html b/docs/Phaser.Tile.html
index c6710c82..1ae5a9a1 100644
--- a/docs/Phaser.Tile.html
+++ b/docs/Phaser.Tile.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -3965,7 +3999,7 @@ The callback must true true for collision processing to take place.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:51 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.TileSprite.html b/docs/Phaser.TileSprite.html
index 04e6138a..29baf294 100644
--- a/docs/Phaser.TileSprite.html
+++ b/docs/Phaser.TileSprite.html
@@ -182,6 +182,10 @@
Group
+
The anchor sets the origin point of the texture.
-The default is 0,0 this means the textures origin is the top left
-Setting than anchor to 0.5,0.5 means the textures origin is centered
-Setting the anchor to 1,1 would mean the textures origin points will be the bottom right
Should this Sprite be automatically culled if out of range of the camera?
+A culled sprite has its renderable property set to 'false'.
+Be advised this is quite an expensive operation, as it has to calculate the bounds of the object every frame, so only enable it if you really need it.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
autoCull
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+
+
A flag indicating if the Sprite should be automatically camera culled or not.
By default Sprites have a Phaser.Physics Body attached to them. You can operate physics actions via this property, or null it to skip all physics updates.
A Sprite that is fixed to the camera uses its x/y coordinates as offsets from the top left of the camera.
+Note that if this Image is a child of a display object that has changed its position then the offset will be calculated from that.
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, BitmapData or PIXI.Texture.
If you would like the Sprite to have a lifespan once 'born' you can set this to a positive value. Handy for particles, bullets, etc.
+The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called.
+
+
+
+
+
+
+
+
+
+
Properties:
+
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
lifespan
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
The lifespan of the Sprite (in ms) before it will be killed.
@@ -4719,7 +6298,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
-
scale
+
<readonly> renderOrderID
@@ -4758,13 +6337,13 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
-
scale
+
renderOrderID
-Phaser.Point
+number
@@ -4774,7 +6353,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
-
The scale of the Sprite when rendered. By default it's set to 1 (no scale). You can modify it via scale.x or scale.y or scale.setTo(x, y). A value of 1 means no change to the scale, 0.5 means "half the size", 2 means "twice the size", etc.
+
The render order ID, reset every frame.
@@ -4791,7 +6370,7 @@ The lifespan is decremented by game.time.elapsed each update, once it reaches ze
Brings the Sprite to the top of the display list it is a child of. Sprites that are members of a Phaser.Group are only
+bought to the top of that Group, not the entire display list.
Crop allows you to crop the texture used to display this Image.
+Cropping takes place from the top-left of the Image and can be modified in real-time by providing an updated rectangle object.
Destroys the Sprite. This removes it from its parent group, destroys the input, event and animation handlers if present
+and nulls its reference to game, freeing it up for garbage collection.
Kills a Sprite. A killed Sprite has its alive, exists and visible properties all set to false.
+It will dispatch the onKilled event, you can listen to Sprite.events.onKilled for the signal.
+Note that killing a Sprite is a way for you to quickly recycle it in a Sprite pool, it doesn't free it up from memory.
+If you don't need this Sprite any more you should call Sprite.destroy instead.
Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
+This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
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, BitmapData or PIXI.Texture.
+
+
+
+
+
+
+
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.
Play an animation based on the given key. The animation should previously have been added via sprite.animations.add()
+If the requested animation is already playing this request will be ignored. If you need to reset an already running animation do so directly on the Animation object itself.
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
name
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The name of the animation to be played, e.g. "fire", "walk", "jump".
+
+
+
+
+
+
+
frameRate
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ null
+
+
+
+
+
The framerate to play the animation at. The speed is given in frames per second. If not provided the previously set frameRate of the Animation is used.
+
+
+
+
+
+
+
loop
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
Should the animation be looped after playback. If not provided the previously set loop value of the Animation is used.
+
+
+
+
+
+
+
killOnComplete
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ false
+
+
+
+
+
If set to true when the animation completes (only happens if loop=false) the parent Sprite will be killed.
Resets the Sprite. This places the Sprite at the given x/y world coordinates and then
+sets alive, exists, visible and renderable all to true. Also resets the outOfBounds state and health values.
+If the Sprite has a physics body that too is reset.
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
x
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The x coordinate (in world space) to position the Sprite at.
+
+
+
+
+
+
+
y
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The y coordinate (in world space) to position the Sprite at.
Brings a 'dead' Sprite back to life, optionally giving it the health value specified.
+A resurrected Sprite has its alive, exists and visible properties all set to true.
+It will dispatch the onRevived event, you can listen to Sprite.events.onRevived for the signal.
@@ -8576,7 +12008,7 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:52 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Tilemap.html b/docs/Phaser.Tilemap.html
index feae7e2e..789fd2db 100644
--- a/docs/Phaser.Tilemap.html
+++ b/docs/Phaser.Tilemap.html
@@ -182,6 +182,10 @@
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:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
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.
Creates a new TilemapLayer object. By default TilemapLayers are fixed to the camera.
+The layer parameter is important. If you've created your map in Tiled then you can get this by looking in Tiled and looking at the Layer name.
+Or you can open the JSON file it exports and look at the layers[].name value. Either way it must match.
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
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.
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:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
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.
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:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
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.
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:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
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.
Sets collision values on a tile in the set.
+You shouldn't usually call this method directly, instead use setCollision, setCollisionBetween or setCollisionByExclusion.
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
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.
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:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
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.
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:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
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.
@@ -5591,7 +10311,7 @@ Note that the tileset name can be found in the JSON file exported from Tiled, or
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:51 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.TilemapLayer.html b/docs/Phaser.TilemapLayer.html
index 6324e83e..fd9324a7 100644
--- a/docs/Phaser.TilemapLayer.html
+++ b/docs/Phaser.TilemapLayer.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -4600,7 +4634,7 @@ half as quickly as the 'normal' camera-locked layers do)
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:52 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.TilemapParser.html b/docs/Phaser.TilemapParser.html
index 8da89b64..00666bcf 100644
--- a/docs/Phaser.TilemapParser.html
+++ b/docs/Phaser.TilemapParser.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1443,7 +1477,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:52 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Tileset.html b/docs/Phaser.Tileset.html
index 2a1cd745..f33eb683 100644
--- a/docs/Phaser.Tileset.html
+++ b/docs/Phaser.Tileset.html
@@ -182,6 +182,10 @@
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:
-
-
-
-
-
-
-
Name
-
-
-
Type
-
-
-
Argument
-
-
-
-
Default
-
-
-
Description
-
-
-
-
-
-
-
-
-
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.
The index of the tileset in this tilemap, or null if not found.
-
-
-
-
-
-
- Type
-
-
-
-number
-
-
-
-
-
-
-
-
-
@@ -4679,946 +2445,6 @@ Mostly used as an internal function by calculateFaces.
-
-
-
-
-
-
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:
-
-
-
-
-
-
-
Name
-
-
-
Type
-
-
-
Argument
-
-
-
-
Default
-
-
-
Description
-
-
-
-
-
-
-
-
-
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.
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:
-
-
-
-
-
-
-
Name
-
-
-
Type
-
-
-
Argument
-
-
-
-
Default
-
-
-
Description
-
-
-
-
-
-
-
-
-
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.
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:
-
-
-
-
-
-
-
Name
-
-
-
Type
-
-
-
Argument
-
-
-
-
Default
-
-
-
Description
-
-
-
-
-
-
-
-
-
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.
Sets collision values on a tile in the set.
-You shouldn't usually call this method directly, instead use setCollision, setCollisionBetween or setCollisionByExclusion.
-
-
-
-
-
-
-
-
-
Parameters:
-
-
-
-
-
-
-
Name
-
-
-
Type
-
-
-
Argument
-
-
-
-
Default
-
-
-
Description
-
-
-
-
-
-
-
-
-
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.
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:
-
-
-
-
-
-
-
Name
-
-
-
Type
-
-
-
Argument
-
-
-
-
-
Description
-
-
-
-
-
-
-
-
-
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.
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:
-
-
-
-
-
-
-
Name
-
-
-
Type
-
-
-
Argument
-
-
-
-
-
Description
-
-
-
-
-
-
-
-
-
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.
@@ -6368,7 +2636,7 @@ If you want to set a callback for a tile at a specific location on the map then
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:35 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:52 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Time.html b/docs/Phaser.Time.html
index 8daece68..4206af8f 100644
--- a/docs/Phaser.Time.html
+++ b/docs/Phaser.Time.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -3082,7 +3116,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:52 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Timer.html b/docs/Phaser.Timer.html
index 0457fc84..62f289d1 100644
--- a/docs/Phaser.Timer.html
+++ b/docs/Phaser.Timer.html
@@ -182,6 +182,10 @@
Group
+
@@ -3746,7 +3780,7 @@ If the Timer is already running the delay will be calculated based on the timers
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:52 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.TimerEvent.html b/docs/Phaser.TimerEvent.html
index ca35f0e0..6cffa887 100644
--- a/docs/Phaser.TimerEvent.html
+++ b/docs/Phaser.TimerEvent.html
@@ -182,6 +182,10 @@
Group
+
@@ -1569,7 +1705,7 @@ It can call a specific callback, passing in optional parameters.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:52 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Touch.html b/docs/Phaser.Touch.html
index 0bcca464..db008289 100644
--- a/docs/Phaser.Touch.html
+++ b/docs/Phaser.Touch.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -2641,7 +2675,7 @@ Doesn't appear to be supported by most browsers on a canvas element yet.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:53 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Tween.html b/docs/Phaser.Tween.html
index 1730684c..c4c94645 100644
--- a/docs/Phaser.Tween.html
+++ b/docs/Phaser.Tween.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -3130,7 +3164,7 @@ Used in combination with repeat you can create endless loops.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:53 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.TweenManager.html b/docs/Phaser.TweenManager.html
index 93737650..8ef46d6d 100644
--- a/docs/Phaser.TweenManager.html
+++ b/docs/Phaser.TweenManager.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1634,7 +1668,7 @@ Please see https://github.com/sole/tw
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:53 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Utils.Debug.html b/docs/Phaser.Utils.Debug.html
index f4c4033c..72d1b6ee 100644
--- a/docs/Phaser.Utils.Debug.html
+++ b/docs/Phaser.Utils.Debug.html
@@ -182,6 +182,10 @@
Group
+
@@ -6856,7 +6939,7 @@ your game set to use Phaser.AUTO then swap it for Phaser.CANVAS to ensure WebGL
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:53 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Utils.html b/docs/Phaser.Utils.html
index 840f9c11..13275310 100644
--- a/docs/Phaser.Utils.html
+++ b/docs/Phaser.Utils.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1259,7 +1293,7 @@ dir = 1 (left), 2 (right), 3 (both)
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:36 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:53 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.World.html b/docs/Phaser.World.html
index 2328e0fa..72de4a0d 100644
--- a/docs/Phaser.World.html
+++ b/docs/Phaser.World.html
@@ -182,6 +182,10 @@
Group
+
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.
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.
@@ -10258,7 +9912,7 @@ Most objects won't have an update method set unless explicitly given one.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:37 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:53 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.html b/docs/Phaser.html
index ecf95de5..2c8d0676 100644
--- a/docs/Phaser.html
+++ b/docs/Phaser.html
@@ -182,6 +182,10 @@
Group
+
@@ -724,7 +767,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:25 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.js.html b/docs/Phaser.js.html
index 0c5ebf0e..51548077 100644
--- a/docs/Phaser.js.html
+++ b/docs/Phaser.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -427,7 +461,7 @@
var Phaser = Phaser || {
VERSION: '<%= version %>',
- DEV_VERSION: '1.1.4',
+ DEV_VERSION: '1.2',
GAMES: [],
AUTO: 0,
@@ -461,7 +495,7 @@ var Phaser = Phaser || {
CANVAS_PX_ROUND: false,
CANVAS_CLEAR_RECT: true
- };
+};
PIXI.InteractionManager = function (dummy) {
// We don't need this in Pixi, so we've removed it to save space
@@ -488,7 +522,7 @@ PIXI.InteractionManager = function (dummy) {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Plugin.js.html b/docs/Plugin.js.html
index 8302d705..65c12d15 100644
--- a/docs/Plugin.js.html
+++ b/docs/Plugin.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -559,7 +593,7 @@ Phaser.Plugin.prototype.constructor = Phaser.Plugin;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/PluginManager.js.html b/docs/PluginManager.js.html
index b2bd4a46..d7aab5e4 100644
--- a/docs/PluginManager.js.html
+++ b/docs/PluginManager.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -735,7 +769,7 @@ Phaser.PluginManager.prototype.constructor = Phaser.PluginManager;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Point.js.html b/docs/Point.js.html
index 34a3fe53..4029a52e 100644
--- a/docs/Point.js.html
+++ b/docs/Point.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1080,7 +1114,7 @@ Object.defineProperty(Phaser.Pointer.prototype, "worldY", {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Polygon.js.html b/docs/Polygon.js.html
index 2a9440c0..7b2d953b 100644
--- a/docs/Polygon.js.html
+++ b/docs/Polygon.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -465,7 +499,7 @@ Phaser.Polygon.prototype.constructor = Phaser.Polygon;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/QuadTree.js.html b/docs/QuadTree.js.html
index 856ca076..de48b23f 100644
--- a/docs/QuadTree.js.html
+++ b/docs/QuadTree.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -723,7 +757,7 @@ Phaser.QuadTree.prototype.constructor = Phaser.QuadTree;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/RandomDataGenerator.js.html b/docs/RandomDataGenerator.js.html
index 20d38246..436502a1 100644
--- a/docs/RandomDataGenerator.js.html
+++ b/docs/RandomDataGenerator.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -685,7 +719,7 @@ Phaser.RandomDataGenerator.prototype.constructor = Phaser.RandomDataGenerator;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Rectangle.js.html b/docs/Rectangle.js.html
index 4b5a9635..8287a74d 100644
--- a/docs/Rectangle.js.html
+++ b/docs/Rectangle.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -430,7 +464,7 @@
* @param {number} y - The y coordinate of the top-left corner of the Rectangle.
* @param {number} width - The width of the Rectangle.
* @param {number} height - The height of the Rectangle.
-* @return {Rectangle} This Rectangle object.
+* @return {Phaser.Rectangle} This Rectangle object.
*/
Phaser.Rectangle = function (x, y, width, height) {
@@ -468,7 +502,7 @@ Phaser.Rectangle.prototype = {
* @method Phaser.Rectangle#offset
* @param {number} dx - Moves the x value of the Rectangle object by this amount.
* @param {number} dy - Moves the y value of the Rectangle object by this amount.
- * @return {Rectangle} This Rectangle object.
+ * @return {Phaser.Rectangle} This Rectangle object.
*/
offset: function (dx, dy) {
@@ -482,11 +516,13 @@ Phaser.Rectangle.prototype = {
/**
* Adjusts the location of the Rectangle object using a Point object as a parameter. This method is similar to the Rectangle.offset() method, except that it takes a Point object as a parameter.
* @method Phaser.Rectangle#offsetPoint
- * @param {Point} point - A Point object to use to offset this Rectangle object.
- * @return {Rectangle} This Rectangle object.
+ * @param {Phaser.Point} point - A Point object to use to offset this Rectangle object.
+ * @return {Phaser.Rectangle} This Rectangle object.
*/
offsetPoint: function (point) {
+
return this.offset(point.x, point.y);
+
},
/**
@@ -496,7 +532,7 @@ Phaser.Rectangle.prototype = {
* @param {number} y - The y coordinate of the top-left corner of the Rectangle.
* @param {number} width - The width of the Rectangle in pixels.
* @param {number} height - The height of the Rectangle in pixels.
- * @return {Rectangle} This Rectangle object
+ * @return {Phaser.Rectangle} This Rectangle object
*/
setTo: function (x, y, width, height) {
@@ -508,7 +544,7 @@ Phaser.Rectangle.prototype = {
return this;
},
-
+
/**
* Runs Math.floor() on both the x and y values of this Rectangle.
* @method Phaser.Rectangle#floor
@@ -537,10 +573,12 @@ Phaser.Rectangle.prototype = {
* Copies the x, y, width and height properties from any given object to this Rectangle.
* @method Phaser.Rectangle#copyFrom
* @param {any} source - The object to copy from.
- * @return {Rectangle} This Rectangle object.
+ * @return {Phaser.Rectangle} This Rectangle object.
*/
copyFrom: function (source) {
+
return this.setTo(source.x, source.y, source.width, source.height);
+
},
/**
@@ -568,7 +606,9 @@ Phaser.Rectangle.prototype = {
* @return {Phaser.Rectangle} This Rectangle object.
*/
inflate: function (dx, dy) {
+
return Phaser.Rectangle.inflate(this, dx, dy);
+
},
/**
@@ -578,7 +618,9 @@ Phaser.Rectangle.prototype = {
* @return {Phaser.Point} The size of the Rectangle object.
*/
size: function (output) {
+
return Phaser.Rectangle.size(this, output);
+
},
/**
@@ -588,7 +630,9 @@ Phaser.Rectangle.prototype = {
* @return {Phaser.Rectangle}
*/
clone: function (output) {
+
return Phaser.Rectangle.clone(this, output);
+
},
/**
@@ -599,7 +643,9 @@ Phaser.Rectangle.prototype = {
* @return {boolean} A value of true if the Rectangle object contains the specified point; otherwise false.
*/
contains: function (x, y) {
+
return Phaser.Rectangle.contains(this, x, y);
+
},
/**
@@ -610,7 +656,9 @@ Phaser.Rectangle.prototype = {
* @return {boolean} A value of true if the Rectangle object contains the specified point; otherwise false.
*/
containsRect: function (b) {
+
return Phaser.Rectangle.containsRect(this, b);
+
},
/**
@@ -621,7 +669,9 @@ Phaser.Rectangle.prototype = {
* @return {boolean} A value of true if the two Rectangles have exactly the same values for the x, y, width and height properties; otherwise false.
*/
equals: function (b) {
+
return Phaser.Rectangle.equals(this, b);
+
},
/**
@@ -632,7 +682,9 @@ Phaser.Rectangle.prototype = {
* @return {Phaser.Rectangle} A Rectangle object that equals the area of intersection. If the Rectangles do not intersect, this method returns an empty Rectangle object; that is, a Rectangle with its x, y, width, and height properties set to 0.
*/
intersection: function (b, out) {
+
return Phaser.Rectangle.intersection(this, b, out);
+
},
/**
@@ -644,7 +696,9 @@ Phaser.Rectangle.prototype = {
* @return {boolean} A value of true if the specified object intersects with this Rectangle object; otherwise false.
*/
intersects: function (b, tolerance) {
+
return Phaser.Rectangle.intersects(this, b, tolerance);
+
},
/**
@@ -658,7 +712,9 @@ Phaser.Rectangle.prototype = {
* @return {boolean} A value of true if the specified object intersects with the Rectangle; otherwise false.
*/
intersectsRaw: function (left, right, top, bottom, tolerance) {
+
return Phaser.Rectangle.intersectsRaw(this, left, right, top, bottom, tolerance);
+
},
/**
@@ -669,7 +725,9 @@ Phaser.Rectangle.prototype = {
* @return {Phaser.Rectangle} A Rectangle object that is the union of the two Rectangles.
*/
union: function (b, out) {
+
return Phaser.Rectangle.union(this, b, out);
+
},
/**
@@ -678,237 +736,238 @@ Phaser.Rectangle.prototype = {
* @return {string} A string representation of the instance.
*/
toString: function () {
+
return "[{Rectangle (x=" + this.x + " y=" + this.y + " width=" + this.width + " height=" + this.height + " empty=" + this.empty + ")}]";
- }
-};
+ },
-Phaser.Rectangle.prototype.constructor = Phaser.Rectangle;
+ /**
+ * @name Phaser.Rectangle#halfWidth
+ * @property {number} halfWidth - Half of the width of the Rectangle.
+ * @readonly
+ */
+ get halfWidth() {
-/**
-* @name Phaser.Rectangle#halfWidth
-* @property {number} halfWidth - Half of the width of the Rectangle.
-* @readonly
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "halfWidth", {
-
- get: function () {
return Math.round(this.width / 2);
- }
-});
+ },
-/**
-* @name Phaser.Rectangle#halfHeight
-* @property {number} halfHeight - Half of the height of the Rectangle.
-* @readonly
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "halfHeight", {
+ /**
+ * @name Phaser.Rectangle#halfHeight
+ * @property {number} halfHeight - Half of the height of the Rectangle.
+ * @readonly
+ */
+ get halfHeight() {
- get: function () {
return Math.round(this.height / 2);
- }
-});
+ },
+
+ /**
+ * 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.
+ * @name Phaser.Rectangle#bottom
+ * @property {number} bottom - The sum of the y and height properties.
+ */
+ get bottom() {
-/**
-* 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.
-* @name Phaser.Rectangle#bottom
-* @property {number} bottom - The sum of the y and height properties.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "bottom", {
-
- get: function () {
return this.y + this.height;
+
},
- set: function (value) {
- if (value <= this.y) {
+ set bottom(value) {
+
+ if (value <= this.y)
+ {
this.height = 0;
- } else {
+ }
+ else
+ {
this.height = (this.y - value);
}
- }
+ },
-});
+ /**
+ * The location of the Rectangles bottom right corner as a Point object.
+ * @name Phaser.Rectangle#bottomRight
+ * @property {Phaser.Point} bottomRight - Gets or sets the location of the Rectangles bottom right corner as a Point object.
+ */
+ get bottomRight() {
-/**
-* The location of the Rectangles bottom right corner as a Point object.
-* @name Phaser.Rectangle#bottom
-* @property {Phaser.Point} bottomRight - Gets or sets the location of the Rectangles bottom right corner as a Point object.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "bottomRight", {
-
- get: function () {
return new Phaser.Point(this.right, this.bottom);
},
- set: function (value) {
+
+ set bottomRight(value) {
+
this.right = value.x;
this.bottom = value.y;
- }
-});
-
-/**
-* The x coordinate of the left of the Rectangle. Changing the left property of a Rectangle object has no effect on the y and height properties. However it does affect the width property, whereas changing the x value does not affect the width property.
-* @name Phaser.Rectangle#left
-* @property {number} left - The x coordinate of the left of the Rectangle.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "left", {
-
- get: function () {
- return this.x;
},
- set: function (value) {
- if (value >= this.right) {
+ /**
+ * The x coordinate of the left of the Rectangle. Changing the left property of a Rectangle object has no effect on the y and height properties. However it does affect the width property, whereas changing the x value does not affect the width property.
+ * @name Phaser.Rectangle#left
+ * @property {number} left - The x coordinate of the left of the Rectangle.
+ */
+ get left() {
+
+ return this.x;
+
+ },
+
+ set left(value) {
+
+ if (value >= this.right)
+ {
this.width = 0;
- } else {
+ }
+ else
+ {
this.width = this.right - value;
}
+
this.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.
-* @name Phaser.Rectangle#right
-* @property {number} right - The sum of the x and width properties.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "right", {
-
- get: function () {
- return this.x + this.width;
},
- set: function (value) {
- if (value <= this.x) {
+ /**
+ * 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.
+ * @name Phaser.Rectangle#right
+ * @property {number} right - The sum of the x and width properties.
+ */
+ get right() {
+
+ return this.x + this.width;
+
+ },
+
+ set right(value) {
+
+ if (value <= this.x)
+ {
this.width = 0;
- } else {
+ }
+ else
+ {
this.width = this.x + value;
}
- }
-});
+ },
+
+ /**
+ * The volume of the Rectangle derived from width * height.
+ * @name Phaser.Rectangle#volume
+ * @property {number} volume - The volume of the Rectangle derived from width * height.
+ * @readonly
+ */
+ get volume() {
-/**
-* The volume of the Rectangle derived from width * height.
-* @name Phaser.Rectangle#volume
-* @property {number} volume - The volume of the Rectangle derived from width * height.
-* @readonly
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "volume", {
-
- get: function () {
return this.width * this.height;
- }
-});
+ },
+
+ /**
+ * The perimeter size of the Rectangle. This is the sum of all 4 sides.
+ * @name Phaser.Rectangle#perimeter
+ * @property {number} perimeter - The perimeter size of the Rectangle. This is the sum of all 4 sides.
+ * @readonly
+ */
+ get perimeter() {
-/**
-* The perimeter size of the Rectangle. This is the sum of all 4 sides.
-* @name Phaser.Rectangle#perimeter
-* @property {number} perimeter - The perimeter size of the Rectangle. This is the sum of all 4 sides.
-* @readonly
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "perimeter", {
-
- get: function () {
return (this.width * 2) + (this.height * 2);
- }
-});
+ },
+
+ /**
+ * The x coordinate of the center of the Rectangle.
+ * @name Phaser.Rectangle#centerX
+ * @property {number} centerX - The x coordinate of the center of the Rectangle.
+ */
+ get centerX() {
-/**
-* The x coordinate of the center of the Rectangle.
-* @name Phaser.Rectangle#centerX
-* @property {number} centerX - The x coordinate of the center of the Rectangle.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "centerX", {
-
- get: function () {
return this.x + this.halfWidth;
+
},
- set: function (value) {
+ set centerX(value) {
+
this.x = value - this.halfWidth;
- }
-});
+ },
+
+ /**
+ * The y coordinate of the center of the Rectangle.
+ * @name Phaser.Rectangle#centerY
+ * @property {number} centerY - The y coordinate of the center of the Rectangle.
+ */
+ get centerY() {
-/**
-* The y coordinate of the center of the Rectangle.
-* @name Phaser.Rectangle#centerY
-* @property {number} centerY - The y coordinate of the center of the Rectangle.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "centerY", {
-
- get: function () {
return this.y + this.halfHeight;
+
},
- set: function (value) {
+ set centerY(value) {
+
this.y = value - this.halfHeight;
- }
-});
-
-/**
-* The y coordinate of the top of the Rectangle. Changing the top property of a Rectangle object has no effect on the x and width properties.
-* However it does affect the height property, whereas changing the y value does not affect the height property.
-* @name Phaser.Rectangle#top
-* @property {number} top - The y coordinate of the top of the Rectangle.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "top", {
-
- get: function () {
- return this.y;
},
- set: function (value) {
- if (value >= this.bottom) {
+ /**
+ * The y coordinate of the top of the Rectangle. Changing the top property of a Rectangle object has no effect on the x and width properties.
+ * However it does affect the height property, whereas changing the y value does not affect the height property.
+ * @name Phaser.Rectangle#top
+ * @property {number} top - The y coordinate of the top of the Rectangle.
+ */
+ get top() {
+
+ return this.y;
+
+ },
+
+ set top(value) {
+
+ if (value >= this.bottom)
+ {
this.height = 0;
this.y = value;
- } else {
+ }
+ else
+ {
this.height = (this.bottom - value);
}
- }
-});
+ },
-/**
-* The location of the Rectangles top left corner as a Point object.
-* @name Phaser.Rectangle#topLeft
-* @property {Phaser.Point} topLeft - The location of the Rectangles top left corner as a Point object.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "topLeft", {
+ /**
+ * The location of the Rectangles top left corner as a Point object.
+ * @name Phaser.Rectangle#topLeft
+ * @property {Phaser.Point} topLeft - The location of the Rectangles top left corner as a Point object.
+ */
+ get topLeft() {
- get: function () {
return new Phaser.Point(this.x, this.y);
+
},
- set: function (value) {
+ set topLeft(value) {
+
this.x = value.x;
this.y = value.y;
- }
-});
-
-/**
-* Determines whether or not this Rectangle object is empty. A Rectangle object is empty if its width or height is less than or equal to 0.
-* If set to true then all of the Rectangle properties are set to 0.
-* @name Phaser.Rectangle#empty
-* @property {boolean} empty - Gets or sets the Rectangles empty state.
-*/
-Object.defineProperty(Phaser.Rectangle.prototype, "empty", {
-
- get: function () {
- return (!this.width || !this.height);
},
- set: function (value) {
+ /**
+ * Determines whether or not this Rectangle object is empty. A Rectangle object is empty if its width or height is less than or equal to 0.
+ * If set to true then all of the Rectangle properties are set to 0.
+ * @name Phaser.Rectangle#empty
+ * @property {boolean} empty - Gets or sets the Rectangles empty state.
+ */
+ get empty() {
+
+ return (!this.width || !this.height);
+
+ },
+
+ set empty(value) {
if (value === true)
{
@@ -917,7 +976,9 @@ Object.defineProperty(Phaser.Rectangle.prototype, "empty", {
}
-});
+};
+
+Phaser.Rectangle.prototype.constructor = Phaser.Rectangle;
/**
* Increases the size of the Rectangle object by the specified amounts. The center point of the Rectangle object stays the same, and its size increases to the left and right by the dx value, and to the top and the bottom by the dy value.
@@ -928,11 +989,14 @@ Object.defineProperty(Phaser.Rectangle.prototype, "empty", {
* @return {Phaser.Rectangle} This Rectangle object.
*/
Phaser.Rectangle.inflate = function (a, dx, dy) {
+
a.x -= dx;
a.width += 2 * dx;
a.y -= dy;
a.height += 2 * dy;
+
return a;
+
};
/**
@@ -943,7 +1007,9 @@ Phaser.Rectangle.inflate = function (a, dx, dy) {
* @return {Phaser.Rectangle} The Rectangle object.
*/
Phaser.Rectangle.inflatePoint = function (a, point) {
+
return Phaser.Rectangle.inflate(a, point.x, point.y);
+
};
/**
@@ -954,8 +1020,18 @@ Phaser.Rectangle.inflatePoint = function (a, point) {
* @return {Phaser.Point} The size of the Rectangle object
*/
Phaser.Rectangle.size = function (a, output) {
- if (typeof output === "undefined") { output = new Phaser.Point(); }
- return output.setTo(a.width, a.height);
+
+ if (typeof output === "undefined")
+ {
+ output = new Phaser.Point(a.width, a.height);
+ }
+ else
+ {
+ output.setTo(a.width, a.height);
+ }
+
+ return output;
+
};
/**
@@ -966,8 +1042,18 @@ Phaser.Rectangle.size = function (a, output) {
* @return {Phaser.Rectangle}
*/
Phaser.Rectangle.clone = function (a, output) {
- if (typeof output === "undefined") { output = new Phaser.Rectangle(); }
- return output.setTo(a.x, a.y, a.width, a.height);
+
+ if (typeof output === "undefined")
+ {
+ output = new Phaser.Rectangle(a.x, a.y, a.width, a.height);
+ }
+ else
+ {
+ output.setTo(a.x, a.y, a.width, a.height);
+ }
+
+ return output;
+
};
/**
@@ -979,11 +1065,31 @@ Phaser.Rectangle.clone = function (a, output) {
* @return {boolean} A value of true if the Rectangle object contains the specified point; otherwise false.
*/
Phaser.Rectangle.contains = function (a, x, y) {
+
+ if (a.width <= 0 || a.height <= 0)
+ {
+ return false;
+ }
+
return (x >= a.x && x <= a.right && y >= a.y && y <= a.bottom);
+
};
+/**
+* Determines whether the specified coordinates are contained within the region defined by the given raw values.
+* @method Phaser.Rectangle.containsRaw
+* @param {number} rx - The x coordinate of the top left of the area.
+* @param {number} ry - The y coordinate of the top left of the area.
+* @param {number} rw - The width of the area.
+* @param {number} rh - The height of the area.
+* @param {number} x - The x coordinate of the point to test.
+* @param {number} y - The y coordinate of the point to test.
+* @return {boolean} A value of true if the Rectangle object contains the specified point; otherwise false.
+*/
Phaser.Rectangle.containsRaw = function (rx, ry, rw, rh, x, y) {
+
return (x >= rx && x <= (rx + rw) && y >= ry && y <= (ry + rh));
+
};
/**
@@ -994,7 +1100,9 @@ Phaser.Rectangle.containsRaw = function (rx, ry, rw, rh, x, y) {
* @return {boolean} A value of true if the Rectangle object contains the specified point; otherwise false.
*/
Phaser.Rectangle.containsPoint = function (a, point) {
+
return Phaser.Rectangle.contains(a, point.x, point.y);
+
};
/**
@@ -1026,7 +1134,9 @@ Phaser.Rectangle.containsRect = function (a, b) {
* @return {boolean} A value of true if the two Rectangles have exactly the same values for the x, y, width and height properties; otherwise false.
*/
Phaser.Rectangle.equals = function (a, b) {
+
return (a.x == b.x && a.y == b.y && a.width == b.width && a.height == b.height);
+
};
/**
@@ -1034,22 +1144,25 @@ Phaser.Rectangle.equals = function (a, b) {
* @method Phaser.Rectangle.intersection
* @param {Phaser.Rectangle} a - The first Rectangle object.
* @param {Phaser.Rectangle} b - The second Rectangle object.
-* @param {Phaser.Rectangle} [out] - Optional Rectangle object. If given the intersection values will be set into this object, otherwise a brand new Rectangle object will be created and returned.
+* @param {Phaser.Rectangle} [output] - Optional Rectangle object. If given the intersection values will be set into this object, otherwise a brand new Rectangle object will be created and returned.
* @return {Phaser.Rectangle} A Rectangle object that equals the area of intersection. If the Rectangles do not intersect, this method returns an empty Rectangle object; that is, a Rectangle with its x, y, width, and height properties set to 0.
*/
-Phaser.Rectangle.intersection = function (a, b, out) {
+Phaser.Rectangle.intersection = function (a, b, output) {
- out = out || new Phaser.Rectangle();
+ if (typeof output === "undefined")
+ {
+ output = new Phaser.Rectangle();
+ }
if (Phaser.Rectangle.intersects(a, b))
{
- out.x = Math.max(a.x, b.x);
- out.y = Math.max(a.y, b.y);
- out.width = Math.min(a.right, b.right) - out.x;
- out.height = Math.min(a.bottom, b.bottom) - out.y;
+ output.x = Math.max(a.x, b.x);
+ output.y = Math.max(a.y, b.y);
+ output.width = Math.min(a.right, b.right) - output.x;
+ output.height = Math.min(a.bottom, b.bottom) - output.y;
}
- return out;
+ return output;
};
@@ -1095,16 +1208,23 @@ Phaser.Rectangle.intersectsRaw = function (a, left, right, top, bottom, toleranc
* @method Phaser.Rectangle.union
* @param {Phaser.Rectangle} a - The first Rectangle object.
* @param {Phaser.Rectangle} b - The second Rectangle object.
-* @param {Phaser.Rectangle} [out] - Optional Rectangle object. If given the new values will be set into this object, otherwise a brand new Rectangle object will be created and returned.
+* @param {Phaser.Rectangle} [output] - Optional Rectangle object. If given the new values will be set into this object, otherwise a brand new Rectangle object will be created and returned.
* @return {Phaser.Rectangle} A Rectangle object that is the union of the two Rectangles.
*/
-Phaser.Rectangle.union = function (a, b, out) {
+Phaser.Rectangle.union = function (a, b, output) {
- if (typeof out === "undefined") { out = new Phaser.Rectangle(); }
+ if (typeof output === "undefined")
+ {
+ output = new Phaser.Rectangle();
+ }
- return out.setTo(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.max(a.right, b.right) - Math.min(a.left, b.left), Math.max(a.bottom, b.bottom) - Math.min(a.top, b.top));
+ return output.setTo(Math.min(a.x, b.x), Math.min(a.y, b.y), Math.max(a.right, b.right) - Math.min(a.left, b.left), Math.max(a.bottom, b.bottom) - Math.min(a.top, b.top));
};
+
+// Because PIXI uses its own Rectangle, we'll replace it with ours to avoid duplicating code or confusion.
+PIXI.Rectangle = Phaser.Rectangle;
+PIXI.EmptyRectangle = new Phaser.Rectangle(0, 0, 0, 0);
@@ -1126,7 +1246,7 @@ Phaser.Rectangle.union = function (a, b, out) {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/RenderTexture.js.html b/docs/RenderTexture.js.html
index b85fcadd..192f88da 100644
--- a/docs/RenderTexture.js.html
+++ b/docs/RenderTexture.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -595,7 +629,7 @@ Phaser.RequestAnimationFrame.prototype.constructor = Phaser.RequestAnimationFram
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/SAT.js.html b/docs/SAT.js.html
index daffcd9a..36c69c9c 100644
--- a/docs/SAT.js.html
+++ b/docs/SAT.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1297,7 +1331,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Signal.js.html b/docs/Signal.js.html
index 02fe379b..d9630889 100644
--- a/docs/Signal.js.html
+++ b/docs/Signal.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -740,7 +774,7 @@ Phaser.Signal.prototype.constructor = Phaser.Signal;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/SignalBinding.html b/docs/SignalBinding.html
index b3c0f540..cc07418e 100644
--- a/docs/SignalBinding.html
+++ b/docs/SignalBinding.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -733,7 +767,7 @@ Inspired by Joa Ebert AS3 SignalBinding and Robert Penner's Slot classes.
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:37 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:53 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/SignalBinding.js.html b/docs/SignalBinding.js.html
index 8bc0854f..823a47f6 100644
--- a/docs/SignalBinding.js.html
+++ b/docs/SignalBinding.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -600,7 +634,7 @@ Phaser.SignalBinding.prototype.constructor = Phaser.SignalBinding;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/SinglePad.js.html b/docs/SinglePad.js.html
index af2fdfca..79235ff1 100644
--- a/docs/SinglePad.js.html
+++ b/docs/SinglePad.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1005,7 +1039,7 @@ Object.defineProperty(Phaser.SinglePad.prototype, "index", {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Sound.js.html b/docs/Sound.js.html
index 03167d6d..b1e79fca 100644
--- a/docs/Sound.js.html
+++ b/docs/Sound.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1261,7 +1295,7 @@ Object.defineProperty(Phaser.Sound.prototype, "volume", {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/SoundManager.js.html b/docs/SoundManager.js.html
index 6fa385c5..e36bc9a3 100644
--- a/docs/SoundManager.js.html
+++ b/docs/SoundManager.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -918,7 +952,7 @@ Object.defineProperty(Phaser.SoundManager.prototype, "volume", {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Sprite.js.html b/docs/Sprite.js.html
index cce3609a..17059fa6 100644
--- a/docs/Sprite.js.html
+++ b/docs/Sprite.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -455,17 +489,6 @@ Phaser.Sprite = function (game, x, y, key, frame) {
*/
this.exists = true;
- /**
- * @property {boolean} alive - This is a handy little var your game can use to determine if a sprite is alive or not, it doesn't effect rendering.
- * @default
- */
- this.alive = true;
-
- /**
- * @property {Phaser.Group} group - The parent Group of this Sprite. This is usually set after Sprite instantiation by the parent.
- */
- this.group = null;
-
/**
* @property {string} name - The user defined name given to this Sprite.
* @default
@@ -478,20 +501,6 @@ Phaser.Sprite = function (game, x, y, key, frame) {
*/
this.type = Phaser.SPRITE;
- /**
- * @property {number} renderOrderID - Used by the Renderer and Input Manager to control picking order.
- * @default
- */
- this.renderOrderID = -1;
-
- /**
- * If you would like the Sprite to have a lifespan once 'born' you can set this to a positive value. Handy for particles, bullets, etc.
- * The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called.
- * @property {number} lifespan - The lifespan of the Sprite (in ms) before it will be killed.
- * @default
- */
- this.lifespan = 0;
-
/**
* @property {Phaser.Events} events - The Events you can subscribe to that are dispatched when certain things happen on this Sprite or its components.
*/
@@ -502,104 +511,28 @@ Phaser.Sprite = function (game, x, y, key, frame) {
*/
this.animations = new Phaser.AnimationManager(this);
- /**
- * @property {Phaser.InputHandler} input - The Input Handler Component.
- */
- this.input = new Phaser.InputHandler(this);
-
/**
* @property {string|Phaser.RenderTexture|Phaser.BitmapData|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, BitmapData or PIXI.Texture.
*/
this.key = key;
/**
- * @property {Phaser.Frame} currentFrame - A reference to the currently displayed frame.
+ * @property {number} _frame - Internal cache var.
+ * @private
*/
- this.currentFrame = null;
-
- if (key instanceof Phaser.RenderTexture)
- {
- PIXI.Sprite.call(this, key);
-
- this.currentFrame = this.game.cache.getTextureFrame(key.name);
- }
- else if (key instanceof Phaser.BitmapData)
- {
- PIXI.Sprite.call(this, key.texture, key.textureFrame);
-
- this.currentFrame = key.textureFrame;
- }
- else if (key instanceof PIXI.Texture)
- {
- PIXI.Sprite.call(this, key);
-
- this.currentFrame = frame;
- }
- else
- {
- if (key === null || typeof key === 'undefined')
- {
- key = '__default';
- this.key = key;
- }
- else if (typeof key === 'string' && this.game.cache.checkImageKey(key) === false)
- {
- key = '__missing';
- this.key = key;
- }
-
- PIXI.Sprite.call(this, PIXI.TextureCache[key]);
-
- if (this.game.cache.isSpriteSheet(key))
- {
- this.animations.loadFrameData(this.game.cache.getFrameData(key));
-
- if (frame !== null)
- {
- if (typeof frame === 'string')
- {
- this.frameName = frame;
- }
- else
- {
- this.frame = frame;
- }
- }
- }
- else
- {
- this.currentFrame = this.game.cache.getFrame(key);
- }
- }
+ this._frame = 0;
/**
- * The rectangular area from the texture that will be rendered.
- * @property {Phaser.Rectangle} textureRegion
+ * @property {string} _frameName - Internal cache var.
+ * @private
*/
- this.textureRegion = new Phaser.Rectangle(this.texture.frame.x, this.texture.frame.y, this.texture.frame.width, this.texture.frame.height);
+ this._frameName = '';
- /**
- * The anchor sets the origin point of the texture.
- * The default is 0,0 this means the textures origin is the top left
- * Setting than anchor to 0.5,0.5 means the textures origin is centered
- * Setting the anchor to 1,1 would mean the textures origin points will be the bottom right
- *
- * @property {Phaser.Point} anchor - The anchor around which rotation and scaling takes place.
- */
- this.anchor = new Phaser.Point();
+ PIXI.Sprite.call(this, PIXI.TextureCache['__default']);
- /**
- * @property {number} x - The x coordinate in world space of this Sprite.
- */
- this.x = x;
-
- /**
- * @property {number} y - The y coordinate in world space of this Sprite.
- */
- this.y = y;
+ this.loadTexture(key, frame);
- this.position.x = x;
- this.position.y = y;
+ this.position.set(x, y);
/**
* @property {Phaser.Point} world - The world coordinates of this Sprite. This differs from the x/y coordinates which are relative to the Sprites container.
@@ -609,6 +542,7 @@ Phaser.Sprite = function (game, x, y, key, frame) {
/**
* Should this Sprite be automatically culled if out of range of the camera?
* A culled sprite has its renderable property set to 'false'.
+ * Be advised this is quite an expensive operation, as it has to calculate the bounds of the object every frame, so only enable it if you really need it.
*
* @property {boolean} autoCull - A flag indicating if the Sprite should be automatically camera culled or not.
* @default
@@ -616,118 +550,18 @@ Phaser.Sprite = function (game, x, y, key, frame) {
this.autoCull = false;
/**
- * @property {Phaser.Point} scale - The scale of the Sprite when rendered. By default it's set to 1 (no scale). You can modify it via scale.x or scale.y or scale.setTo(x, y). A value of 1 means no change to the scale, 0.5 means "half the size", 2 means "twice the size", etc.
+ * A Sprite that is fixed to the camera uses its x/y coordinates as offsets from the top left of the camera.
+ * Note that if this Image is a child of a display object that has changed its position then the offset will be calculated from that.
+ * @property {boolean} fixedToCamera - Fixes this Sprite to the Camera.
+ * @default
*/
- this.scale = new Phaser.Point(1, 1);
+ this.fixedToCamera = false;
/**
- * @property {object} _cache - A mini cache for storing all of the calculated values.
- * @private
+ * @property {Phaser.InputHandler|null} input - The Input Handler for this object. Needs to be enabled with image.inputEnabled = true before you can use it.
*/
- this._cache = {
+ this.input = null;
- fresh: true,
- dirty: false,
-
- // Transform cache
- a00: -1,
- a01: -1,
- a02: -1,
- a10: -1,
- a11: -1,
- a12: -1,
- id: -1,
-
- // Input specific transform cache
- i01: -1,
- i10: -1,
- idi: -1,
-
- // Bounds check
- left: null,
- right: null,
- top: null,
- bottom: null,
-
- // delta cache
- prevX: x,
- prevY: y,
-
- // The previous calculated position
- x: -1,
- y: -1,
-
- // The actual scale values based on the worldTransform
- scaleX: 1,
- scaleY: 1,
-
- // The width/height of the image, based on the un-modified frame size multiplied by the final calculated scale size
- width: this.currentFrame.sourceSizeW,
- height: this.currentFrame.sourceSizeH,
-
- // The actual width/height of the image if from a trimmed atlas, multiplied by the final calculated scale size
- halfWidth: Math.floor(this.currentFrame.sourceSizeW / 2),
- halfHeight: Math.floor(this.currentFrame.sourceSizeH / 2),
-
- // The width/height of the image, based on the un-modified frame size multiplied by the final calculated scale size
- calcWidth: -1,
- calcHeight: -1,
-
- // The current frame details
- // frameID: this.currentFrame.uuid, frameWidth: this.currentFrame.width, frameHeight: this.currentFrame.height,
- frameID: -1,
- frameWidth: this.currentFrame.width,
- frameHeight: this.currentFrame.height,
-
- // If this sprite visible to the camera (regardless of being set to visible or not)
- cameraVisible: true,
-
- // Crop cache
- cropX: 0,
- cropY: 0,
- cropWidth: this.currentFrame.sourceSizeW,
- cropHeight: this.currentFrame.sourceSizeH
-
- };
-
- /**
- * @property {Phaser.Point} offset - Corner point defaults. Should not typically be modified.
- */
- this.offset = new Phaser.Point();
-
- /**
- * @property {Phaser.Point} center - A Point containing the center coordinate of the Sprite. Takes rotation and scale into account.
- */
- this.center = new Phaser.Point(x + Math.floor(this._cache.width / 2), y + Math.floor(this._cache.height / 2));
-
- /**
- * @property {Phaser.Point} topLeft - A Point containing the top left coordinate of the Sprite. Takes rotation and scale into account.
- */
- this.topLeft = new Phaser.Point(x, y);
-
- /**
- * @property {Phaser.Point} topRight - A Point containing the top right coordinate of the Sprite. Takes rotation and scale into account.
- */
- this.topRight = new Phaser.Point(x + this._cache.width, y);
-
- /**
- * @property {Phaser.Point} bottomRight - A Point containing the bottom right coordinate of the Sprite. Takes rotation and scale into account.
- */
- this.bottomRight = new Phaser.Point(x + this._cache.width, y + this._cache.height);
-
- /**
- * @property {Phaser.Point} bottomLeft - A Point containing the bottom left coordinate of the Sprite. Takes rotation and scale into account.
- */
- this.bottomLeft = new Phaser.Point(x, y + this._cache.height);
-
- /**
- * This Rectangle object fully encompasses the Sprite and is updated in real-time.
- * The bounds is the full bounding area after rotation and scale have been taken into account. It should not be modified directly.
- * It's used for Camera culling and physics body alignment.
- * @property {Phaser.Rectangle} bounds
- */
- this.bounds = new Phaser.Rectangle(x, y, this._cache.width, this._cache.height);
-
/**
* @property {Phaser.Physics.Arcade.Body} body - By default Sprites have a Phaser.Physics Body attached to them. You can operate physics actions via this property, or null it to skip all physics updates.
*/
@@ -739,15 +573,12 @@ Phaser.Sprite = function (game, x, y, key, frame) {
this.health = 1;
/**
- * @property {boolean} inWorld - This value is set to true if the Sprite is positioned within the World, otherwise false.
- */
- this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds);
-
- /**
- * @property {number} inWorldThreshold - A threshold value applied to the inWorld check. If you don't want a Sprite to be considered "out of the world" until at least 100px away for example then set it to 100.
+ * If you would like the Sprite to have a lifespan once 'born' you can set this to a positive value. Handy for particles, bullets, etc.
+ * The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called.
+ * @property {number} lifespan - The lifespan of the Sprite (in ms) before it will be killed.
* @default
*/
- this.inWorldThreshold = 0;
+ this.lifespan = 0;
/**
* @property {boolean} outOfBoundsKill - If true the Sprite is killed as soon as Sprite.inWorld is false.
@@ -755,72 +586,47 @@ Phaser.Sprite = function (game, x, y, key, frame) {
*/
this.outOfBoundsKill = false;
- /**
- * @property {boolean} _outOfBoundsFired - Internal flag.
- * @private
- * @default
- */
- this._outOfBoundsFired = false;
-
- /**
- * A Sprite 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 Sprite to the Camera.
- * @default
- */
- this.fixedToCamera = false;
-
- /**
- * @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(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.
- * The crop is only applied if you have set Sprite.cropEnabled to true.
- * @property {Phaser.Rectangle} crop - The crop Rectangle applied to the Sprite texture before rendering.
- * @default
- */
- this.crop = new Phaser.Rectangle(0, 0, this._cache.width, this._cache.height);
-
- /**
- * @property {boolean} cropEnabled - If true the Sprite.crop property is used to crop the texture before render. Set to false to disable.
- * @default
- */
- this.cropEnabled = false;
-
/**
* @property {boolean} debug - Handy flag to use with Game.enableStep
* @default
*/
this.debug = false;
- this.updateCache();
- this.updateBounds();
+ /**
+ * @property {boolean} _outOfBoundsFired - Internal flag.
+ * @private
+ */
+ this._outOfBoundsFired = false;
/**
- * @property {PIXI.Point} pivot - The pivot point of the displayObject that it rotates around.
+ * @property {array} _cache - A small cache for previous step values. 0 = x, 1 = y, 2 = rotation, 3 = renderID, 4 = fresh? (0 = no, 1 = yes)
+ * @private
*/
+ this._cache = [0, 0, 0, 0, 1];
};
-// Needed to keep the PIXI.Sprite constructor in the prototype chain (as the core pixi renderer uses an instanceof check sadly)
Phaser.Sprite.prototype = Object.create(PIXI.Sprite.prototype);
Phaser.Sprite.prototype.constructor = Phaser.Sprite;
/**
-* Automatically called by World.preUpdate. Handles cache updates, lifespan checks, animation updates and physics updates.
+* Automatically called by World.preUpdate.
*
* @method Phaser.Sprite#preUpdate
* @memberof Phaser.Sprite
*/
Phaser.Sprite.prototype.preUpdate = function() {
- if (this._cache.fresh)
+ if (this._cache[4] === 1)
{
- this.world.setTo(this.parent.position.x + this.x, this.parent.position.y + this.y);
+ console.log('sprite cache fresh');
+ this.world.setTo(this.parent.position.x + this.position.x, this.parent.position.y + this.position.y);
this.worldTransform[2] = this.world.x;
this.worldTransform[5] = this.world.y;
- this._cache.fresh = false;
+ // this._cache[0] = this.world.x;
+ // this._cache[1] = this.world.y;
+ // this._cache[2] = this.rotation;
+ this._cache[4] = 0;
if (this.body)
{
@@ -833,11 +639,13 @@ Phaser.Sprite.prototype.preUpdate = function() {
return;
}
- if (!this.exists || (this.group && !this.group.exists))
+ this._cache[0] = this.world.x;
+ this._cache[1] = this.world.y;
+ this._cache[2] = this.rotation;
+
+ if (!this.exists || !this.parent.exists)
{
this.renderOrderID = -1;
-
- // Skip children if not exists
return false;
}
@@ -852,175 +660,30 @@ Phaser.Sprite.prototype.preUpdate = function() {
}
}
- this._cache.dirty = false;
-
- if (this.visible)
+ if (this.autoCull)
{
- this.renderOrderID = this.game.world.currentRenderOrderID++;
- }
-
- this.updateCache();
-
- this.updateAnimation();
-
- this.updateCrop();
-
- // Re-run the camera visibility check
- if (this._cache.dirty || this.world.x !== this._cache.prevX || this.world.y !== this._cache.prevY)
- {
- this.updateBounds();
- }
-
- if (this.body)
- {
- this.body.preUpdate();
- }
-
- return true;
-
-};
-
-/**
-* Internal function called by preUpdate.
-*
-* @method Phaser.Sprite#updateCache
-* @memberof Phaser.Sprite
-*/
-Phaser.Sprite.prototype.updateCache = function() {
-
- this._cache.prevX = this.world.x;
- this._cache.prevY = this.world.y;
-
- if (this.fixedToCamera)
- {
- this.x = this.game.camera.view.x + this.cameraOffset.x;
- this.y = this.game.camera.view.y + this.cameraOffset.y;
+ // Won't get rendered but will still get its transform updated
+ this.renderable = this.game.world.camera.screenView.intersects(this.getBounds());
}
this.world.setTo(this.game.camera.x + this.worldTransform[2], this.game.camera.y + this.worldTransform[5]);
- if (this.worldTransform[1] != this._cache.i01 || this.worldTransform[3] != this._cache.i10 || this.worldTransform[0] != this._cache.a00 || this.worldTransform[41] != this._cache.a11)
+ if (this.visible)
{
- this._cache.a00 = this.worldTransform[0]; // scaleX a |a c tx|
- this._cache.a01 = this.worldTransform[1]; // skewY c |b d ty|
- this._cache.a10 = this.worldTransform[3]; // skewX b |0 0 1|
- this._cache.a11 = this.worldTransform[4]; // scaleY d
-
- this._cache.i01 = this.worldTransform[1]; // skewY c (remains non-modified for input checks)
- this._cache.i10 = this.worldTransform[3]; // skewX b (remains non-modified for input checks)
-
- this._cache.scaleX = Math.sqrt((this._cache.a00 * this._cache.a00) + (this._cache.a01 * this._cache.a01)); // round this off a bit?
- this._cache.scaleY = Math.sqrt((this._cache.a10 * this._cache.a10) + (this._cache.a11 * this._cache.a11)); // round this off a bit?
-
- 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 = true;
+ this._cache[3] = this.game.world.currentRenderOrderID++;
}
- this._cache.a02 = this.worldTransform[2]; // translateX tx
- this._cache.a12 = this.worldTransform[5]; // translateY ty
+ this.animations.update();
-};
-
-/**
-* Internal function called by preUpdate.
-*
-* @method Phaser.Sprite#updateAnimation
-* @memberof Phaser.Sprite
-*/
-Phaser.Sprite.prototype.updateAnimation = function() {
-
- if (this.animations.update() || (this.currentFrame && this.currentFrame.uuid != this._cache.frameID))
+ if (!this.inWorld && Phaser.Rectangle.intersects(this.getBounds(), this.game.world.bounds, this.inWorldThreshold))
{
- 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 = true;
- }
-
-};
-
-/**
-* Internal function called by preUpdate.
-*
-* @method Phaser.Sprite#updateCrop
-* @memberof Phaser.Sprite
-*/
-Phaser.Sprite.prototype.updateCrop = function() {
-
- // This only runs if crop is enabled
- if (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 = true;
-
- PIXI.Texture.frameUpdates.push(this.texture);
- }
-
-};
-
-/**
-* Internal function called by preUpdate.
-*
-* @method Phaser.Sprite#updateBounds
-* @memberof Phaser.Sprite
-*/
-Phaser.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 = Phaser.Math.min(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
- this._cache.right = Phaser.Math.max(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
- this._cache.top = Phaser.Math.min(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y);
- this._cache.bottom = Phaser.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 = true;
-
- if (this.inWorld === false)
- {
- // Sprite WAS out of the screen, is it still?
- this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds, this.inWorldThreshold);
-
- if (this.inWorld)
- {
- // It's back again, reset the OOB check
- this._outOfBoundsFired = false;
- }
+ // It's back again, reset the OOB check
+ this._outOfBoundsFired = false;
}
else
{
// Sprite WAS in the screen, has it now left?
- this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds, this.inWorldThreshold);
+ this.inWorld = Phaser.Rectangle.intersects(this.getBounds(), this.game.world.bounds, this.inWorldThreshold);
if (this.inWorld === false)
{
@@ -1034,7 +697,7 @@ Phaser.Sprite.prototype.updateBounds = function() {
}
}
- this._cache.cameraVisible = Phaser.Rectangle.intersects(this.game.world.camera.screenView, this.bounds, 0);
+ this._cache.cameraVisible = Phaser.Rectangle.intersects(this.game.world.camera.screenView, this.getBounds(), 0);
if (this.autoCull)
{
@@ -1042,59 +705,12 @@ Phaser.Sprite.prototype.updateBounds = function() {
this.renderable = this._cache.cameraVisible;
}
-};
+ if (this.body)
+ {
+ this.body.preUpdate();
+ }
-/**
-* Gets the local position of a coordinate relative to the Sprite, factoring in rotation and scale.
-* Mostly only used internally.
-*
-* @method Phaser.Sprite#getLocalPosition
-* @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 - y coordinate within the Sprite to translate.
-* @return {Phaser.Point} The translated point.
-*/
-Phaser.Sprite.prototype.getLocalPosition = function(p, x, y) {
-
- p.x = ((this._cache.a11 * this._cache.id * x + -this._cache.a01 * this._cache.id * y + (this._cache.a12 * this._cache.a01 - this._cache.a02 * this._cache.a11) * this._cache.id) * this.scale.x) + this._cache.a02;
- p.y = ((this._cache.a00 * this._cache.id * y + -this._cache.a10 * this._cache.id * x + (-this._cache.a12 * this._cache.a00 + this._cache.a02 * this._cache.a10) * this._cache.id) * this.scale.y) + this._cache.a12;
-
- return p;
-
-};
-
-/**
-* Gets the local unmodified position of a coordinate relative to the Sprite, factoring in rotation and scale.
-* Mostly only used internally by the Input Manager, but also useful for custom hit detection.
-*
-* @method Phaser.Sprite#getLocalUnmodifiedPosition
-* @memberof Phaser.Sprite
-* @param {Phaser.Point} p - The Point object to store the results in.
-* @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) {
-
- p.x = (this._cache.a11 * this._cache.idi * gx + -this._cache.i01 * this._cache.idi * gy + (this._cache.a12 * this._cache.i01 - this._cache.a02 * this._cache.a11) * this._cache.idi) + (this.anchor.x * this._cache.width);
- p.y = (this._cache.a00 * this._cache.idi * gy + -this._cache.i10 * this._cache.idi * gx + (-this._cache.a12 * this._cache.a00 + this._cache.a02 * this._cache.i10) * this._cache.idi) + (this.anchor.y * this._cache.height);
-
- return p;
-
-};
-
-/**
-* Resets the Sprite.crop value back to the frame dimensions.
-*
-* @method Phaser.Sprite#resetCrop
-* @memberof Phaser.Sprite
-*/
-Phaser.Sprite.prototype.resetCrop = function() {
-
- this.crop = new Phaser.Rectangle(0, 0, this._cache.width, this._cache.height);
- this.texture.setFrame(this.crop);
- this.cropEnabled = false;
+ return true;
};
@@ -1120,17 +736,9 @@ Phaser.Sprite.prototype.postUpdate = function() {
if (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.position.x = this.game.camera.view.x + this.x;
+ // this.position.y = this.game.camera.view.y + this.y;
}
- else
- {
- this._cache.x = this.x;
- this._cache.y = this.y;
- }
-
- this.position.x = this._cache.x;
- this.position.y = this._cache.y;
}
};
@@ -1146,48 +754,55 @@ Phaser.Sprite.prototype.postUpdate = function() {
*/
Phaser.Sprite.prototype.loadTexture = function (key, frame) {
- this.key = key;
+ frame = frame || 0;
if (key instanceof Phaser.RenderTexture)
{
- this.currentFrame = this.game.cache.getTextureFrame(key.name);
+ this.key = key.key;
+ this.setTexture(key);
}
else if (key instanceof Phaser.BitmapData)
{
+ this.key = key.key;
this.setTexture(key.texture);
- this.currentFrame = key.textureFrame;
}
else if (key instanceof PIXI.Texture)
{
- this.currentFrame = frame;
+ this.key = key;
+ this.setTexture(key);
}
else
{
- if (typeof key === 'undefined' || this.game.cache.checkImageKey(key) === false)
+ if (key === null || typeof key === 'undefined')
{
- key = '__default';
- this.key = key;
+ this.key = '__default';
+ this.setTexture(PIXI.TextureCache[this.key]);
+ }
+ else if (typeof key === 'string' && !this.game.cache.checkImageKey(key))
+ {
+ this.key = '__missing';
+ this.setTexture(PIXI.TextureCache[this.key]);
}
if (this.game.cache.isSpriteSheet(key))
{
+ this.key = key;
+
+ // var frameData = this.game.cache.getFrameData(key);
this.animations.loadFrameData(this.game.cache.getFrameData(key));
- if (typeof frame !== 'undefined')
+ if (typeof frame === 'string')
{
- if (typeof frame === 'string')
- {
- this.frameName = frame;
- }
- else
- {
- this.frame = frame;
- }
+ this.frameName = frame;
+ }
+ else
+ {
+ this.frame = frame;
}
}
else
{
- this.currentFrame = this.game.cache.getFrame(key);
+ this.key = key;
this.setTexture(PIXI.TextureCache[key]);
}
}
@@ -1195,29 +810,49 @@ Phaser.Sprite.prototype.loadTexture = function (key, frame) {
};
/**
-* Moves the sprite so its center is located on the given x and y coordinates.
-* Doesn't change the anchor point of the sprite.
-*
-* @method Phaser.Sprite#centerOn
+* Crop allows you to crop the texture used to display this Image.
+* Cropping takes place from the top-left of the Image and can be modified in real-time by providing an updated rectangle object.
+*
+* @method Phaser.Sprite#crop
* @memberof Phaser.Sprite
-* @param {number} x - The x coordinate (in world space) to position the Sprite at.
-* @param {number} y - The y coordinate (in world space) to position the Sprite at.
-* @return (Phaser.Sprite) This instance.
+* @param {Phaser.Rectangle} rect - The Rectangle to crop the Image to. Pass null or no parameters to clear a previously set crop rectangle.
*/
-Phaser.Sprite.prototype.centerOn = function(x, y) {
+Phaser.Sprite.prototype.crop = function(rect) {
- if (this.fixedToCamera)
+ if (typeof rect === 'undefined' || rect === null)
{
- this.cameraOffset.x = x + (this.cameraOffset.x - this.center.x);
- this.cameraOffset.y = y + (this.cameraOffset.y - this.center.y);
+ // Clear any crop that may be set
+ if (this.texture.hasOwnProperty('sourceWidth'))
+ {
+ this.texture.setFrame(new Phaser.Rectangle(0, 0, this.texture.sourceWidth, this.texture.sourceHeight));
+ }
}
else
{
- this.x = x + (this.x - this.center.x);
- this.y = y + (this.y - this.center.y);
- }
+ // Do we need to clone the PIXI.Texture object?
+ if (this.texture instanceof PIXI.Texture)
+ {
+ // Yup, let's rock it ...
+ var local = {};
- return this;
+ Phaser.Utils.extend(true, local, this.texture);
+
+ local.sourceWidth = local.width;
+ local.sourceHeight = local.height;
+ local.frame = rect;
+ local.width = rect.width;
+ local.height = rect.height;
+
+ this.texture = local;
+
+ this.texture.updateFrame = true;
+ PIXI.Texture.frameUpdates.push(this.texture);
+ }
+ else
+ {
+ this.texture.setFrame(rect);
+ }
+ }
};
@@ -1288,14 +923,9 @@ Phaser.Sprite.prototype.destroy = function() {
this.filters = null;
}
- if (this.group)
+ if (this.parent)
{
- this.group.remove(this);
- }
-
- if (this.input)
- {
- this.input.destroy();
+ this.parent.remove(this);
}
if (this.events)
@@ -1303,6 +933,11 @@ Phaser.Sprite.prototype.destroy = function() {
this.events.destroy();
}
+ if (this.input)
+ {
+ this.input.destroy();
+ }
+
if (this.animations)
{
this.animations.destroy();
@@ -1362,11 +997,9 @@ Phaser.Sprite.prototype.reset = function(x, y, health) {
if (typeof health === 'undefined') { health = 1; }
- this.x = x;
- this.y = y;
this.world.setTo(x, y);
- this.position.x = this.x;
- this.position.y = this.y;
+ this.position.x = x;
+ this.position.y = y;
this.alive = true;
this.exists = true;
this.visible = true;
@@ -1392,15 +1025,18 @@ Phaser.Sprite.prototype.reset = function(x, y, health) {
* @memberof Phaser.Sprite
* @return (Phaser.Sprite) This instance.
*/
-Phaser.Sprite.prototype.bringToTop = function() {
+Phaser.Sprite.prototype.bringToTop = function(child) {
- if (this.group)
+ if (typeof child === 'undefined')
{
- this.group.bringToTop(this);
+ if (this.parent)
+ {
+ this.parent.bringToTop(this);
+ }
}
else
{
- this.game.world.bringToTop(this);
+
}
return this;
@@ -1429,48 +1065,110 @@ 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.
+* 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. Working in radians is also a little faster as it doesn't have to convert the angle.
+*
+* @name Phaser.Sprite#angle
+* @property {number} angle - The angle of this Image in degrees.
+*/
+Object.defineProperty(Phaser.Sprite.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));
+
+ }
+
+});
+
+/**
+* Returns the delta x value. The difference between world.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', {
+Object.defineProperty(Phaser.Sprite.prototype, "deltaX", {
get: function() {
- return this.world.x - this._cache.prevX;
+
+ return this.world.x - this._cache[0];
+
}
});
/**
-* Returns the delta x value. The difference between Sprite.y now and in the previous step.
+* Returns the delta y value. The difference between world.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', {
+Object.defineProperty(Phaser.Sprite.prototype, "deltaY", {
get: function() {
- return this.world.y - this._cache.prevY;
+
+ return this.world.y - this._cache[1];
+
}
});
/**
-* 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.Sprite#angle
-* @property {number} angle - Gets or sets the Sprites angle of rotation in degrees.
+* Returns the delta z value. The difference between rotation now and in the previous step.
+*
+* @name Phaser.Sprite#deltaZ
+* @property {number} deltaZ - The delta value.
+* @readonly
*/
-Object.defineProperty(Phaser.Sprite.prototype, 'angle', {
+Object.defineProperty(Phaser.Sprite.prototype, "deltaZ", {
get: function() {
- return Phaser.Math.wrapAngle(Phaser.Math.radToDeg(this.rotation));
- },
+
+ return this.rotation - this._cache[2];
+
+ }
+
+});
+
+/**
+* Checks if the Image bounds are within the game world, otherwise false if fully outside of it.
+*
+* @name Phaser.Sprite#inWorld
+* @property {boolean} inWorld - True if the Image bounds is within the game world, even if only partially. Otherwise false if fully outside of it.
+* @readonly
+*/
+Object.defineProperty(Phaser.Sprite.prototype, "inWorld", {
+
+ get: function() {
+
+ return this.game.world.bounds.intersects(this.getBounds());
+
+ }
+
+});
+
+/**
+* Checks if the Image bounds are within the game camera, otherwise false if fully outside of it.
+*
+* @name Phaser.Sprite#inCamera
+* @property {boolean} inCamera - True if the Image bounds is within the game camera, even if only partially. Otherwise false if fully outside of it.
+* @readonly
+*/
+Object.defineProperty(Phaser.Sprite.prototype, "inCamera", {
+
+ get: function() {
+
+ return this.game.world.camera.screenView.intersects(this.getBounds());
- set: function(value) {
- this.rotation = Phaser.Math.degToRad(Phaser.Math.wrapAngle(value));
}
});
@@ -1480,7 +1178,7 @@ Object.defineProperty(Phaser.Sprite.prototype, 'angle', {
* @property {number} frame - Gets or sets the current frame index and updates the Texture Cache for display.
*/
Object.defineProperty(Phaser.Sprite.prototype, "frame", {
-
+
get: function () {
return this.animations.frame;
},
@@ -1496,7 +1194,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "frame", {
* @property {string} frameName - Gets or sets the current frame name and updates the Texture Cache for display.
*/
Object.defineProperty(Phaser.Sprite.prototype, "frameName", {
-
+
get: function () {
return this.animations.frameName;
},
@@ -1508,102 +1206,32 @@ Object.defineProperty(Phaser.Sprite.prototype, "frameName", {
});
/**
-* @name Phaser.Sprite#inCamera
-* @property {boolean} inCamera - Is this sprite visible to the camera or not?
+* @name Phaser.Sprite#renderOrderID
+* @property {number} renderOrderID - The render order ID, reset every frame.
* @readonly
*/
-Object.defineProperty(Phaser.Sprite.prototype, "inCamera", {
-
- get: function () {
- return this._cache.cameraVisible;
- }
-
-});
-
-/**
-* @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.
-*
-* @name Phaser.Sprite#width
-* @property {number} width - The width of the Sprite in pixels.
-*/
-Object.defineProperty(Phaser.Sprite.prototype, 'width', {
+Object.defineProperty(Phaser.Sprite.prototype, "renderOrderID", {
get: function() {
- return this.scale.x * this.currentFrame.width;
- },
- set: function(value) {
-
- this.scale.x = value / this.currentFrame.width;
- this._cache.scaleX = value / this.currentFrame.width;
- this._width = value;
+ return this._cache[3];
}
});
/**
-* The height 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.
-*
-* @name Phaser.Sprite#height
-* @property {number} height - The height of the Sprite in pixels.
-*/
-Object.defineProperty(Phaser.Sprite.prototype, 'height', {
-
- get: function() {
- return this.scale.y * this.currentFrame.height;
- },
-
- set: function(value) {
-
- this.scale.y = value / this.currentFrame.height;
- this._cache.scaleY = value / this.currentFrame.height;
- this._height = value;
-
- }
-
-});
-
-/**
-* 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.
+* By default an Image won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is
+* activated for this object and it will then start to process click/touch events and more.
*
* @name Phaser.Sprite#inputEnabled
-* @property {boolean} inputEnabled - Set to true to allow this Sprite to receive input events, otherwise false.
+* @property {boolean} inputEnabled - Set to true to allow this object to receive input events.
*/
Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", {
get: function () {
- return (this.input.enabled);
+ return (this.input && this.input.enabled);
},
@@ -1611,19 +1239,19 @@ Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", {
if (value)
{
- if (this.input.enabled === false)
+ if (this.input === null)
{
+ this.input = new Phaser.InputHandler(this);
this.input.start();
}
}
else
{
- if (this.input.enabled)
+ if (this.input && this.input.enabled)
{
this.input.stop();
}
}
-
}
});
@@ -1648,7 +1276,7 @@ Object.defineProperty(Phaser.Sprite.prototype, "inputEnabled", {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Stage.js.html b/docs/Stage.js.html
index 61e45c67..9a68cd74 100644
--- a/docs/Stage.js.html
+++ b/docs/Stage.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -665,21 +699,12 @@ Object.defineProperty(Phaser.Stage.prototype, "backgroundColor", {
if (this.game.transparent === false)
{
- if (this.game.renderType == Phaser.CANVAS)
+ if (typeof color === 'string')
{
- // Set it directly, this allows us to use rgb alpha values in Canvas mode.
- this.game.canvas.style.backgroundColor = color;
- }
- else
- {
- if (typeof color === 'string')
- {
- color = Phaser.Color.hexToRGB(color);
- }
-
- this._stage.setBackgroundColor(color);
+ color = Phaser.Color.hexToRGB(color);
}
+ this._stage.setBackgroundColor(color);
}
}
@@ -706,7 +731,7 @@ Object.defineProperty(Phaser.Stage.prototype, "backgroundColor", {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/StageScaleMode.js.html b/docs/StageScaleMode.js.html
index 156a13d6..dcb6582c 100644
--- a/docs/StageScaleMode.js.html
+++ b/docs/StageScaleMode.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1212,7 +1246,7 @@ Object.defineProperty(Phaser.StageScaleMode.prototype, "isLandscape", {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/State.js.html b/docs/State.js.html
index b20515cf..de4968e5 100644
--- a/docs/State.js.html
+++ b/docs/State.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -607,7 +641,7 @@ Phaser.State.prototype.constructor = Phaser.State;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/StateManager.js.html b/docs/StateManager.js.html
index e3b8a73f..9cba01a8 100644
--- a/docs/StateManager.js.html
+++ b/docs/StateManager.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -964,7 +998,7 @@ Phaser.StateManager.prototype.constructor = Phaser.StateManager;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Text.js.html b/docs/Text.js.html
index 9376f7f1..589d77e6 100644
--- a/docs/Text.js.html
+++ b/docs/Text.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -737,7 +771,7 @@ Object.defineProperty(Phaser.Text.prototype, 'font', {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Tile.js.html b/docs/Tile.js.html
index 0dc8af7a..57038134 100644
--- a/docs/Tile.js.html
+++ b/docs/Tile.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -729,7 +763,7 @@ Object.defineProperty(Phaser.Tile.prototype, "bottom", {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/TileSprite.js.html b/docs/TileSprite.js.html
index a9fdfd0d..ea50c502 100644
--- a/docs/TileSprite.js.html
+++ b/docs/TileSprite.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -594,7 +628,7 @@ Object.defineProperty(Phaser.TileSprite.prototype, "inputEnabled", {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Tilemap.js.html b/docs/Tilemap.js.html
index ed75f137..d86b6e9c 100644
--- a/docs/Tilemap.js.html
+++ b/docs/Tilemap.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -449,14 +483,49 @@ Phaser.Tilemap = function (game, key) {
return;
}
+ /**
+ * @property {number} width - The width of the map (in tiles).
+ */
this.width = data.width;
+
+ /**
+ * @property {number} height - The height of the map (in tiles).
+ */
this.height = data.height;
+
+ /**
+ * @property {number} tileWidth - The base width of the tiles in the map (in pixels).
+ */
this.tileWidth = data.tileWidth;
+
+ /**
+ * @property {number} tileHeight - The base height of the tiles in the map (in pixels).
+ */
this.tileHeight = data.tileHeight;
+
+ /**
+ * @property {string} orientation - The orientation of the map data (as specified in Tiled), usually 'orthogonal'.
+ */
this.orientation = data.orientation;
+
+ /**
+ * @property {number} version - The version of the map data (as specified in Tiled, usually 1).
+ */
this.version = data.version;
+
+ /**
+ * @property {object} properties - Map specific properties as specified in Tiled.
+ */
this.properties = data.properties;
+
+ /**
+ * @property {number} widthInPixels - The width of the map in pixels based on width * tileWidth.
+ */
this.widthInPixels = data.widthInPixels;
+
+ /**
+ * @property {number} heightInPixels - The height of the map in pixels based on height * tileHeight.
+ */
this.heightInPixels = data.heightInPixels;
/**
@@ -608,12 +677,13 @@ Phaser.Tilemap.prototype = {
},
- // Region? Remove tile from map data?
+ /*
createFromTiles: function (layer, tileIndex, key, frame, group) {
if (typeof group === 'undefined') { group = this.game.world; }
},
+ */
/**
* 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
@@ -621,7 +691,7 @@ Phaser.Tilemap.prototype = {
* 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.Tileset#createFromObjects
+ * @method Phaser.Tilemap#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.
@@ -666,8 +736,10 @@ Phaser.Tilemap.prototype = {
/**
* Creates a new TilemapLayer object. By default TilemapLayers are fixed to the camera.
+ * The `layer` parameter is important. If you've created your map in Tiled then you can get this by looking in Tiled and looking at the Layer name.
+ * Or you can open the JSON file it exports and look at the layers[].name value. Either way it must match.
*
- * @method Phaser.Tileset#createLayer
+ * @method Phaser.Tilemap#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.
@@ -702,7 +774,7 @@ Phaser.Tilemap.prototype = {
/**
* Gets the layer index based on the layers name.
*
- * @method Phaser.Tileset#getIndex
+ * @method Phaser.Tilemap#getIndex
* @protected
* @param {array} location - The local array to search.
* @param {string} name - The name of the array element to get.
@@ -725,7 +797,7 @@ Phaser.Tilemap.prototype = {
/**
* Gets the layer index based on its name.
*
- * @method Phaser.Tileset#getLayerIndex
+ * @method Phaser.Tilemap#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.
*/
@@ -738,7 +810,7 @@ Phaser.Tilemap.prototype = {
/**
* Gets the tileset index based on its name.
*
- * @method Phaser.Tileset#getTilesetIndex
+ * @method Phaser.Tilemap#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.
*/
@@ -751,7 +823,7 @@ Phaser.Tilemap.prototype = {
/**
* Gets the image index based on its name.
*
- * @method Phaser.Tileset#getImageIndex
+ * @method Phaser.Tilemap#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.
*/
@@ -764,7 +836,7 @@ Phaser.Tilemap.prototype = {
/**
* Gets the object index based on its name.
*
- * @method Phaser.Tileset#getObjectIndex
+ * @method Phaser.Tilemap#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.
*/
@@ -779,7 +851,7 @@ Phaser.Tilemap.prototype = {
* 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
+ * @method Phaser.Tilemap#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.
@@ -810,7 +882,7 @@ Phaser.Tilemap.prototype = {
* 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
+ * @method Phaser.Tilemap#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)
@@ -841,7 +913,7 @@ Phaser.Tilemap.prototype = {
* 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
+ * @method Phaser.Tilemap#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.
@@ -875,7 +947,7 @@ Phaser.Tilemap.prototype = {
* 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
+ * @method Phaser.Tilemap#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.
@@ -906,7 +978,7 @@ Phaser.Tilemap.prototype = {
* 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
+ * @method Phaser.Tilemap#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.
@@ -935,7 +1007,7 @@ Phaser.Tilemap.prototype = {
* 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
+ * @method Phaser.Tilemap#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.
@@ -978,7 +1050,7 @@ Phaser.Tilemap.prototype = {
/**
* Gets the TilemapLayer index as used in the setCollision calls.
*
- * @method Phaser.Tileset#getLayer
+ * @method Phaser.Tilemap#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.
@@ -1009,7 +1081,7 @@ Phaser.Tilemap.prototype = {
/**
* Internal function.
*
- * @method Phaser.Tileset#calculateFaces
+ * @method Phaser.Tilemap#calculateFaces
* @protected
* @param {number} layer - The index of the TilemapLayer to operate on.
*/
@@ -1066,7 +1138,7 @@ Phaser.Tilemap.prototype = {
* Gets the tile above the tile coordinates given.
* Mostly used as an internal function by calculateFaces.
*
- * @method Phaser.Tileset#getTileAbove
+ * @method Phaser.Tilemap#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.
@@ -1086,7 +1158,7 @@ Phaser.Tilemap.prototype = {
* Gets the tile below the tile coordinates given.
* Mostly used as an internal function by calculateFaces.
*
- * @method Phaser.Tileset#getTileBelow
+ * @method Phaser.Tilemap#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.
@@ -1106,7 +1178,7 @@ Phaser.Tilemap.prototype = {
* Gets the tile to the left of the tile coordinates given.
* Mostly used as an internal function by calculateFaces.
*
- * @method Phaser.Tileset#getTileLeft
+ * @method Phaser.Tilemap#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.
@@ -1126,7 +1198,7 @@ Phaser.Tilemap.prototype = {
* Gets the tile to the right of the tile coordinates given.
* Mostly used as an internal function by calculateFaces.
*
- * @method Phaser.Tileset#getTileRight
+ * @method Phaser.Tilemap#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.
@@ -1673,7 +1745,7 @@ Phaser.Tilemap.prototype.constructor = Phaser.Tilemap;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/TilemapLayer.js.html b/docs/TilemapLayer.js.html
index e92aa009..c16427e1 100644
--- a/docs/TilemapLayer.js.html
+++ b/docs/TilemapLayer.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1316,7 +1350,7 @@ Object.defineProperty(Phaser.TilemapLayer.prototype, "collisionHeight", {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/TilemapParser.js.html b/docs/TilemapParser.js.html
index 8bd6058b..feee6acd 100644
--- a/docs/TilemapParser.js.html
+++ b/docs/TilemapParser.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -814,7 +848,7 @@ Phaser.TilemapParser = {
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Tileset.js.html b/docs/Tileset.js.html
index 56d573a1..1fd15ec2 100644
--- a/docs/Tileset.js.html
+++ b/docs/Tileset.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -592,7 +626,7 @@ Phaser.Tileset.prototype.constructor = Phaser.Tileset;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Time.js.html b/docs/Time.js.html
index 91ac8c29..9b78ae92 100644
--- a/docs/Time.js.html
+++ b/docs/Time.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -783,7 +817,7 @@ Phaser.Time.prototype.constructor = Phaser.Time;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Timer.js.html b/docs/Timer.js.html
index fd8151d7..4f29b7fd 100644
--- a/docs/Timer.js.html
+++ b/docs/Timer.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -807,7 +841,7 @@ Phaser.Touch.prototype.constructor = Phaser.Touch;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Tween.js.html b/docs/Tween.js.html
index 9b4e0de5..83f6136a 100644
--- a/docs/Tween.js.html
+++ b/docs/Tween.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -1015,7 +1049,7 @@ Phaser.Tween.prototype.constructor = Phaser.Tween;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/TweenManager.js.html b/docs/TweenManager.js.html
index 07e47e17..a673e730 100644
--- a/docs/TweenManager.js.html
+++ b/docs/TweenManager.js.html
@@ -182,6 +182,10 @@
Group
+
+
@@ -640,7 +674,7 @@ Phaser.TweenManager.prototype.constructor = Phaser.TweenManager;
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Utils.js.html b/docs/Utils.js.html
index abbfff1f..e0c1a76e 100644
--- a/docs/Utils.js.html
+++ b/docs/Utils.js.html
@@ -182,6 +182,10 @@
Group
+
@@ -774,7 +817,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/global.html b/docs/global.html
index 36df3ad4..307c8d56 100644
--- a/docs/global.html
+++ b/docs/global.html
@@ -182,6 +182,10 @@
Group
+
@@ -1180,7 +1125,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:20:17 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/index.html b/docs/index.html
index 0af4ffc2..b2fb68f7 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -182,6 +182,10 @@
Group
+
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
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.
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.
+
Upgraded to Pixi.js 1.4.4
+
Group now extends PIXI.DisplayObjectContainer, rather than owning a _container property, which makes life a whole lot easier re: nesting.
+
Removed Sprite.group property. You can use Sprite.parent for all similar needs now.
+
PIXI.Point is now aliased to Phaser.Point - saves on code duplication and works exactly the same.
+
PIXI.Rectangle is now aliased to Phaser.Rectangle - saves on code duplication and works exactly the same.
+
PIXI.Circle is now aliased to Phaser.Circle - saves on code duplication and works exactly the same.
+
Sprite.deltaX and deltaY swapped to functions: Sprite.deltaX() and Sprite.deltaY()
+
Sprite.crop() now takes a Phaser.Rectangle instead of explicit parameters.
+
PixiPatch no longer needed, all features that it patched are now native in Pixi :)
+
Removed: Sprite.offset, center, topLeft, topRight, bottomRight, bottomLeft and bounds as no longer needed internally. Use Sprite.getBounds() to derive them.
+
Button now extends Phaser.Image not Phaser.Sprite, all the same functionality as before remains, just no animations or physics body.
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!
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.
+
Phaser.Image is a brand new display object perfect for logos, backgrounds, etc. You can scale, rotate, tint and blend and Image, but it has no animation, physics body or input events.
+
You can now use the hitArea property on Sprites and Image objects. hitArea can be a geometry object (Rectangle, Circle, Polygon, Ellipse) and is used in pointerOver checks.
+
InputManager.getLocalPosition(displayObject, pointer, output) will return the local coordinates of the specified displayObject and pointer.
+
InputManager.hitTest will test for pointer hits against a Sprite/Image, its hitArea (if set) or any of its children.
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)
+
Debug.renderRectangle has a new parameter: filled. If true it renders as with fillRect, if false strokeRect.
+
Phaser.AnimationParser now sets the trimmed data directly for Pixi Texture frames. Tested across JSON Hash, JSON Data, Sprite Sheet and XML.
+
Game.add.renderTexture now has the addToCache parameter. If set the texture will be stored in Game.Cache and can be retrieved with Cache.getTexture(key).
+
Game.add.bitmapData now has the addToCache parameter. If set the texture will be stored in Game.Cache and can be retrieved with Cache.getBitmapData(key).
+
The InputManager now sets the canvas style cursor to 'inherit' instead of 'default'.
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)
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.
+
Explicitly paused Timer continues if you un-focus and focus the browser window (thanks georgiee)
+
Added TimerEvent.pendingDelete and checks in Timer.update, so that removing an event in a callback no longer throws an exception (thanks georgiee)
+
Fixed TypeScript defs on lines 1741-1748 (thanks wombatbuddy)
+
Previously if you used Sprite.crop() it would crop all Sprites using the same base image. It now takes a local copy of the texture data and crops just that.
+
Tilemap had the wrong @method signatures so most were missing from the docs.
@@ -705,14 +608,6 @@ Sprites also have full Input support: click them, touch them, drag them around,
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.
@@ -738,6 +633,8 @@ Sprites also have full Input support: click them, touch them, drag them around,
Look at HiDPI Canvas settings.
Multiple Camera support.
+
Nadion
+
Nadion is a set of powerful enhancements for Phaser that makes level building even easier. It includes features such as Trigger, Area, Alarms and Emitters, debug panels, state machines, parallax layer scrolling, 'developer mode' short-cuts and more.
Contributing
We now have a full Contributors Guide which goes into the process in more detail, but here are the headlines:
@@ -778,7 +675,7 @@ Sprites also have full Input support: click them, touch them, drag them around,
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/namespaces.list.html b/docs/namespaces.list.html
index f5a3ebbe..d4f4332b 100644
--- a/docs/namespaces.list.html
+++ b/docs/namespaces.list.html
@@ -182,6 +182,10 @@
Group
+
@@ -774,7 +817,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Wed Feb 05 2014 06:28:24 GMT-0000 (GMT) using the DocStrap template.
+ on Sat Feb 08 2014 07:19:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/src/tilemap/Tilemap.js b/src/tilemap/Tilemap.js
index e9530a30..284845be 100644
--- a/src/tilemap/Tilemap.js
+++ b/src/tilemap/Tilemap.js
@@ -32,14 +32,49 @@ Phaser.Tilemap = function (game, key) {
return;
}
+ /**
+ * @property {number} width - The width of the map (in tiles).
+ */
this.width = data.width;
+
+ /**
+ * @property {number} height - The height of the map (in tiles).
+ */
this.height = data.height;
+
+ /**
+ * @property {number} tileWidth - The base width of the tiles in the map (in pixels).
+ */
this.tileWidth = data.tileWidth;
+
+ /**
+ * @property {number} tileHeight - The base height of the tiles in the map (in pixels).
+ */
this.tileHeight = data.tileHeight;
+
+ /**
+ * @property {string} orientation - The orientation of the map data (as specified in Tiled), usually 'orthogonal'.
+ */
this.orientation = data.orientation;
+
+ /**
+ * @property {number} version - The version of the map data (as specified in Tiled, usually 1).
+ */
this.version = data.version;
+
+ /**
+ * @property {object} properties - Map specific properties as specified in Tiled.
+ */
this.properties = data.properties;
+
+ /**
+ * @property {number} widthInPixels - The width of the map in pixels based on width * tileWidth.
+ */
this.widthInPixels = data.widthInPixels;
+
+ /**
+ * @property {number} heightInPixels - The height of the map in pixels based on height * tileHeight.
+ */
this.heightInPixels = data.heightInPixels;
/**
@@ -191,12 +226,13 @@ Phaser.Tilemap.prototype = {
},
- // Region? Remove tile from map data?
+ /*
createFromTiles: function (layer, tileIndex, key, frame, group) {
if (typeof group === 'undefined') { group = this.game.world; }
},
+ */
/**
* 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
@@ -204,7 +240,7 @@ Phaser.Tilemap.prototype = {
* 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.Tileset#createFromObjects
+ * @method Phaser.Tilemap#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.
@@ -249,8 +285,10 @@ Phaser.Tilemap.prototype = {
/**
* Creates a new TilemapLayer object. By default TilemapLayers are fixed to the camera.
+ * The `layer` parameter is important. If you've created your map in Tiled then you can get this by looking in Tiled and looking at the Layer name.
+ * Or you can open the JSON file it exports and look at the layers[].name value. Either way it must match.
*
- * @method Phaser.Tileset#createLayer
+ * @method Phaser.Tilemap#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.
@@ -285,7 +323,7 @@ Phaser.Tilemap.prototype = {
/**
* Gets the layer index based on the layers name.
*
- * @method Phaser.Tileset#getIndex
+ * @method Phaser.Tilemap#getIndex
* @protected
* @param {array} location - The local array to search.
* @param {string} name - The name of the array element to get.
@@ -308,7 +346,7 @@ Phaser.Tilemap.prototype = {
/**
* Gets the layer index based on its name.
*
- * @method Phaser.Tileset#getLayerIndex
+ * @method Phaser.Tilemap#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.
*/
@@ -321,7 +359,7 @@ Phaser.Tilemap.prototype = {
/**
* Gets the tileset index based on its name.
*
- * @method Phaser.Tileset#getTilesetIndex
+ * @method Phaser.Tilemap#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.
*/
@@ -334,7 +372,7 @@ Phaser.Tilemap.prototype = {
/**
* Gets the image index based on its name.
*
- * @method Phaser.Tileset#getImageIndex
+ * @method Phaser.Tilemap#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.
*/
@@ -347,7 +385,7 @@ Phaser.Tilemap.prototype = {
/**
* Gets the object index based on its name.
*
- * @method Phaser.Tileset#getObjectIndex
+ * @method Phaser.Tilemap#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.
*/
@@ -362,7 +400,7 @@ Phaser.Tilemap.prototype = {
* 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
+ * @method Phaser.Tilemap#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.
@@ -393,7 +431,7 @@ Phaser.Tilemap.prototype = {
* 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
+ * @method Phaser.Tilemap#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)
@@ -424,7 +462,7 @@ Phaser.Tilemap.prototype = {
* 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
+ * @method Phaser.Tilemap#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.
@@ -458,7 +496,7 @@ Phaser.Tilemap.prototype = {
* 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
+ * @method Phaser.Tilemap#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.
@@ -489,7 +527,7 @@ Phaser.Tilemap.prototype = {
* 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
+ * @method Phaser.Tilemap#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.
@@ -518,7 +556,7 @@ Phaser.Tilemap.prototype = {
* 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
+ * @method Phaser.Tilemap#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.
@@ -561,7 +599,7 @@ Phaser.Tilemap.prototype = {
/**
* Gets the TilemapLayer index as used in the setCollision calls.
*
- * @method Phaser.Tileset#getLayer
+ * @method Phaser.Tilemap#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.
@@ -592,7 +630,7 @@ Phaser.Tilemap.prototype = {
/**
* Internal function.
*
- * @method Phaser.Tileset#calculateFaces
+ * @method Phaser.Tilemap#calculateFaces
* @protected
* @param {number} layer - The index of the TilemapLayer to operate on.
*/
@@ -649,7 +687,7 @@ Phaser.Tilemap.prototype = {
* Gets the tile above the tile coordinates given.
* Mostly used as an internal function by calculateFaces.
*
- * @method Phaser.Tileset#getTileAbove
+ * @method Phaser.Tilemap#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.
@@ -669,7 +707,7 @@ Phaser.Tilemap.prototype = {
* Gets the tile below the tile coordinates given.
* Mostly used as an internal function by calculateFaces.
*
- * @method Phaser.Tileset#getTileBelow
+ * @method Phaser.Tilemap#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.
@@ -689,7 +727,7 @@ Phaser.Tilemap.prototype = {
* Gets the tile to the left of the tile coordinates given.
* Mostly used as an internal function by calculateFaces.
*
- * @method Phaser.Tileset#getTileLeft
+ * @method Phaser.Tilemap#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.
@@ -709,7 +747,7 @@ Phaser.Tilemap.prototype = {
* Gets the tile to the right of the tile coordinates given.
* Mostly used as an internal function by calculateFaces.
*
- * @method Phaser.Tileset#getTileRight
+ * @method Phaser.Tilemap#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.
From 243820c9736066821d162fe739422f161a50fdf7 Mon Sep 17 00:00:00 2001
From: photonstorm
Date: Sat, 8 Feb 2014 09:14:44 +0000
Subject: [PATCH 26/26] Fixing up Pixis setBackgroundColor.
---
examples/wip/pixi1.js | 4 +
src/gameobjects/Sprite.js | 2 +
src/gameobjects/old_Sprite.js | 1211 +++++++++++++++++++
src/physics/arcade/Body.js | 56 +-
src/pixi/Pixi.js | 15 +
src/pixi/display/Stage.js | 3 +
src/pixi/renderers/canvas/CanvasRenderer.js | 27 +-
7 files changed, 1300 insertions(+), 18 deletions(-)
create mode 100644 src/gameobjects/old_Sprite.js
diff --git a/examples/wip/pixi1.js b/examples/wip/pixi1.js
index 210adfc1..cf625586 100644
--- a/examples/wip/pixi1.js
+++ b/examples/wip/pixi1.js
@@ -14,6 +14,10 @@ var p;
function create() {
+ // game.stage.backgroundColor = '#ff5500';
+
+ game.stage._stage.setBackgroundColor(0xff5500);
+
sprite = game.add.sprite(0, 0, 'pic');
g = game.add.group(null, 'billy');
diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js
index 988c07e7..83b22fb1 100644
--- a/src/gameobjects/Sprite.js
+++ b/src/gameobjects/Sprite.js
@@ -166,6 +166,7 @@ Phaser.Sprite.prototype.constructor = Phaser.Sprite;
*/
Phaser.Sprite.prototype.preUpdate = function() {
+ /*
if (this._cache[4] === 1)
{
console.log('sprite cache fresh');
@@ -187,6 +188,7 @@ Phaser.Sprite.prototype.preUpdate = function() {
return;
}
+ */
this._cache[0] = this.world.x;
this._cache[1] = this.world.y;
diff --git a/src/gameobjects/old_Sprite.js b/src/gameobjects/old_Sprite.js
new file mode 100644
index 00000000..0b98feb1
--- /dev/null
+++ b/src/gameobjects/old_Sprite.js
@@ -0,0 +1,1211 @@
+/**
+* @author Richard Davey
+* @copyright 2014 Photon Storm Ltd.
+* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
+*/
+
+/**
+* @class Phaser.Sprite
+*
+* @classdesc Create a new `Sprite` object. Sprites are the lifeblood of your game, used for nearly everything visual.
+*
+* At its most basic a Sprite consists of a set of coordinates and a texture that is rendered to the canvas.
+* They also contain additional properties allowing for physics motion (via Sprite.body), input handling (via Sprite.input),
+* events (via Sprite.events), animation (via Sprite.animations), camera culling and more. Please see the Examples for use cases.
+*
+* @constructor
+* @param {Phaser.Game} game - A reference to the currently running game.
+* @param {number} x - The x coordinate (in world space) to position the Sprite at.
+* @param {number} y - The y coordinate (in world space) to position the Sprite at.
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|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.Sprite = function (game, x, y, key, frame) {
+
+ x = x || 0;
+ y = y || 0;
+ key = key || null;
+ frame = frame || null;
+
+ /**
+ * @property {Phaser.Game} game - A reference to the currently running Game.
+ */
+ this.game = game;
+
+ /**
+ * @property {boolean} exists - If exists = false then the Sprite isn't updated by the core game loop or physics subsystem at all.
+ * @default
+ */
+ this.exists = true;
+
+ /**
+ * @property {boolean} alive - This is a handy little var your game can use to determine if a sprite is alive or not, it doesn't effect rendering.
+ * @default
+ */
+ this.alive = true;
+
+ /**
+ * @property {Phaser.Group|Phaser.Sprite} parent - The parent of this Sprite.
+ */
+ // this.group = null;
+
+ /**
+ * @property {string} name - The user defined name given to this Sprite.
+ * @default
+ */
+ this.name = '';
+
+ /**
+ * @property {number} type - The const type of this object.
+ * @readonly
+ */
+ this.type = Phaser.SPRITE;
+
+ /**
+ * @property {number} renderOrderID - Used by the Renderer and Input Manager to control picking order.
+ * @default
+ */
+ this.renderOrderID = -1;
+
+ /**
+ * If you would like the Sprite to have a lifespan once 'born' you can set this to a positive value. Handy for particles, bullets, etc.
+ * The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called.
+ * @property {number} lifespan - The lifespan of the Sprite (in ms) before it will be killed.
+ * @default
+ */
+ this.lifespan = 0;
+
+ /**
+ * @property {Phaser.Events} events - The Events you can subscribe to that are dispatched when certain things happen on this Sprite or its components.
+ */
+ this.events = new Phaser.Events(this);
+
+ /**
+ * @property {Phaser.AnimationManager} animations - This manages animations of the sprite. You can modify animations through it (see Phaser.AnimationManager)
+ */
+ this.animations = new Phaser.AnimationManager(this);
+
+ /**
+ * @property {Phaser.InputHandler} input - The Input Handler Component.
+ */
+ this.input = new Phaser.InputHandler(this);
+
+ /**
+ * @property {string|Phaser.RenderTexture|Phaser.BitmapData|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, BitmapData or PIXI.Texture.
+ */
+ this.key = key;
+
+ /**
+ * @property {Phaser.Frame} currentFrame - A reference to the currently displayed frame.
+ */
+ this.currentFrame = null;
+
+ if (key instanceof Phaser.RenderTexture)
+ {
+ PIXI.Sprite.call(this, key);
+
+ this.currentFrame = this.game.cache.getTextureFrame(key.name);
+ }
+ else if (key instanceof Phaser.BitmapData)
+ {
+ PIXI.Sprite.call(this, key.texture, key.textureFrame);
+
+ this.currentFrame = key.textureFrame;
+ }
+ else if (key instanceof PIXI.Texture)
+ {
+ PIXI.Sprite.call(this, key);
+
+ this.currentFrame = frame;
+ }
+ else
+ {
+ if (key === null || typeof key === 'undefined')
+ {
+ key = '__default';
+ this.key = key;
+ }
+ else if (typeof key === 'string' && this.game.cache.checkImageKey(key) === false)
+ {
+ key = '__missing';
+ this.key = key;
+ }
+
+ PIXI.Sprite.call(this, PIXI.TextureCache[key]);
+
+ if (this.game.cache.isSpriteSheet(key))
+ {
+ this.animations.loadFrameData(this.game.cache.getFrameData(key));
+
+ if (frame !== null)
+ {
+ if (typeof frame === 'string')
+ {
+ this.frameName = frame;
+ }
+ else
+ {
+ this.frame = frame;
+ }
+ }
+ }
+ else
+ {
+ this.currentFrame = this.game.cache.getFrame(key);
+ }
+ }
+
+ /**
+ * The rectangular area from the texture that will be rendered.
+ * @property {Phaser.Rectangle} textureRegion
+ */
+ this.textureRegion = new Phaser.Rectangle(this.texture.frame.x, this.texture.frame.y, this.texture.frame.width, this.texture.frame.height);
+
+ /**
+ * The anchor sets the origin point of the texture.
+ * The default is 0,0 this means the textures origin is the top left
+ * Setting than anchor to 0.5,0.5 means the textures origin is centered
+ * Setting the anchor to 1,1 would mean the textures origin points will be the bottom right
+ *
+ * @property {Phaser.Point} anchor - The anchor around which rotation and scaling takes place.
+ */
+ // this.anchor = new Phaser.Point();
+
+ // this.position.x = x;
+ // this.position.y = y;
+
+ /**
+ * @property {number} x - The x coordinate in world space of this Sprite.
+ */
+ this.x = x;
+
+ /**
+ * @property {number} y - The y coordinate in world space of this Sprite.
+ */
+ this.y = y;
+
+
+ /**
+ * @property {Phaser.Point} world - The world coordinates of this Sprite. This differs from the x/y coordinates which are relative to the Sprites container.
+ */
+ this.world = new Phaser.Point(x, y);
+
+ /**
+ * Should this Sprite be automatically culled if out of range of the camera?
+ * A culled sprite has its renderable property set to 'false'.
+ *
+ * @property {boolean} autoCull - A flag indicating if the Sprite should be automatically camera culled or not.
+ * @default
+ */
+ this.autoCull = false;
+
+ /**
+ * @property {Phaser.Point} scale - The scale of the Sprite when rendered. By default it's set to 1 (no scale). You can modify it via scale.x or scale.y or scale.setTo(x, y). A value of 1 means no change to the scale, 0.5 means "half the size", 2 means "twice the size", etc.
+ */
+ // this.scale = new Phaser.Point(1, 1);
+
+ /**
+ * @property {object} _cache - A mini cache for storing all of the calculated values.
+ * @private
+ */
+ this._cache = {
+
+ fresh: true,
+ dirty: false,
+
+ // Transform cache
+ a00: -1,
+ a01: -1,
+ a02: -1,
+ a10: -1,
+ a11: -1,
+ a12: -1,
+ id: -1,
+
+ // Input specific transform cache
+ i01: -1,
+ i10: -1,
+ idi: -1,
+
+ // Bounds check
+ left: null,
+ right: null,
+ top: null,
+ bottom: null,
+
+ // delta cache
+ prevX: x,
+ prevY: y,
+
+ // The previous calculated position
+ x: -1,
+ y: -1,
+
+ // The actual scale values based on the worldTransform
+ scaleX: 1,
+ scaleY: 1,
+
+ // The width/height of the image, based on the un-modified frame size multiplied by the final calculated scale size
+ width: this.currentFrame.sourceSizeW,
+ height: this.currentFrame.sourceSizeH,
+
+ // The actual width/height of the image if from a trimmed atlas, multiplied by the final calculated scale size
+ halfWidth: Math.floor(this.currentFrame.sourceSizeW / 2),
+ halfHeight: Math.floor(this.currentFrame.sourceSizeH / 2),
+
+ // The width/height of the image, based on the un-modified frame size multiplied by the final calculated scale size
+ calcWidth: -1,
+ calcHeight: -1,
+
+ // The current frame details
+ // frameID: this.currentFrame.uuid, frameWidth: this.currentFrame.width, frameHeight: this.currentFrame.height,
+ frameID: -1,
+ frameWidth: this.currentFrame.width,
+ frameHeight: this.currentFrame.height,
+
+ // If this sprite visible to the camera (regardless of being set to visible or not)
+ cameraVisible: true,
+
+ // Crop cache
+ cropX: 0,
+ cropY: 0,
+ cropWidth: this.currentFrame.sourceSizeW,
+ cropHeight: this.currentFrame.sourceSizeH
+
+ };
+
+ /**
+ * @property {Phaser.Point} offset - Corner point defaults. Should not typically be modified.
+ */
+ this.offset = new Phaser.Point();
+
+ /**
+ * @property {Phaser.Point} center - A Point containing the center coordinate of the Sprite. Takes rotation and scale into account.
+ */
+ this.center = new Phaser.Point(x + Math.floor(this._cache.width / 2), y + Math.floor(this._cache.height / 2));
+
+ /**
+ * @property {Phaser.Point} topLeft - A Point containing the top left coordinate of the Sprite. Takes rotation and scale into account.
+ */
+ this.topLeft = new Phaser.Point(x, y);
+
+ /**
+ * @property {Phaser.Point} topRight - A Point containing the top right coordinate of the Sprite. Takes rotation and scale into account.
+ */
+ this.topRight = new Phaser.Point(x + this._cache.width, y);
+
+ /**
+ * @property {Phaser.Point} bottomRight - A Point containing the bottom right coordinate of the Sprite. Takes rotation and scale into account.
+ */
+ this.bottomRight = new Phaser.Point(x + this._cache.width, y + this._cache.height);
+
+ /**
+ * @property {Phaser.Point} bottomLeft - A Point containing the bottom left coordinate of the Sprite. Takes rotation and scale into account.
+ */
+ this.bottomLeft = new Phaser.Point(x, y + this._cache.height);
+
+ /**
+ * This Rectangle object fully encompasses the Sprite and is updated in real-time.
+ * The bounds is the full bounding area after rotation and scale have been taken into account. It should not be modified directly.
+ * It's used for Camera culling and physics body alignment.
+ * @property {Phaser.Rectangle} bounds
+ */
+ this.bounds = new Phaser.Rectangle(x, y, this._cache.width, this._cache.height);
+
+ /**
+ * @property {Phaser.Physics.Arcade.Body} body - By default Sprites have a Phaser.Physics Body attached to them. You can operate physics actions via this property, or null it to skip all physics updates.
+ */
+ this.body = new Phaser.Physics.Arcade.Body(this);
+
+ /**
+ * @property {number} health - Health value. Used in combination with damage() to allow for quick killing of Sprites.
+ */
+ this.health = 1;
+
+ /**
+ * @property {boolean} inWorld - This value is set to true if the Sprite is positioned within the World, otherwise false.
+ */
+ this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds);
+
+ /**
+ * @property {number} inWorldThreshold - A threshold value applied to the inWorld check. If you don't want a Sprite to be considered "out of the world" until at least 100px away for example then set it to 100.
+ * @default
+ */
+ this.inWorldThreshold = 0;
+
+ /**
+ * @property {boolean} outOfBoundsKill - If true the Sprite is killed as soon as Sprite.inWorld is false.
+ * @default
+ */
+ this.outOfBoundsKill = false;
+
+ /**
+ * @property {boolean} _outOfBoundsFired - Internal flag.
+ * @private
+ * @default
+ */
+ this._outOfBoundsFired = false;
+
+ /**
+ * A Sprite 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 Sprite to the Camera.
+ * @default
+ */
+ this.fixedToCamera = false;
+
+ /**
+ * @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(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.
+ * The crop is only applied if you have set Sprite.cropEnabled to true.
+ * @property {Phaser.Rectangle} crop - The crop Rectangle applied to the Sprite texture before rendering.
+ * @default
+ */
+ this.crop = new Phaser.Rectangle(0, 0, this._cache.width, this._cache.height);
+
+ /**
+ * @property {boolean} cropEnabled - If true the Sprite.crop property is used to crop the texture before render. Set to false to disable.
+ * @default
+ */
+ this.cropEnabled = false;
+
+ /**
+ * @property {boolean} debug - Handy flag to use with Game.enableStep
+ * @default
+ */
+ this.debug = false;
+
+ this.updateCache();
+ this.updateBounds();
+
+ /**
+ * @property {Phaser.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)
+Phaser.Sprite.prototype = Object.create(PIXI.Sprite.prototype);
+Phaser.Sprite.prototype.constructor = Phaser.Sprite;
+
+/**
+* Automatically called by World.preUpdate. Handles cache updates, lifespan checks, animation updates and physics updates.
+*
+* @method Phaser.Sprite#preUpdate
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.preUpdate = function() {
+
+ if (this._cache.fresh)
+ {
+ this.world.setTo(this.parent.position.x + this.position.x, this.parent.position.y + this.position.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;
+
+ // Skip children if not exists
+ return false;
+ }
+
+ if (this.lifespan > 0)
+ {
+ this.lifespan -= this.game.time.elapsed;
+
+ if (this.lifespan <= 0)
+ {
+ this.kill();
+ return false;
+ }
+ }
+
+ this._cache.dirty = false;
+
+ if (this.visible)
+ {
+ this.renderOrderID = this.game.world.currentRenderOrderID++;
+ }
+
+ this.updateCache();
+
+ this.updateAnimation();
+
+ this.updateCrop();
+
+ // Re-run the camera visibility check
+ if (this._cache.dirty || this.world.x !== this._cache.prevX || this.world.y !== this._cache.prevY)
+ {
+ this.updateBounds();
+ }
+
+ if (this.body)
+ {
+ this.body.preUpdate();
+ }
+
+ return true;
+
+};
+
+/**
+* Internal function called by preUpdate.
+*
+* @method Phaser.Sprite#updateCache
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.updateCache = function() {
+
+ this._cache.prevX = this.world.x;
+ this._cache.prevY = this.world.y;
+
+ if (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]);
+
+ if (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]; // scaleX a |a c tx|
+ this._cache.a01 = this.worldTransform[1]; // skewY c |b d ty|
+ this._cache.a10 = this.worldTransform[3]; // skewX b |0 0 1|
+ this._cache.a11 = this.worldTransform[4]; // scaleY d
+
+ this._cache.i01 = this.worldTransform[1]; // skewY c (remains non-modified for input checks)
+ this._cache.i10 = this.worldTransform[3]; // skewX b (remains non-modified for input checks)
+
+ this._cache.scaleX = Math.sqrt((this._cache.a00 * this._cache.a00) + (this._cache.a01 * this._cache.a01)); // round this off a bit?
+ this._cache.scaleY = Math.sqrt((this._cache.a10 * this._cache.a10) + (this._cache.a11 * this._cache.a11)); // round this off a bit?
+
+ 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 = true;
+ }
+
+ this._cache.a02 = this.worldTransform[2]; // translateX tx
+ this._cache.a12 = this.worldTransform[5]; // translateY ty
+
+};
+
+/**
+* Internal function called by preUpdate.
+*
+* @method Phaser.Sprite#updateAnimation
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.updateAnimation = function() {
+
+ if (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 = true;
+ }
+
+};
+
+/**
+* Internal function called by preUpdate.
+*
+* @method Phaser.Sprite#updateCrop
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.updateCrop = function() {
+
+ // This only runs if crop is enabled
+ if (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 = true;
+
+ PIXI.Texture.frameUpdates.push(this.texture);
+ }
+
+};
+
+/**
+* Internal function called by preUpdate.
+*
+* @method Phaser.Sprite#updateBounds
+* @memberof Phaser.Sprite
+*/
+Phaser.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 = Phaser.Math.min(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
+ this._cache.right = Phaser.Math.max(this.topLeft.x, this.topRight.x, this.bottomLeft.x, this.bottomRight.x);
+ this._cache.top = Phaser.Math.min(this.topLeft.y, this.topRight.y, this.bottomLeft.y, this.bottomRight.y);
+ this._cache.bottom = Phaser.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 = true;
+
+ if (this.inWorld === false)
+ {
+ // Sprite WAS out of the screen, is it still?
+ this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds, this.inWorldThreshold);
+
+ if (this.inWorld)
+ {
+ // It's back again, reset the OOB check
+ this._outOfBoundsFired = false;
+ }
+ }
+ else
+ {
+ // Sprite WAS in the screen, has it now left?
+ this.inWorld = Phaser.Rectangle.intersects(this.bounds, this.game.world.bounds, this.inWorldThreshold);
+
+ if (this.inWorld === false)
+ {
+ this.events.onOutOfBounds.dispatch(this);
+ this._outOfBoundsFired = true;
+
+ if (this.outOfBoundsKill)
+ {
+ this.kill();
+ }
+ }
+ }
+
+ this._cache.cameraVisible = Phaser.Rectangle.intersects(this.game.world.camera.screenView, this.bounds, 0);
+
+ if (this.autoCull)
+ {
+ // Won't get rendered but will still get its transform updated
+ this.renderable = this._cache.cameraVisible;
+ }
+
+};
+
+/**
+* Gets the local position of a coordinate relative to the Sprite, factoring in rotation and scale.
+* Mostly only used internally.
+*
+* @method Phaser.Sprite#getLocalPosition
+* @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 - y coordinate within the Sprite to translate.
+* @return {Phaser.Point} The translated point.
+*/
+Phaser.Sprite.prototype.getLocalPosition = function(p, x, y) {
+
+ p.x = ((this._cache.a11 * this._cache.id * x + -this._cache.a01 * this._cache.id * y + (this._cache.a12 * this._cache.a01 - this._cache.a02 * this._cache.a11) * this._cache.id) * this.scale.x) + this._cache.a02;
+ p.y = ((this._cache.a00 * this._cache.id * y + -this._cache.a10 * this._cache.id * x + (-this._cache.a12 * this._cache.a00 + this._cache.a02 * this._cache.a10) * this._cache.id) * this.scale.y) + this._cache.a12;
+
+ return p;
+
+};
+
+/**
+* Gets the local unmodified position of a coordinate relative to the Sprite, factoring in rotation and scale.
+* Mostly only used internally by the Input Manager, but also useful for custom hit detection.
+*
+* @method Phaser.Sprite#getLocalUnmodifiedPosition
+* @memberof Phaser.Sprite
+* @param {Phaser.Point} p - The Point object to store the results in.
+* @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) {
+
+ p.x = (this._cache.a11 * this._cache.idi * gx + -this._cache.i01 * this._cache.idi * gy + (this._cache.a12 * this._cache.i01 - this._cache.a02 * this._cache.a11) * this._cache.idi) + (this.anchor.x * this._cache.width);
+ p.y = (this._cache.a00 * this._cache.idi * gy + -this._cache.i10 * this._cache.idi * gx + (-this._cache.a12 * this._cache.a00 + this._cache.a02 * this._cache.i10) * this._cache.idi) + (this.anchor.y * this._cache.height);
+
+ return p;
+
+};
+
+/**
+* Resets the Sprite.crop value back to the frame dimensions.
+*
+* @method Phaser.Sprite#resetCrop
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.resetCrop = function() {
+
+ this.crop = new Phaser.Rectangle(0, 0, this._cache.width, this._cache.height);
+ this.texture.setFrame(this.crop);
+ this.cropEnabled = false;
+
+};
+
+/**
+* Internal function called by the World postUpdate cycle.
+*
+* @method Phaser.Sprite#postUpdate
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.postUpdate = function() {
+
+ if (this.key instanceof Phaser.BitmapData && this.key._dirty)
+ {
+ this.key.render();
+ }
+
+ if (this.exists)
+ {
+ if (this.body)
+ {
+ this.body.postUpdate();
+ }
+
+ if (this.fixedToCamera)
+ {
+ this._cache.x = this.game.camera.view.x + this.cameraOffset.x;
+ this._cache.y = this.game.camera.view.y + this.cameraOffset.y;
+ }
+ else
+ {
+ this._cache.x = this.x;
+ this._cache.y = this.y;
+ }
+
+ this.position.x = this._cache.x;
+ this.position.y = this._cache.y;
+ }
+
+};
+
+/**
+* Changes the Texture the Sprite is using entirely. The old texture is removed and the new one is referenced or fetched from the Cache.
+* This causes a WebGL texture update, so use sparingly or in low-intensity portions of your game.
+*
+* @method Phaser.Sprite#loadTexture
+* @memberof Phaser.Sprite
+* @param {string|Phaser.RenderTexture|Phaser.BitmapData|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, BitmapData 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.Sprite.prototype.loadTexture = function (key, frame) {
+
+ this.key = key;
+
+ if (key instanceof Phaser.RenderTexture)
+ {
+ this.currentFrame = this.game.cache.getTextureFrame(key.name);
+ }
+ else if (key instanceof Phaser.BitmapData)
+ {
+ this.setTexture(key.texture);
+ this.currentFrame = key.textureFrame;
+ }
+ else if (key instanceof PIXI.Texture)
+ {
+ this.currentFrame = frame;
+ }
+ else
+ {
+ if (typeof key === 'undefined' || this.game.cache.checkImageKey(key) === false)
+ {
+ key = '__default';
+ this.key = key;
+ }
+
+ if (this.game.cache.isSpriteSheet(key))
+ {
+ this.animations.loadFrameData(this.game.cache.getFrameData(key));
+
+ if (typeof frame !== 'undefined')
+ {
+ if (typeof frame === 'string')
+ {
+ this.frameName = frame;
+ }
+ else
+ {
+ this.frame = frame;
+ }
+ }
+ }
+ else
+ {
+ this.currentFrame = this.game.cache.getFrame(key);
+ this.setTexture(PIXI.TextureCache[key]);
+ }
+ }
+
+};
+
+/**
+* Moves the sprite so its center is located on the given x and y coordinates.
+* Doesn't change the anchor point of the sprite.
+*
+* @method Phaser.Sprite#centerOn
+* @memberof Phaser.Sprite
+* @param {number} x - The x coordinate (in world space) to position the Sprite at.
+* @param {number} y - The y coordinate (in world space) to position the Sprite at.
+* @return (Phaser.Sprite) This instance.
+*/
+Phaser.Sprite.prototype.centerOn = function(x, 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;
+
+};
+
+/**
+* Brings a 'dead' Sprite back to life, optionally giving it the health value specified.
+* A resurrected Sprite has its alive, exists and visible properties all set to true.
+* It will dispatch the onRevived event, you can listen to Sprite.events.onRevived for the signal.
+*
+* @method Phaser.Sprite#revive
+* @memberof Phaser.Sprite
+* @param {number} [health=1] - The health to give the Sprite.
+* @return (Phaser.Sprite) This instance.
+*/
+Phaser.Sprite.prototype.revive = function(health) {
+
+ if (typeof health === 'undefined') { health = 1; }
+
+ this.alive = true;
+ this.exists = true;
+ this.visible = true;
+ this.health = health;
+
+ if (this.events)
+ {
+ this.events.onRevived.dispatch(this);
+ }
+
+ return this;
+
+};
+
+/**
+* Kills a Sprite. A killed Sprite has its alive, exists and visible properties all set to false.
+* It will dispatch the onKilled event, you can listen to Sprite.events.onKilled for the signal.
+* Note that killing a Sprite is a way for you to quickly recycle it in a Sprite pool, it doesn't free it up from memory.
+* If you don't need this Sprite any more you should call Sprite.destroy instead.
+*
+* @method Phaser.Sprite#kill
+* @memberof Phaser.Sprite
+* @return (Phaser.Sprite) This instance.
+*/
+Phaser.Sprite.prototype.kill = function() {
+
+ this.alive = false;
+ this.exists = false;
+ this.visible = false;
+
+ if (this.events)
+ {
+ this.events.onKilled.dispatch(this);
+ }
+
+ return this;
+
+};
+
+/**
+* Destroys the Sprite. This removes it from its parent group, destroys the input, event and animation handlers if present
+* and nulls its reference to game, freeing it up for garbage collection.
+*
+* @method Phaser.Sprite#destroy
+* @memberof Phaser.Sprite
+*/
+Phaser.Sprite.prototype.destroy = function() {
+
+ if (this.filters)
+ {
+ this.filters = null;
+ }
+
+ if (this.parent)
+ {
+ this.parent.remove(this);
+ }
+
+ if (this.input)
+ {
+ this.input.destroy();
+ }
+
+ if (this.events)
+ {
+ this.events.destroy();
+ }
+
+ if (this.animations)
+ {
+ this.animations.destroy();
+ }
+
+ if (this.body)
+ {
+ this.body.destroy();
+ }
+
+ this.alive = false;
+ this.exists = false;
+ this.visible = false;
+
+ this.game = null;
+
+};
+
+/**
+* Damages the Sprite, this removes the given amount from the Sprites health property.
+* If health is then taken below zero Sprite.kill is called.
+*
+* @method Phaser.Sprite#damage
+* @memberof Phaser.Sprite
+* @param {number} amount - The amount to subtract from the Sprite.health value.
+* @return (Phaser.Sprite) This instance.
+*/
+Phaser.Sprite.prototype.damage = function(amount) {
+
+ if (this.alive)
+ {
+ this.health -= amount;
+
+ if (this.health < 0)
+ {
+ this.kill();
+ }
+ }
+
+ return this;
+
+};
+
+/**
+* Resets the Sprite. This places the Sprite at the given x/y world coordinates and then
+* sets alive, exists, visible and renderable all to true. Also resets the outOfBounds state and health values.
+* If the Sprite has a physics body that too is reset.
+*
+* @method Phaser.Sprite#reset
+* @memberof Phaser.Sprite
+* @param {number} x - The x coordinate (in world space) to position the Sprite at.
+* @param {number} y - The y coordinate (in world space) to position the Sprite at.
+* @param {number} [health=1] - The health to give the Sprite.
+* @return (Phaser.Sprite) This instance.
+*/
+Phaser.Sprite.prototype.reset = function(x, y, health) {
+
+ if (typeof health === 'undefined') { health = 1; }
+
+ // this.x = x;
+ // this.y = y;
+ this.world.setTo(x, y);
+ this.position.x = this.x;
+ this.position.y = this.y;
+ this.alive = true;
+ this.exists = true;
+ this.visible = true;
+ this.renderable = true;
+ this._outOfBoundsFired = false;
+
+ this.health = health;
+
+ if (this.body)
+ {
+ this.body.reset(false);
+ }
+
+ return this;
+
+};
+
+/**
+* Brings the Sprite to the top of the display list it is a child of. Sprites that are members of a Phaser.Group are only
+* bought to the top of that Group, not the entire display list.
+*
+* @method Phaser.Sprite#bringToTop
+* @memberof Phaser.Sprite
+* @return (Phaser.Sprite) This instance.
+*/
+Phaser.Sprite.prototype.bringToTop = function() {
+
+ if (this.parent)
+ {
+ this.parent.bringToTop(this);
+ }
+ else
+ {
+ this.game.world.bringToTop(this);
+ }
+
+ return this;
+
+};
+
+/**
+* Play an animation based on the given key. The animation should previously have been added via sprite.animations.add()
+* If the requested animation is already playing this request will be ignored. If you need to reset an already running animation do so directly on the Animation object itself.
+*
+* @method Phaser.Sprite#play
+* @memberof Phaser.Sprite
+* @param {string} name - The name of the animation to be played, e.g. "fire", "walk", "jump".
+* @param {number} [frameRate=null] - The framerate to play the animation at. The speed is given in frames per second. If not provided the previously set frameRate of the Animation is used.
+* @param {boolean} [loop=false] - Should the animation be looped after playback. If not provided the previously set loop value of the Animation is used.
+* @param {boolean} [killOnComplete=false] - If set to true when the animation completes (only happens if loop=false) the parent Sprite will be killed.
+* @return {Phaser.Animation} A reference to playing Animation instance.
+*/
+Phaser.Sprite.prototype.play = function (name, frameRate, loop, killOnComplete) {
+
+ if (this.animations)
+ {
+ return this.animations.play(name, frameRate, loop, killOnComplete);
+ }
+
+};
+
+/**
+* Returns the delta x value. The difference between Sprite.x now and in the previous step.
+*
+* @method Phaser.Sprite#deltaX
+* @memberof Phaser.Sprite
+* @return {number} The delta value. Positive if the motion was to the right, negative if to the left.
+*/
+Phaser.Sprite.prototype.deltaX = function () {
+
+ return this.world.x - this._cache.prevX;
+
+};
+
+/**
+* Returns the delta x value. The difference between Sprite.y now and in the previous step.
+*
+* @method Phaser.Sprite#deltaY
+* @memberof Phaser.Sprite
+* @return {number} The delta value. Positive if the motion was downwards, negative if upwards.
+*/
+Phaser.Sprite.prototype.deltaY = 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.
+* If you wish to work in radians instead of degrees use the property Sprite.rotation instead.
+* @name Phaser.Sprite#angle
+* @property {number} angle - Gets or sets the Sprites angle of rotation in degrees.
+*/
+Object.defineProperty(Phaser.Sprite.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.Sprite#frame
+* @property {number} frame - Gets or sets the current frame index and updates the Texture Cache for display.
+*/
+Object.defineProperty(Phaser.Sprite.prototype, "frame", {
+
+ get: function () {
+ return this.animations.frame;
+ },
+
+ set: function (value) {
+ this.animations.frame = value;
+ }
+
+});
+
+/**
+* @name Phaser.Sprite#frameName
+* @property {string} frameName - Gets or sets the current frame name and updates the Texture Cache for display.
+*/
+Object.defineProperty(Phaser.Sprite.prototype, "frameName", {
+
+ get: function () {
+ return this.animations.frameName;
+ },
+
+ set: function (value) {
+ this.animations.frameName = value;
+ }
+
+});
+
+/**
+* @name Phaser.Sprite#inCamera
+* @property {boolean} inCamera - Is this sprite visible to the camera or not?
+* @readonly
+*/
+Object.defineProperty(Phaser.Sprite.prototype, "inCamera", {
+
+ get: function () {
+ return this._cache.cameraVisible;
+ }
+
+});
+
+/**
+* @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.
+*
+* @name Phaser.Sprite#width
+* @property {number} width - The width of the Sprite in pixels.
+*/
+// Object.defineProperty(Phaser.Sprite.prototype, 'width', {
+
+// get: function() {
+// return this.scale.x * this.currentFrame.width;
+// },
+
+// set: function(value) {
+
+// this.scale.x = value / this.currentFrame.width;
+// this._cache.scaleX = value / this.currentFrame.width;
+// this._width = value;
+
+// }
+
+// });
+
+/**
+* The height 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.
+*
+* @name Phaser.Sprite#height
+* @property {number} height - The height of the Sprite in pixels.
+*/
+// Object.defineProperty(Phaser.Sprite.prototype, 'height', {
+
+// get: function() {
+// return this.scale.y * this.currentFrame.height;
+// },
+
+// set: function(value) {
+
+// this.scale.y = value / this.currentFrame.height;
+// this._cache.scaleY = value / this.currentFrame.height;
+// this._height = value;
+
+// }
+
+// });
+
+/**
+* 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.Sprite#inputEnabled
+* @property {boolean} inputEnabled - Set to true to allow this Sprite to receive input events, otherwise false.
+*/
+Object.defineProperty(Phaser.Sprite.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/physics/arcade/Body.js b/src/physics/arcade/Body.js
index 930ed22e..57c23358 100644
--- a/src/physics/arcade/Body.js
+++ b/src/physics/arcade/Body.js
@@ -69,6 +69,12 @@ Phaser.Physics.Arcade.Body = function (sprite) {
*/
this.angle = 0;
+ /**
+ * @property {number} deltaCap - The maximum a delta is allowed to reach before its capped.
+ * @default
+ */
+ this.deltaCap = 2;
+
/**
* @property {Phaser.Point} gravity - The gravity applied to the motion of the Body. This works in addition to any gravity set on the world.
*/
@@ -381,7 +387,7 @@ Phaser.Physics.Arcade.Body.prototype = {
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;
- console.log('body pre', this.preX, this.preY, 'now', this.x, this.y);
+ // console.log('body pre', this.preX, this.preY, 'now', this.x, this.y);
// This covers any motion that happens during this frame, not since the last frame
this.preX = this.x;
@@ -1438,32 +1444,74 @@ Phaser.Physics.Arcade.Body.prototype = {
/**
* Returns the delta x value. The amount the Body has moved horizontally in the current step.
+ * This value is capped by Body.deltaCap.
*
* @method Phaser.Physics.Arcade.Body#deltaX
* @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;
+
+ var d = this.x - this.preX;
+
+ if (d < -this.deltaCap)
+ {
+ d = -this.deltaCap;
+ }
+ else if (d > this.deltaCap)
+ {
+ d = this.deltaCap;
+ }
+
+ return d;
+
},
/**
* Returns the delta y value. The amount the Body has moved vertically in the current step.
+ * This value is capped by Body.deltaCap.
*
* @method Phaser.Physics.Arcade.Body#deltaY
* @return {number} The delta value. Positive if the motion was downwards, negative if upwards.
*/
deltaY: function () {
- return this.y - this.preY;
+
+ var d = this.y - this.preY;
+
+ if (d < -this.deltaCap)
+ {
+ d = -this.deltaCap;
+ }
+ else if (d > this.deltaCap)
+ {
+ d = this.deltaCap;
+ }
+
+ return d;
+
},
/**
* Returns the delta z value. The amount the Body has rotated in the current step.
+ * This value is capped by Body.deltaCap.
*
* @method Phaser.Physics.Arcade.Body#deltaZ
* @return {number} The delta value.
*/
deltaZ: function () {
- return this.rotation - this.preRotation;
+
+ var d = this.rotation - this.preRotation;
+
+ if (d < -this.deltaCap)
+ {
+ d = -this.deltaCap;
+ }
+ else if (d > this.deltaCap)
+ {
+ d = this.deltaCap;
+ }
+
+ return d;
+
}
};
diff --git a/src/pixi/Pixi.js b/src/pixi/Pixi.js
index 768ef4e4..3a4ebf3d 100644
--- a/src/pixi/Pixi.js
+++ b/src/pixi/Pixi.js
@@ -41,6 +41,21 @@ PIXI.scaleModes = {
NEAREST:1
};
+// Canvas specific controls
+PIXI.canvas = {
+
+ // If the Stage is transparent Pixi will use a canvas sized fillRect operation every frame to set the canvas background color.
+ // Setting this to false forces Pixi to update the view.style.backgroundColor instead.
+ FILL_RECT: true,
+
+ // If the Stage is transparent Pixi will use clearRect to clear the canvas unless you set this to false.
+ // You often don't need clearRect if you've got a large background image fully covering your canvas.
+ CLEAR_RECT: true,
+
+ // If true Pixi will round all x/y values for rendering only, stopping pixel interpolation. Handy for crisp pixel art.
+ PX_ROUND: false
+}
+
// interaction frequency
PIXI.INTERACTION_FREQUENCY = 30;
PIXI.AUTO_PREVENT_DEFAULT = true;
\ No newline at end of file
diff --git a/src/pixi/display/Stage.js b/src/pixi/display/Stage.js
index 50cea165..8871806e 100644
--- a/src/pixi/display/Stage.js
+++ b/src/pixi/display/Stage.js
@@ -63,6 +63,8 @@ PIXI.Stage = function(backgroundColor)
//optimize hit detection a bit
this.stage.hitArea = new PIXI.Rectangle(0,0,100000, 100000);
+ this.resetBackgroundColor = false;
+
this.setBackgroundColor(backgroundColor);
};
@@ -121,6 +123,7 @@ PIXI.Stage.prototype.setBackgroundColor = function(backgroundColor)
var hex = this.backgroundColor.toString(16);
hex = '000000'.substr(0, 6 - hex.length) + hex;
this.backgroundColorString = '#' + hex;
+ this.resetBackgroundColor = true;
};
/**
diff --git a/src/pixi/renderers/canvas/CanvasRenderer.js b/src/pixi/renderers/canvas/CanvasRenderer.js
index 267ad360..5ec8ce48 100644
--- a/src/pixi/renderers/canvas/CanvasRenderer.js
+++ b/src/pixi/renderers/canvas/CanvasRenderer.js
@@ -156,36 +156,35 @@ PIXI.CanvasRenderer.prototype.constructor = PIXI.CanvasRenderer;
*/
PIXI.CanvasRenderer.prototype.render = function(stage)
{
- //stage.__childrenAdded = [];
- //stage.__childrenRemoved = [];
-
// update textures if need be
PIXI.texturesToUpdate.length = 0;
PIXI.texturesToDestroy.length = 0;
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.globalAlpha = 1;
- if(this.view.style.backgroundColor !== stage.backgroundColorString )
+ // Update the background color / cls
+ if (!this.transparent)
{
- if(!this.transparent)
+ if (PIXI.canvas.FILL_RECT)
{
- this.context.globalAlpha = 1;
this.context.fillStyle = stage.backgroundColorString;
this.context.fillRect(0, 0, this.width, this.height);
}
- else
+ else if (stage.resetBackgroundColor)
{
- this.context.clearRect(0, 0, this.width, this.height);
+ this.view.style.backgroundColor = stage.backgroundColorString;
+ stage.resetBackgroundColor = false;
+ console.log('bgcolor reset', this.view.style.backgroundColor);
}
}
-
- //console.log(this.view.style.backgroundColor)
+
+ if (PIXI.canvas.CLEAR_RECT && !PIXI.canvas.FILL_RECT)
+ {
+ this.context.clearRect(0, 0, this.width, this.height);
+ }
this.renderDisplayObject(stage);