diff --git a/Gruntfile.js b/Gruntfile.js
index 0e12c14b..bb57821c 100644
--- a/Gruntfile.js
+++ b/Gruntfile.js
@@ -18,6 +18,7 @@ module.exports = function (grunt) {
'src/pixi/core/Matrix.js',
'src/pixi/core/Point.js',
'src/pixi/core/Rectangle.js',
+ 'src/pixi/core/Polygon.js',
'src/pixi/display/DisplayObject.js',
'src/pixi/display/DisplayObjectContainer.js',
'src/pixi/display/Sprite.js',
@@ -26,12 +27,30 @@ module.exports = function (grunt) {
'src/pixi/extras/Strip.js',
'src/pixi/extras/Rope.js',
'src/pixi/extras/TilingSprite.js',
+ 'src/pixi/filters/AbstractFilter.js',
+ 'src/pixi/filters/BlurFilter.js',
+ 'src/pixi/filters/BlurXFilter.js',
+ 'src/pixi/filters/BlurYFilter.js',
+ 'src/pixi/filters/ColorMatrixFilter.js',
+ 'src/pixi/filters/CrossHatchFilter.js',
+ 'src/pixi/filters/DisplacementFilter.js',
+ 'src/pixi/filters/DotScreenFilter.js',
'src/pixi/filters/FilterBlock.js',
- 'src/pixi/filters/MaskFilter.js',
+ 'src/pixi/filters/GreyFilter.js',
+ 'src/pixi/filters/InvertFilter.js',
+ 'src/pixi/filters/PixelateFilter.js',
+ 'src/pixi/filters/RGBSplitFilter.js',
+ 'src/pixi/filters/SepiaFilter.js',
+ 'src/pixi/filters/SmartBlurFilter.js',
+ 'src/pixi/filters/TwistFilter.js',
'src/pixi/primitives/Graphics.js',
'src/pixi/renderers/canvas/CanvasGraphics.js',
'src/pixi/renderers/canvas/CanvasRenderer.js',
+ 'src/pixi/renderers/webgl/PixiShader.js',
+ 'src/pixi/renderers/webgl/PrimitiveShader.js',
+ 'src/pixi/renderers/webgl/StripShader.js',
'src/pixi/renderers/webgl/WebGLBatch.js',
+ 'src/pixi/renderers/webgl/WebGLFilterManager.js',
'src/pixi/renderers/webgl/WebGLGraphics.js',
'src/pixi/renderers/webgl/WebGLRenderer.js',
'src/pixi/renderers/webgl/WebGLRenderGroup.js',
@@ -82,6 +101,7 @@ module.exports = function (grunt) {
'src/geom/Circle.js',
'src/geom/Point.js',
'src/geom/Rectangle.js',
+ 'src/geom/Polygon.js',
'src/net/Net.js',
'src/tween/TweenManager.js',
'src/tween/Tween.js',
diff --git a/README.md b/README.md
index d9d6e97c..a6b88205 100644
--- a/README.md
+++ b/README.md
@@ -5,7 +5,7 @@ Phaser 1.1
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.2 - Released: November 1st 2013
+Version: 1.1.3 - Released: -in development-
By Richard Davey, [Photon Storm](http://www.photonstorm.com)
@@ -37,186 +37,38 @@ Phaser is everything we ever wanted from an HTML5 game framework. It powers all
Change Log
----------
-Version 1.1.2 - November 1st 2013
+Version 1.1.3 - in build
-* New: You'll now find a complete Basic project Template in the resources/Project Templates folder. Will add more complex ones soon.
-* New: Phaser.Button now has the ability to set over/out/up/down sound effects so they play automatically based on those events.
-* New: Added init method to plugins, to be called as they are added to the PluginManager (thanks beeglebug)
-* New: Physics.Body now has a center property (issue 142, thanks MikeMnD)
-* New: Lots of fixes across Full Screen Mode support. Input now works, scaling restores properly, world scale is correct and anti-alias support added.
-* New: Added Group.cursor. This points to the first item added to a Group. You can move the cursor with Group.next() and Group.previous().
-* New: Added Tween.isTweening(object) to check if an object is currently being tweened or not (thanks mikehamil10)
-* New: Added getMagnitude, setMagnitude, normalize and isZero methods to Point (thanks beeglebug)
-* New/Change: Group.callAll now supports nested functions and a context, making it really powerful!
-* Updated: Fixed a few final bugs in the Sprite body and bounds calculations, in turn this resolved the Tilemap collision issues in the 1.1 release.
-* Updated: Finished documentation for the Phaser.Button class.
-* Updated: Fixed the Invaders game sample and enhanced it.
-* Updated: Fixed the Star Struck game sample and enhanced it.
-* Updated: If you pause an Animation, when you next play it it'll resume (un-pause itself).
-* Updated: hexToRGB now accepts short hex codes (#EEE) (thanks beeglebug)
-* Updated: State functions (preload, update, render, etc) are now passed the current game as a parameter (thanks beeglebug)
-* Updated: If your game is running in Canvas (not WebGL) you can now set Stage.backgroundColor to rgba style CSS strings, allowing for semi-transparent game backgrounds.
-* Updated: event.preventDefault() has been added to all Mouse event handlers.
-* Updated: Sprite.deltaX/Y removed due to non-use. prevX/Y values moved to Sprite._cache.prevX/Y.
-* Updated: Due to missing extends parameter the Sprite prototype was picking up functions from classes it never meant to (Button, TilemapLayer), now fully isolated.
-* Fixed issue 135 - Added typeof checks into most ArcadePhysics functions to avoid errors with zero values.
-* Fixed issue 136 - distanceTo using worldX/Y instead of x/y.
-* Fixed lots of examples where the cursor keys / space bar were not locked from moving the browser page (if you find any more, please tell us!)
-* Fixed issue 149 - Starling XML files now load properly again, also created an Example to show use of them (thanks haden)
-* Fixed an issue where if the Starling XML file didn't contain a frameX/Y value it would crash on import.
-* Fixed the Multiple Animations Example - it's now a lovely underwater scene :)
-* Fixed issue 141 - If a Sprite is dragged and you release the Pointer while not over the Sprite, it will think it's still over it (thanks Paratron)
-* Fixed issue 88 - Incorrect game.input.x/y values on click with scaled stage (thanks DrHackenstein)
-* Fixed issue 143 - Entering full screen mode made the Input x/y coordinates go wrong.
+* New: Updated to use the latest version of Pixi.js - which means you can now use all the sexy new WebGL filters they added :)
+* New: Sprite.animations.getAnimation will return an animation instance which was added by name.
+* New: Added Mouse.button which is set to the button that was pressed: Phaser.Mouse.LEFT_BUTTON, MIDDLE_BUTTON or RIGHT_BUTTON (thanks wKLV)
+* New: Added Mouse.pointerLock signal which you can listen to whenever the browser enters or leaves pointer lock mode.
+* New: StageScaleMode.forceOrientation allows you to lock your game to one orientation and display a Sprite (i.e. a "please rotate" screen) when incorrect.
+* New: World.visible boolean added, toggles rendering of the world on/off entirely.
+* New: Polygon class & drawPolygon method added to Graphics (thanks rjimenezda)
+* New: Added Group.iterate, a powerful way to count or return child that match a certain criteria. Refactored Group to use iterate, lots of repeated code cut.
+* New: Added Group.sort. You can now sort the Group based on any given numeric property (x, y, health), finally you can do depth-sorting :) Example created to show.
+* Fixed: Mouse.stop now uses the true useCapture, which means the event listeners stop listening correctly (thanks beeglebug)
+* Fixed: Input Keyboard example fix (thanks Atrodilla)
+* Fixed: BitmapText.destroy now checks if it has a canvas before calling parentNode on it.
+* Fixed: Group.swap had a hellish to find bug that only manifested when B-A upward swaps occured. Hours of debugging later = bug crushed.
+* Updated: ArcadePhysics.updateMotion applies the dt to the velocity calculations as well as position now (thanks jcs)
+* Updated: RequestAnimationFrame now retains the callbackID which is passed to cancelRequestAnimationFrame.
+* Updated: Button now goes back to over state when setFrames used in action (thanks beeglebug)
+* Updated: plugins now have a postUpdate callback (thanks cocoademon)
-Version 1.1.1 - October 26th 2013
-
-* Quick patch to get Phaser.AUTO working again on Firefox / Android.
-* Any key added via addKey now automatically adds it to the capture list.
-
-Version 1.1 - October 25th 2013
-
-What's New:
-
-* JSDoc is go! We've added jsdoc3 blocks to every property and function, in every file and published the API docs to the docs folder.
-* Brand new Example system (no more php!) and over 150 examples to learn from too.
-* New TypeScript definitions file generated (in the build folder - thanks to TomTom1229 for manually enhancing this).
-* New Grunt based build system added (thanks to Florent Cailhol)
-* New: Phaser.Animation.generateFrameNames - really useful when creating animation data from texture atlases using file names, not indexes.
-* Added Sprite.play as a handy short-cut to play an animation already loaded onto a Sprite.
-* Added Canvas.setUserSelect() to disable touchCallouts and user selections within the canvas.
-* Added Keyboard.addKey() which creates a new Phaser.Key object that can be polled for updates, pressed states, etc. See the 2 new examples showing use.
-* Added Button.freezeFrames boolean. Stops the frames being set on mouse events if true.
-* Extended the Loader 404 error to display the url of the file that didn't load as well as the key.
-* New: Direction constants have been added to Sprites and adjust based on body motion.
-* Brand new Sprite.update loop handler. Combined with the transform cache fix and further optimisations this is now much quicker to execute.
-* Added Keyboard.createCursorKeys() which creates an object with 4 Key objects inside it mapped to up, down, left and right. See the new example in the input folder.
-* Added Body.skipQuadTree boolean for more fine-grained control over when a body is added to the World QuadTree.
-* Re-implemented Angular Velocity and Angular Acceleration on the Sprite.body and created 2 new examples to show use.
-* Added Sprite.fixedToCamera boolean. A Sprite that is fixed to the camera doesn't move with the world, but has its x/y coordinates relative to the top-left of the camera.
-* Added Group.createMultiple - useful when you need to create a Group of identical sprites for pooling, such as bullets.
-* Added Group.total. Same as Group.length, but more in line with the rest of the Group naming.
-* Added Sprite.outOfBoundsKill boolean flag. Will automatically kill a sprite that leaves the game World bounds (off by default).
-* Lots of changes and fixes in ArcadePhysics, including:
-* Functions with "mouse" in the title have been updated to "pointer" to more accurately reflect what they do.
-* New velocity functions: moveToObject, moveToPointer, moveToXY
-* New acceleration functions: accelerateToObject, accelerateToPointer, accelerateToXY
-* New distance functions: distanceBetween, distanceToXY, distanceToPointer
-* New angle functions: angleBetween, angleToXY, angleToPointer
-* velocityFromAngle and velocityFromRotation added with examples created.
-* Added killOnComplete parameter to Animation.play. Really useful in situations where you want a Sprite to animate once then kill itself on complete, like an explosion effect.
-* Added Sprite.loadTexture(key, frame) which allows you to load a new texture set into an existing sprite rather than having to create a new sprite.
-* Added Sprite.destroy back in again and made it a lot more robust at cleaning up child objects.
-* Added 'return this' to all the core Loader functions so you can chain load calls if you so wish.
-* Added Text.destroy() and BitmapText.destroy(), also updated Group.remove to make it more bullet-proof when an element doesn't have any events.
-* Added Phaser.Utils.shuffle to shuffle an array.
-* Added Graphics.destroy, x, y and updated angle functions.
-* Added AnimationManager.refreshFrame - will reset the texture being used for a Sprite (useful after a crop rect clear)
-* Added Physics.overlap(sprite1, sprite2) for quick body vs. body overlap tests with no separation performed.
-* On a busy page it's possible for the game to boot with an incorrect stage offset x/y which can cause input events to be calculated wrong. A new property has been added to Stage to combat this issue: Stage.checkOffsetInterval. By default it will check the canvas offset every 2500ms and adjust it accordingly. You can set the value to 'false' to disable the check entirely, or set a higher or lower value. We recommend that you get the value quite low during your games preloader, but once the game has fully loaded hopefully the containing page will have settled down, so it's probably safe to disable the check entirely.
-* Added Rectangle.floorAll to floor all values in a Rectangle (x, y, width and height).
-
-What's changed:
-
-* Renamed Phaser.Text.text to Phaser.Text.content to avoid conflict and overwrite from Pixi local var.
-* Renamed Phaser.Text.style to Phaser.Text.font to avoid conflict and overwrite from Pixi local var.
-* Phaser.Button now sets useHandCursor to true by default.
-* Change: When you start a new State all active tweens are now purged.
-* When the game boots it will now by default disable user-select and touch action events on the game canvas.
-* Moved LinkedList.dump to Debug.dumpLinkedList(list)
-* Phaser.Animation.Frame is now Phaser.Frame
-* Phaser.Animation.FrameData is now Phaser.FrameData
-* Phaser.Animation.Parser is now Phaser.AnimationParser (also the file has renamed from Parser.js to AnimationParser.js)
-* Phaser.Loader.Parser is now Phaser.LoaderParser (also the file has renamed from Parser.js to LoaderParser.js)
-* Change: We've removed the scrollFactor property from all Game Objects. Sorry, but the new Camera system doesn't work with it and it caused all kinds of issues anyway. We will sort out a replacement for it at a later date.
-* Change: World now extends Phaser.Group. As a result we've updated GameObjectFactory and other classes that linked to it. If you have anywhere in your code that used to reference world.group you can just remove 'group' from that. So before, world.group.add() is now just world.add().
-* Change: The Camera has been completely revamped. Rather than adjusting the position of all display objects (bad) it now just shifts the position of the single world container (good!), this is much quicker and also stops the game objects positions from self-adjusting all the time, allowing for them to be properly nested with other containers.
-* Made Sprite.body optional and added in checks, so you can safely null the Sprite body object if using your own physics system and not impact rendering.
-* Moved the Camera update checks to World.postUpdate, so all the sprites get the correct adjusted camera position.
-* The default Game.antialias value is now 'true', so graphics will be smoothed automatically in canvas. Disable it via the Game constructor or Canvas utils.
-* Phaser.Group now automatically calls updateTransform on any child added to it (avoids temp. frame glitches when new objects are rendered on their first frame).
-
-What has been updated:
-
-* Complete overhaul of Physics.Arcade.Body - now significantly more stable and faster too.
-* Updated ArcadePhysics.separateX/Y to use new body system - much better results now.
-* Added World.postUpdate - all sprite position changes, as a result of physics, happen here before the render.
-* Added Animation.paused - can be set to true/false.
-* Added support for Body.maxVelocity (thanks cocoademon)
-* InputHandler now creates the _pointerData array on creation and populates with one empty set of values, so pointerOver etc all work before a start call.
-* Removed the callbackContext parameter from Group.callAll because it's no longer needed.
-* Updated Group.forEach, forEachAlive and forEachDead so you can now pass as many parameters as you want, which will all be given to the callback after the child.
-* Updated build script so it can be run from the command-line and includes UMD wrappers (thanks iaincarsberg)
-* World.randomX/Y now returns values anywhere in the world.bounds range (if set, otherwise 0), including negative values.
-* Updated InputHandler to use Math.round rather than Math.floor when snapping an object during drag.
-* If you didn't provide the useNumericIndex parameter then AnimationManager.add will set the value by looking at the datatype of the first element in the frames array.
-* Group.create now sets the visible and alive properties of the Sprite to the same value as the 'exists' parameter.
-* World.randomX/Y now works with negative World.bounds values.
-* Tweens .to will now always return the parent (thanks powerfear)
-* You can now pass a PIXI.Texture to Sprite (you also need to pass a Phaser.Frame as the frame parameter) but this is useful for Sprites sharing joint canvases.
-* Group.alpha is now exposed publically and changes the Group container object (not the children directly, who can still have their own alpha values)
-* Device.webGL uses new inspection code to accurately catch more webGL capable devices.
-* Debug.renderSpriteBody updated to use a the new Sprite.Body.screenX/Y properties.
-* Additional checks added to AnimationManager.frame/frameName on the given values.
-* You can now null a Sprite.crop and it will clear down the crop rect area correctly.
-* Phaser.Time physicsElapsed delta timer clamp added. Stops rogue iOS / slow mobile timer errors causing crazy high deltas.
-* Animation.generateFrameNames can now work in reverse, so the start/stop values can create frames that increment or decrement respectively.
-* Loader updated to use xhr.responseText when loading json, csv or text files. xhr.response is still used for Web Audio binary files (thanks bubba)
-* Input.onDown and onUp events now dispatch the original event that triggered them (i.e. a MouseEvent or TouchEvent) as the 2nd parameter, after the Pointer (thanks rezoner)
-* Updated Sprite.crop significantly. Values are now cached, stopping constant Texture frame updates and you can do sprite.crop.width++ for example (thanks haden)
-* Change: Sprite.crop needs to be enabled with sprite.cropEnabled = true.
-* Sprite.loadTexture now works correctly with static images, RenderTextures and Animations.
-* Lots of fixes within Sprite.bounds. The bounds is now correct regardless of rotation, anchor or scale of the Sprite or any of its parent objects.
-
-What has been fixed:
-
-* QuadTree bug found in 1.0.5 now fixed. The QuadTree is updated properly now using localTransform values.
-* Fixed the Bounce.In and Bounce.InOut tweens (thanks XekeDeath)
-* Fixed an issue in Animation.update where if the game was paused it would get an insane delta timer throwing a uuid error.
-* Added PixiPatch.js to patch in a few essential features until Pixi is updated.
-* Fixed issue in Animation.play where the given frameRate and loop values wouldn't overwrite those set on construction.
-* Fixed small bug stopping Tween.pause / resume from resuming correctly when called directly.
-* Fixed an issue where Tweens.removeAll wasn't clearing tweens in the addition queue.
-* Fixed Particle Emitters when using Emitter width/height (thanks XekeDeath)
-* Made animation looping more robust when skipping frames (thanks XekeDeath)
-* Fix for incorrect new particle positioning (issue #73) (thanks cottonflop)
-* Fixed issue in Sound.play where if you gave a missing marker it would play the whole sound sprite instead.
-* Button.setFrames will set the current frame based on the button state immediately.
-* Loaded.setPreloadSprite now rounds the width/height values and starts from 1. This fixes canvas draw errors in IE9/10 and Firefox.
-* Fixed issue causing Keyboard.justPressed to always fire (thanks stemkoski)
-* Fixed bug in LinkedList#remove that could cause first to point to a dead node (thanks onedayitwillmake)
-* Fixed Cache.addDefaultImage so the default image works in Canvas as well as WebGL. Updated to a new image (32x32 black square with green outline)
-* Fixed a bug in the Sprite transform cache check that caused the skew/scale cache to get constantly invalidated - now only updates as needed, significant performance increase!
-* Fixed typo in StageScaleMode so it's not pageAlignVeritcally any longer, but pageAlignVertically.
-* Fixed issue in Group.countLiving / countDead where the value was off by one (thanks mjablonski)
-* Fixed issue with a jittery Camera if you moved a Sprite via velocity instead of x/y placement.
-* Fixed the RandomDataGenerator.sow method so if you give in the same seed you'll now get the same results (thanks Hsaka)
-* Fixed Issue #101 (Mouse Button 0 is not recognised, thanks rezoner)
-* Fixed an issue where creating an animation with just one frame with an index of zero would cause a UUID error (thanks SYNYST3R1)
-* Fixed Rectangle.union (thanks andron77)
-* Fixed Sound.resume so it now correctly resumes playback from the point it was paused (fixes issue 51, thanks Yora).
-* Fixed issue 105 where a dragged object that was destroyed would cause an Input error (thanks onedayitwillmake)
-* Fixed Issue 111 - calling Kill on a Phaser.Graphics instance causes error on undefined events.
-* Game.destroy will now stop the raf from running as well as close down all input related event listeners (issue 92, thanks astrism)
-* Pixel Perfect click detection now works even if the Sprite is part of a texture atlas.
-
-
-
-Outstanding Tasks
------------------
-
-* TODY: Loader conflict if 2 keys are the same even if they are in different packages (i.e. you can't use "title" for both and image and sound file).
-* TODO: d-pad example (http://www.html5gamedevs.com/topic/1574-gameinputondown-question/)
-* TODO: more touch input examples (http://www.html5gamedevs.com/topic/1556-mobile-touch-event/)
-* TODO: Sound.addMarker hh:mm:ss:ms
-* TODO: swap state (non-destructive shift)
-* TODO: rotation offset
-* TODO: Look at HiDPI Canvas settings
+You can view the complete Change Log for all previous versions at https://github.com/photonstorm/phaser/changelog.md
How to Build
------------
-A Grunt script has been provided that will build Phaser from source as well as the examples. Run `grunt` in the phaser folder for a list of command-line options.
+We provide a fully compiled version of Phaser in the `build` directory, in both plain and minified formats.
+
+We also provide a Grunt script that will build Phaser from source along with all the examples.
+
+Run `grunt` in the phaser folder for a list of command-line options.
+
+
Requirements
------------
@@ -302,6 +154,7 @@ Road Map
The 1.1 release was a massive under-taking, but we're really happy with how Phaser is progressing. It's becoming more solid and versatile with each iteration. Here is what's on our road map for future versions:
+* Enhance the State Management, so you can perform non-destructive State swaps and persistence.
* Integration with an advanced physics system. We've been experimenting with p2.js but have yet to conclude our research.
* A more advanced Particle system, one that can render to a single canvas (rather than spawn hundreds of Sprites), more advanced effects, etc.
* Massively enhance the audio side of Phaser. Although it does what it does well, it could do with taking more advantage of Web Audio - echo effects, positional sound, etc.
@@ -314,6 +167,15 @@ The 1.1 release was a massive under-taking, but we're really happy with how Phas
* Flash CC HTML5 export integration.
* Game parameters stored in Google Docs.
* More advanced tile map features. Better support for advanced Tiled features and also I want to add full support for DAME tilemaps.
+* Add a d-pad example (http://www.html5gamedevs.com/topic/1574-gameinputondown-question/)
+* Create more touch input examples (http://www.html5gamedevs.com/topic/1556-mobile-touch-event/)
+* Look at HiDPI Canvas settings.
+
+Some specific features / issues we will address soon:
+
+* Loader conflict if 2 keys are the same even if they are in different packages (i.e. you can't use "title" for both and image and sound file).
+* Sound.addMarker hh:mm:ss:ms.
+* Add support for a rotation offset.
Learn By Example
----------------
@@ -351,26 +213,7 @@ Please add them to the [Issue Tracker][1] with as much info as possible.
License
-------
-The MIT License (MIT)
-
-Copyright (c) 2013 Richard Davey, Photon Storm Ltd.
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of
-this software and associated documentation files (the "Software"), to deal in
-the Software without restriction, including without limitation the rights to
-use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
-the Software, and to permit persons to whom the Software is furnished to do so,
-subject to the following conditions:
-
-The above copyright notice and this permission notice shall be included in all
-copies or substantial portions of the Software.
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
-IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
-FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
-COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
-IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
-CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+Phaser is released under the (http://opensource.org/licenses/MIT) MIT License.
[1]: https://github.com/photonstorm/phaser/issues
[phaser]: https://github.com/photonstorm/phaser
diff --git a/build/config.php b/build/config.php
index e41fb353..f6d76bc4 100644
--- a/build/config.php
+++ b/build/config.php
@@ -2,41 +2,67 @@
// All JS files in build order.
// Much easier for debugging re: line numbers
?>
-
-
-
-
+
+
+
+
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/build/phaser.d.ts b/build/phaser.d.ts
index 249e9d2a..0a29e288 100644
--- a/build/phaser.d.ts
+++ b/build/phaser.d.ts
@@ -1,5 +1,6 @@
declare class Phaser {
static VERSION: string;
+ static DEV_VERSION: string;
static GAMES: Array;
static AUTO: number;
static CANVAS: number;
@@ -252,7 +253,7 @@ declare module Phaser {
}
class Game {
- constructor(width: number, height: number, renderer: number, parent: string, state: Phaser.StateManager, transparent: boolean, antialias: boolean);
+ constructor(width: number, height: number, renderer: number, parent: string, state: object, transparent: boolean, antialias: boolean);
id: number;
width: number;
height: number;
diff --git a/build/phaser.js b/build/phaser.js
index 1113e7ac..0c44531d 100644
--- a/build/phaser.js
+++ b/build/phaser.js
@@ -18,7 +18,7 @@
*
* Phaser - http://www.phaser.io
*
-* v1.1.2 - Built at: Fri Nov 01 2013 18:12:54
+* v1.1.3 - Built at: Thu Nov 07 2013 06:09:12
*
* By Richard Davey http://www.photonstorm.com @photonstorm
*
@@ -57,8 +57,8 @@ var PIXI = PIXI || {};
*/
var Phaser = Phaser || {
- VERSION: '1.1.2',
- DEV_VERSION: '1.1.2',
+ VERSION: '1.1.3',
+ DEV_VERSION: '1.1.3',
GAMES: [],
AUTO: 0,
CANVAS: 1,
@@ -76,6 +76,7 @@ var Phaser = Phaser || {
TILEMAP: 9,
TILEMAPLAYER: 10,
EMITTER: 11,
+ POLYGON: 12,
NONE: 0,
LEFT: 1,
@@ -102,6 +103,12 @@ PIXI.InteractionManager = function (dummy) {
*/
Phaser.Utils = {
+ /**
+ * A standard Fisher-Yates Array shuffle implementation.
+ * @method Phaser.Utils.shuffle
+ * @param {array} array - The array to shuffle.
+ * @return {array} The shuffled array.
+ */
shuffle: function (array) {
for (var i = array.length - 1; i > 0; i--)
@@ -118,14 +125,14 @@ Phaser.Utils = {
/**
* Javascript string pad http://www.webtoolkit.info/.
- * pad = the string to pad it out with (defaults to a space)
+ * pad = the string to pad it out with (defaults to a space)
* dir = 1 (left), 2 (right), 3 (both)
* @method Phaser.Utils.pad
* @param {string} str - The target string.
* @param {number} len - Description.
* @param {number} pad - the string to pad it out with (defaults to a space).
* @param {number} [dir=3] the direction dir = 1 (left), 2 (right), 3 (both).
- * @return {string}
+ * @return {string} The padded string
*/
pad: function (str, len, pad, dir) {
@@ -347,7 +354,7 @@ PIXI.mat3.create = function()
matrix[6] = 0;
matrix[7] = 0;
matrix[8] = 1;
-
+
return matrix;
}
@@ -363,7 +370,7 @@ PIXI.mat3.identity = function(matrix)
matrix[6] = 0;
matrix[7] = 0;
matrix[8] = 1;
-
+
return matrix;
}
@@ -390,35 +397,35 @@ PIXI.mat4.create = function()
matrix[13] = 0;
matrix[14] = 0;
matrix[15] = 1;
-
+
return matrix;
}
-PIXI.mat3.multiply = function (mat, mat2, dest)
+PIXI.mat3.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],
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;
}
@@ -435,11 +442,11 @@ PIXI.mat3.clone = function(mat)
matrix[6] = mat[6];
matrix[7] = mat[7];
matrix[8] = mat[8];
-
+
return matrix;
}
-PIXI.mat3.transpose = function (mat, dest)
+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) {
@@ -467,30 +474,30 @@ PIXI.mat3.transpose = function (mat, dest)
return dest;
}
-PIXI.mat3.toMat4 = function (mat, 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;
}
@@ -518,19 +525,19 @@ PIXI.mat4.create = function()
matrix[13] = 0;
matrix[14] = 0;
matrix[15] = 1;
-
+
return matrix;
}
-PIXI.mat4.transpose = function (mat, dest)
+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 (!dest || mat === dest)
{
var a01 = mat[1], a02 = mat[2], a03 = mat[3],
a12 = mat[6], a13 = mat[7],
a23 = mat[11];
-
+
mat[1] = mat[4];
mat[2] = mat[8];
mat[3] = mat[12];
@@ -545,7 +552,7 @@ PIXI.mat4.transpose = function (mat, dest)
mat[14] = a23;
return mat;
}
-
+
dest[0] = mat[0];
dest[1] = mat[4];
dest[2] = mat[8];
@@ -565,18 +572,18 @@ PIXI.mat4.transpose = function (mat, dest)
return dest;
}
-PIXI.mat4.multiply = function (mat, mat2, dest)
+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];
+ 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;
@@ -620,19 +627,19 @@ PIXI.mat4.multiply = function (mat, mat2, dest)
* The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis.
*
* @class Point
- * @constructor
- * @param x {number} position of the point
- * @param y {number} position of the point
+ * @constructor
+ * @param x {Number} position of the point
+ * @param y {Number} position of the point
*/
PIXI.Point = function(x, y)
{
/**
- * @property x
+ * @property x
* @type Number
* @default 0
*/
this.x = x || 0;
-
+
/**
* @property y
* @type Number
@@ -664,11 +671,11 @@ PIXI.Point.prototype.constructor = PIXI.Point;
* the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height.
*
* @class Rectangle
- * @constructor
- * @param x {number} The X coord of the upper-left corner of the rectangle
- * @param y {number} The Y coord of the upper-left corner of the rectangle
- * @param width {number} The overall wisth of this rectangle
- * @param height {number} The overall height of this rectangle
+ * @constructor
+ * @param x {Number} The X coord of the upper-left corner of the rectangle
+ * @param y {Number} The Y coord of the upper-left corner of the rectangle
+ * @param width {Number} The overall width of this rectangle
+ * @param height {Number} The overall height of this rectangle
*/
PIXI.Rectangle = function(x, y, width, height)
{
@@ -678,21 +685,21 @@ PIXI.Rectangle = function(x, y, width, height)
* @default 0
*/
this.x = x || 0;
-
+
/**
* @property y
* @type Number
* @default 0
*/
this.y = y || 0;
-
+
/**
* @property width
* @type Number
* @default 0
*/
this.width = width || 0;
-
+
/**
* @property height
* @type Number
@@ -716,8 +723,8 @@ PIXI.Rectangle.prototype.clone = function()
* Checks if the x, and y coords 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
+ * @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
*/
PIXI.Rectangle.prototype.contains = function(x, y)
@@ -729,7 +736,7 @@ PIXI.Rectangle.prototype.contains = function(x, y)
if(x >= x1 && x <= x1 + this.width)
{
var y1 = this.y;
-
+
if(y >= y1 && y <= y1 + this.height)
{
return true;
@@ -743,6 +750,84 @@ PIXI.Rectangle.prototype.contains = function(x, y)
PIXI.Rectangle.prototype.constructor = PIXI.Rectangle;
+/**
+ * @author Adrien Brault
+ */
+
+/**
+ * @class Polygon
+ * @constructor
+ * @param points* {Array|Array|Point...|Number...} This can be an array of Points that form the polygon,
+ * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
+ * all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the
+ * arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are
+ * Numbers.
+ */
+PIXI.Polygon = function(points)
+{
+ //if points isn't an array, use arguments as the array
+ if(!(points instanceof Array))
+ points = Array.prototype.slice.call(arguments);
+
+ //if this is a flat array of numbers, convert it to points
+ if(typeof points[0] === 'number') {
+ var p = [];
+ for(var i = 0, il = points.length; i < il; i+=2) {
+ p.push(
+ new PIXI.Point(points[i], points[i + 1])
+ );
+ }
+
+ points = p;
+ }
+
+ this.points = points;
+}
+
+/**
+ * Creates a clone of this polygon
+ *
+ * @method clone
+ * @return {Polygon} a copy of the polygon
+ */
+PIXI.Polygon.prototype.clone = function()
+{
+ var points = [];
+ for (var i=0; i y) != (yj > y)) && (x < (xj - xi) * (y - yi) / (yj - yi) + xi);
+
+ if(intersect) inside = !inside;
+ }
+
+ return inside;
+}
+
+// constructor
+PIXI.Polygon.prototype.constructor = PIXI.Polygon;
+
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
@@ -757,7 +842,6 @@ PIXI.DisplayObject = function()
{
this.last = this;
this.first = this;
-
/**
* The coordinate of the object relative to the local coordinates of the parent.
*
@@ -910,6 +994,9 @@ PIXI.DisplayObject = function()
this._sr = 0;
this._cr = 1;
+
+ this.filterArea = new PIXI.Rectangle(0,0,1,1);
+
/*
* MOUSE Callbacks
*/
@@ -1034,16 +1121,71 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', {
},
set: function(value) {
- this._mask = value;
-
+
if(value)
{
- this.addFilter(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.removeFilter(this._mask);
+ this._mask.renderable = true;
}
+
+ this._mask = value;
+ }
+});
+
+/**
+ * Sets the filters for the displayObject.
+ * * IMPORTANT: This is a webGL only feature and will be ignored by the canvas renderer.
+ * To remove filters simply set this property to 'null'
+ * @property filters
+ * @type Array An array of filters
+ */
+Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', {
+ get: function() {
+ return this._filters;
+ },
+ set: function(value) {
+
+ 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++)
+ {
+ var filterPasses = value[i].passes;
+ for (var j = 0; j < filterPasses.length; j++)
+ {
+ passes.push(filterPasses[j]);
+ };
+ };
+
+ value.start.filterPasses = passes;
+ }
+ else
+ {
+ if(this._filters)this.removeFilter(this._filters);
+ }
+
+ this._filters = value;
+
+
+
+
}
});
@@ -1054,23 +1196,31 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', {
* @param mask {Graphics} the graphics object to use as a filter
* @private
*/
-PIXI.DisplayObject.prototype.addFilter = function(mask)
+PIXI.DisplayObject.prototype.addFilter = function(data)
{
- if(this.filter)return;
- this.filter = true;
+ //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();
- start.mask = mask;
- end.mask = mask;
+ 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
*/
@@ -1142,8 +1292,6 @@ PIXI.DisplayObject.prototype.addFilter = function(mask)
this.__renderGroup.addFilterBlocks(start, end);
}
- mask.renderable = false;
-
}
/*
@@ -1152,13 +1300,14 @@ PIXI.DisplayObject.prototype.addFilter = function(mask)
* @method removeFilter
* @private
*/
-PIXI.DisplayObject.prototype.removeFilter = function()
+PIXI.DisplayObject.prototype.removeFilter = function(data)
{
- if(!this.filter)return;
- this.filter = false;
-
+ //if(!this.filter)return;
+ //this.filter = false;
+ console.log("YUOIO")
// modify the list..
- var startBlock = this.first;
+ var startBlock = data.start;
+
var nextObject = startBlock._iNext;
var previousObject = startBlock._iPrev;
@@ -1168,9 +1317,8 @@ PIXI.DisplayObject.prototype.removeFilter = function()
this.first = startBlock._iNext;
-
// remove the end filter
- var lastBlock = this.last;
+ var lastBlock = data.end;
var nextObject = lastBlock._iNext;
var previousObject = lastBlock._iPrev;
@@ -1189,9 +1337,6 @@ PIXI.DisplayObject.prototype.removeFilter = function()
if(!updateLast)break;
}
- var mask = startBlock.mask
- mask.renderable = true;
-
// if webGL...
if(this.__renderGroup)
{
@@ -1287,18 +1432,6 @@ PIXI.DisplayObjectContainer = function()
PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype );
PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer;
-//TODO make visible a getter setter
-/*
-Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'visible', {
- get: function() {
- return this._visible;
- },
- set: function(value) {
- this._visible = value;
-
- }
-});*/
-
/**
* Adds a child to the container.
*
@@ -1342,7 +1475,7 @@ PIXI.DisplayObjectContainer.prototype.addChild = function(child)
var previousObject;
// this could be wrong if there is a filter??
- if(this.filter)
+ if(this._filters || this._mask)
{
previousObject = this.last._iPrev;
}
@@ -1392,7 +1525,7 @@ PIXI.DisplayObjectContainer.prototype.addChild = function(child)
*
* @method addChildAt
* @param child {DisplayObject} The child to add
- * @param index {number} The index to place the child in
+ * @param index {Number} The index to place the child in
*/
PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index)
{
@@ -1527,7 +1660,7 @@ PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2)
* Returns the Child at the specified index
*
* @method getChildAt
- * @param index {number} The index to get the child from
+ * @param index {Number} The index to get the child from
*/
PIXI.DisplayObjectContainer.prototype.getChildAt = function(index)
{
@@ -1624,7 +1757,6 @@ PIXI.DisplayObjectContainer.prototype.updateTransform = function()
this.children[i].updateTransform();
}
}
-
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
@@ -1779,7 +1911,7 @@ PIXI.Sprite.prototype.setTexture = function(texture)
PIXI.Sprite.prototype.onTextureUpdate = function(event)
{
//this.texture.removeEventListener( 'update', this.onTextureUpdateBind );
-
+
// so if _width is 0 then width was not set..
if(this._width)this.scale.x = this._width / this.texture.frame.width;
if(this._height)this.scale.y = this._height / this.texture.frame.height;
@@ -1822,7 +1954,6 @@ PIXI.Sprite.fromImage = function(imageId)
return new PIXI.Sprite(texture);
}
-
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
@@ -1833,11 +1964,10 @@ PIXI.Sprite.fromImage = function(imageId)
* @class Stage
* @extends DisplayObjectContainer
* @constructor
- * @param backgroundColor {number} the background color of the stage, easiest way to pass this in is in hex format
+ * @param backgroundColor {Number} the background color of the stage, easiest way to pass this in is in hex format
* like: 0xFFFFFF for white
- * @param interactive {Boolean} enable / disable interaction (default is false)
*/
-PIXI.Stage = function(backgroundColor, interactive)
+PIXI.Stage = function(backgroundColor)
{
PIXI.DisplayObjectContainer.call( this );
@@ -1857,7 +1987,7 @@ PIXI.Stage = function(backgroundColor, interactive)
* @property interactive
* @type Boolean
*/
- this.interactive = interactive;
+ this.interactive = true;
/**
* The interaction manage for this stage, manages all interactive activity on the stage
@@ -1893,6 +2023,18 @@ PIXI.Stage = function(backgroundColor, interactive)
PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
PIXI.Stage.prototype.constructor = PIXI.Stage;
+/**
+ * Sets another DOM element which can receive mouse/touch interactions instead of the default Canvas element.
+ * This is useful for when you have other DOM elements ontop of the Canvas element.
+ *
+ * @method setInteractionDelegate
+ * @param domElement {DOMElement} This new domElement which will receive mouse/touch events
+ */
+PIXI.Stage.prototype.setInteractionDelegate = function(domElement)
+{
+ this.interactionManager.setTargetDomElement( domElement );
+}
+
/*
* Updates the object transform for rendering
*
@@ -1924,7 +2066,7 @@ PIXI.Stage.prototype.updateTransform = function()
* Sets the background color for the stage
*
* @method setBackgroundColor
- * @param backgroundColor {number} the color of the background, easiest way to pass this in is in hex format
+ * @param backgroundColor {Number} the color of the background, easiest way to pass this in is in hex format
* like: 0xFFFFFF for white
*/
PIXI.Stage.prototype.setBackgroundColor = function(backgroundColor)
@@ -1955,7 +2097,7 @@ PIXI.Stage.prototype.getMousePosition = function()
/**
* This object is one that will allow you to specify custom rendering functions based on render type
*
- * @class CustomRenderable
+ * @class CustomRenderable
* @extends DisplayObject
* @constructor
*/
@@ -1963,6 +2105,7 @@ PIXI.CustomRenderable = function()
{
PIXI.DisplayObject.call( this );
+ this.renderable = true;
}
// constructor
@@ -2013,20 +2156,20 @@ PIXI.Strip = function(texture, width, height)
PIXI.DisplayObjectContainer.call( this );
this.texture = texture;
this.blendMode = PIXI.blendModes.NORMAL;
-
+
try
{
this.uvs = new Float32Array([0, 1,
1, 1,
1, 0, 0,1]);
-
+
this.verticies = new Float32Array([0, 0,
0,0,
0,0, 0,
0, 0]);
-
+
this.colors = new Float32Array([1, 1, 1, 1]);
-
+
this.indices = new Uint16Array([0, 1, 2, 3]);
}
catch(error)
@@ -2034,18 +2177,18 @@ PIXI.Strip = function(texture, width, height)
this.uvs = [0, 1,
1, 1,
1, 0, 0,1];
-
+
this.verticies = [0, 0,
0,0,
0,0, 0,
0, 0];
-
+
this.colors = [1, 1, 1, 1];
-
+
this.indices = [0, 1, 2, 3];
}
-
-
+
+
/*
this.uvs = new Float32Array()
this.verticies = new Float32Array()
@@ -2054,7 +2197,7 @@ PIXI.Strip = function(texture, width, height)
*/
this.width = width;
this.height = height;
-
+
// load the texture!
if(texture.baseTexture.hasLoaded)
{
@@ -2067,7 +2210,7 @@ PIXI.Strip = function(texture, width, height)
this.onTextureUpdateBind = this.onTextureUpdate.bind(this);
this.texture.addEventListener( 'update', this.onTextureUpdateBind );
}
-
+
this.renderable = true;
}
@@ -2079,8 +2222,8 @@ PIXI.Strip.prototype.setTexture = function(texture)
{
//TODO SET THE TEXTURES
//TODO VISIBILITY
-
- // stop current texture
+
+ // stop current texture
this.texture = texture;
this.width = texture.frame.width;
this.height = texture.frame.height;
@@ -2103,7 +2246,7 @@ PIXI.Rope = function(texture, points)
{
PIXI.Strip.call( this, texture );
this.points = points;
-
+
try
{
this.verticies = new Float32Array( points.length * 4);
@@ -2114,12 +2257,12 @@ PIXI.Rope = function(texture, points)
catch(error)
{
this.verticies = verticies
-
+
this.uvs = uvs
this.colors = colors
this.indices = indices
}
-
+
this.refresh();
}
@@ -2132,99 +2275,99 @@ PIXI.Rope.prototype.refresh = function()
{
var points = this.points;
if(points.length < 1)return;
-
+
var uvs = this.uvs
var indices = this.indices;
var colors = this.colors;
-
+
var lastPoint = points[0];
var nextPoint;
var perp = {x:0, y:0};
var point = points[0];
-
+
this.count-=0.2;
-
-
+
+
uvs[0] = 0
uvs[1] = 1
uvs[2] = 0
uvs[3] = 1
-
+
colors[0] = 1;
colors[1] = 1;
-
+
indices[0] = 0;
indices[1] = 1;
-
+
var total = points.length;
-
- for (var i = 1; i < total; i++)
+
+ for (var i = 1; i < total; i++)
{
-
+
var point = points[i];
var index = i * 4;
// time to do some smart drawing!
var amount = i/(total-1)
-
+
if(i%2)
{
uvs[index] = amount;
uvs[index+1] = 0;
-
+
uvs[index+2] = amount
uvs[index+3] = 1
-
+
}
else
{
uvs[index] = amount
uvs[index+1] = 0
-
+
uvs[index+2] = amount
uvs[index+3] = 1
}
-
+
index = i * 2;
colors[index] = 1;
colors[index+1] = 1;
-
+
index = i * 2;
indices[index] = index;
indices[index + 1] = index + 1;
-
+
lastPoint = point;
}
}
PIXI.Rope.prototype.updateTransform = function()
{
-
+
var points = this.points;
if(points.length < 1)return;
-
- var verticies = this.verticies
-
+
+ var verticies = this.verticies
+
var lastPoint = points[0];
var nextPoint;
var perp = {x:0, y:0};
var point = points[0];
-
+
this.count-=0.2;
-
- verticies[0] = point.x + perp.x
+
+ verticies[0] = point.x + perp.x
verticies[1] = point.y + perp.y //+ 200
- verticies[2] = point.x - perp.x
+ verticies[2] = point.x - perp.x
verticies[3] = point.y - perp.y//+200
// time to do some smart drawing!
-
+
var total = points.length;
-
- for (var i = 1; i < total; i++)
+
+ for (var i = 1; i < total; i++)
{
-
+
var point = points[i];
var index = i * 4;
-
+
if(i < points.length-1)
{
nextPoint = points[i+1];
@@ -2233,35 +2376,35 @@ PIXI.Rope.prototype.updateTransform = function()
{
nextPoint = point
}
-
+
perp.y = -(nextPoint.x - lastPoint.x);
perp.x = nextPoint.y - lastPoint.y;
-
+
var ratio = (1 - (i / (total-1))) * 10;
if(ratio > 1)ratio = 1;
-
+
var perpLength = Math.sqrt(perp.x * perp.x + perp.y * perp.y);
var num = this.texture.height/2//(20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio;
perp.x /= perpLength;
perp.y /= perpLength;
-
+
perp.x *= num;
perp.y *= num;
-
- verticies[index] = point.x + perp.x
+
+ verticies[index] = point.x + perp.x
verticies[index+1] = point.y + perp.y
- verticies[index+2] = point.x - perp.x
+ verticies[index+2] = point.x - perp.x
verticies[index+3] = point.y - perp.y
lastPoint = point;
}
-
+
PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
}
PIXI.Rope.prototype.setTexture = function(texture)
{
- // stop current texture
+ // stop current texture
this.texture = texture;
this.updateFrame = true;
}
@@ -2281,8 +2424,8 @@ PIXI.Rope.prototype.setTexture = function(texture)
* @extends DisplayObjectContainer
* @constructor
* @param texture {Texture} the texture of the tiling sprite
- * @param width {number} the width of the tiling sprite
- * @param height {number} the height of the tiling sprite
+ * @param width {Number} the width of the tiling sprite
+ * @param height {Number} the height of the tiling sprite
*/
PIXI.TilingSprite = function(texture, width, height)
{
@@ -2317,7 +2460,7 @@ PIXI.TilingSprite = function(texture, width, height)
*
* @property tileScale
* @type Point
- */
+ */
this.tileScale = new PIXI.Point(1,1);
/**
@@ -2325,11 +2468,11 @@ PIXI.TilingSprite = function(texture, width, height)
*
* @property tilePosition
* @type Point
- */
+ */
this.tilePosition = new PIXI.Point(0,0);
this.renderable = true;
-
+
this.blendMode = PIXI.blendModes.NORMAL
}
@@ -2347,8 +2490,8 @@ PIXI.TilingSprite.prototype.setTexture = function(texture)
{
//TODO SET THE TEXTURES
//TODO VISIBILITY
-
- // stop current texture
+
+ // stop current texture
this.texture = texture;
this.updateFrame = true;
}
@@ -2371,46 +2514,1042 @@ PIXI.TilingSprite.prototype.onTextureUpdate = function(event)
*/
-
-PIXI.FilterBlock = function(mask)
+/**
+ * This is the base class for creating a pixi.js filter. Currently only webGL supports filters.
+ * If you want to make a custom filter this should be your base class.
+ * @class AbstractFilter
+ * @constructor
+ * @param fragmentSrc
+ * @param unifroms
+ */
+PIXI.AbstractFilter = function(fragmentSrc, unifroms)
+{
+ /**
+ * An array of passes - some filters contain a few steps this array simply stores the steps in a liniear fashion.
+ * For example the blur filter has two passes blurX and blurY.
+ * @property passes
+ * @type Array an array of filter objects
+ * @private
+ */
+ this.passes = [this];
+
+
+ this.dirty = true;
+ this.padding = 0;
+
+ /**
+ @property uniforms
+ @private
+ */
+ this.uniforms = unifroms || {};
+
+ this.fragmentSrc = fragmentSrc || [];
+}
+
+
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+/**
+ *
+ * The BlurFilter applies a Gaussian blur to an object.
+ * The strength of the blur can be set for x- and y-axis separately (always relative to the stage).
+ *
+ * @class BlurFilter
+ * @contructor
+ */
+PIXI.BlurFilter = function()
+{
+
+ this.blurXFilter = new PIXI.BlurXFilter();
+ this.blurYFilter = new PIXI.BlurYFilter();
+
+ this.passes =[this.blurXFilter, this.blurYFilter];
+
+}
+
+/**
+ * Sets the strength of both the blurX and blurY properties simultaneously
+ *
+ * @property blur
+ * @type Number the strength of the blur
+ * @default 2
+ */
+Object.defineProperty(PIXI.BlurFilter.prototype, 'blur', {
+ get: function() {
+ return this.blurXFilter.blur;
+ },
+ set: function(value) {
+ this.blurXFilter.blur = this.blurYFilter.blur = value;
+ }
+});
+
+/**
+ * Sets the strength of the blurX property simultaneously
+ *
+ * @property blurX
+ * @type Number the strength of the blurX
+ * @default 2
+ */
+Object.defineProperty(PIXI.BlurFilter.prototype, 'blurX', {
+ get: function() {
+ return this.blurXFilter.blur;
+ },
+ set: function(value) {
+ this.blurXFilter.blur = value;
+ }
+});
+
+/**
+ * Sets the strength of the blurX property simultaneously
+ *
+ * @property blurY
+ * @type Number the strength of the blurY
+ * @default 2
+ */
+Object.defineProperty(PIXI.BlurFilter.prototype, 'blurY', {
+ get: function() {
+ return this.blurYFilter.blur;
+ },
+ set: function(value) {
+ this.blurYFilter.blur = value;
+ }
+});
+
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+
+PIXI.BlurXFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ blur: {type: 'f', value: 1/512},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float blur;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "vec4 sum = vec4(0.0);",
+
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x - 4.0*blur, vTextureCoord.y)) * 0.05;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x - 3.0*blur, vTextureCoord.y)) * 0.09;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x - 2.0*blur, vTextureCoord.y)) * 0.12;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x - blur, vTextureCoord.y)) * 0.15;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x + blur, vTextureCoord.y)) * 0.15;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x + 2.0*blur, vTextureCoord.y)) * 0.12;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x + 3.0*blur, vTextureCoord.y)) * 0.09;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x + 4.0*blur, vTextureCoord.y)) * 0.05;",
+
+ "gl_FragColor = sum;",
+
+ "}"
+ ];
+}
+
+PIXI.BlurXFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.BlurXFilter.prototype.constructor = PIXI.BlurXFilter;
+
+
+Object.defineProperty(PIXI.BlurXFilter.prototype, 'blur', {
+ get: function() {
+ return this.uniforms.blur.value / (1/7000);
+ },
+ set: function(value) {
+
+ this.dirty = true;
+ this.uniforms.blur.value = (1/7000) * value;
+ }
+});
+
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+
+PIXI.BlurYFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ blur: {type: 'f', value: 1/512},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float blur;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "vec4 sum = vec4(0.0);",
+
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 4.0*blur)) * 0.05;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 3.0*blur)) * 0.09;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 2.0*blur)) * 0.12;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - blur)) * 0.15;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + blur)) * 0.15;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 2.0*blur)) * 0.12;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 3.0*blur)) * 0.09;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 4.0*blur)) * 0.05;",
+
+ "gl_FragColor = sum;",
+
+ "}"
+ ];
+}
+
+PIXI.BlurYFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.BlurYFilter.prototype.constructor = PIXI.BlurYFilter;
+
+Object.defineProperty(PIXI.BlurYFilter.prototype, 'blur', {
+ get: function() {
+ return this.uniforms.blur.value / (1/7000);
+ },
+ set: function(value) {
+ //this.padding = value;
+ this.uniforms.blur.value = (1/7000) * value;
+ }
+});
+
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+/**
+ *
+ * The ColorMatrixFilter class lets you apply a 4x4 matrix transformation on the RGBA
+ * color and alpha values of every pixel on your displayObject to produce a result
+ * with a new set of RGBA color and alpha values. Its pretty powerful!
+ * @class ColorMatrixFilter
+ * @contructor
+ */
+PIXI.ColorMatrixFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ matrix: {type: 'mat4', value: [1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0,
+ 0,0,0,1]},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float invert;",
+ "uniform mat4 matrix;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;",
+ "gl_FragColor = gl_FragColor * vColor;",
+ "}"
+ ];
+
+}
+
+PIXI.ColorMatrixFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.ColorMatrixFilter.prototype.constructor = PIXI.ColorMatrixFilter;
+
+/**
+ * Sets the matrix of the color matrix filter
+ *
+ * @property matrix
+ * @type Array and array of 26 numbers
+ * @default [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
+ */
+Object.defineProperty(PIXI.ColorMatrixFilter.prototype, 'matrix', {
+ get: function() {
+ return this.uniforms.matrix.value;
+ },
+ set: function(value) {
+ this.uniforms.matrix.value = value;
+ }
+});
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+
+PIXI.CrossHatchFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ blur: {type: 'f', value: 1/512},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float blur;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+
+
+ " float lum = length(texture2D(uSampler, vTextureCoord.xy).rgb);",
+ " ",
+ " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);",
+ " ",
+ " if (lum < 1.00) {",
+ " if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) {",
+ " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);",
+ " }",
+ " }",
+ " ",
+ " if (lum < 0.75) {",
+ " if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) {",
+ " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);",
+ " }",
+ " }",
+ " ",
+ " if (lum < 0.50) {",
+ " if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) {",
+ " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);",
+ " }",
+ " }",
+ " ",
+ " if (lum < 0.3) {",
+ " if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) {",
+ " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);",
+ " }",
+ " }",
+ "}"
+ ];
+}
+
+PIXI.CrossHatchFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.CrossHatchFilter.prototype.constructor = PIXI.BlurYFilter;
+
+Object.defineProperty(PIXI.CrossHatchFilter.prototype, 'blur', {
+ get: function() {
+ return this.uniforms.blur.value / (1/7000);
+ },
+ set: function(value) {
+ //this.padding = value;
+ this.uniforms.blur.value = (1/7000) * value;
+ }
+});
+
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+/**
+ *
+ * The DisplacementFilter 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 DisplacementFilter
+ * @contructor
+ * @param texture {Texture} The texture used for the displacemtent map * must be power of 2 texture at the moment
+ */
+PIXI.DisplacementFilter = 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: 'f2', value:{x:30, y:30}},
+ offset: {type: 'f2', value:{x:0, y:0}},
+ mapDimensions: {type: 'f2', value:{x:1, y:5112}},
+ dimensions: {type: 'f4', value:[0,0,0,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 vec2 scale;",
+ "uniform vec2 offset;",
+ "uniform vec4 dimensions;",
+ "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);",
+ // "const vec2 textureDimensions = vec2(750.0, 750.0);",
+
+ "void main(void) {",
+ "vec2 mapCords = vTextureCoord.xy;",
+// "mapCords -= ;",
+ "mapCords += (dimensions.zw + offset)/ dimensions.xy ;",
+ "mapCords.y *= -1.0;",
+ "mapCords.y += 1.0;",
+ "vec2 matSample = texture2D(displacementMap, mapCords).xy;",
+ "matSample -= 0.5;",
+ "matSample *= scale;",
+ "matSample /= mapDimensions;",
+ "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x + matSample.x, vTextureCoord.y + matSample.y));",
+ "gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb, 1.0);",
+ "vec2 cord = vTextureCoord;",
+
+ //"gl_FragColor = texture2D(displacementMap, cord);",
+ "gl_FragColor = gl_FragColor * vColor;",
+
+ "}"
+ ];
+
+}
+
+PIXI.DisplacementFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.DisplacementFilter.prototype.constructor = PIXI.DisplacementFilter;
+
+PIXI.DisplacementFilter.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.DisplacementFilter.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.DisplacementFilter.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.DisplacementFilter.prototype, 'offset', {
+ get: function() {
+ return this.uniforms.offset.value;
+ },
+ set: function(value) {
+ this.uniforms.offset.value = value;
+ }
+});
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ * original filter: https://github.com/evanw/glfx.js/blob/master/src/filters/fun/dotscreen.js
+ */
+
+/**
+ *
+ * This filter applies a pixlate effect making display objects appear "blocky"
+ * @class PixelateFilter
+ * @contructor
+ */
+PIXI.DotScreenFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ scale: {type: 'f', value:1},
+ angle: {type: 'f', value:5},
+ dimensions: {type: 'f4', value:[0,0,0,0]}
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform vec4 dimensions;",
+ "uniform sampler2D uSampler;",
+
+ "uniform float angle;",
+ "uniform float scale;",
+
+ "float pattern() {",
+ "float s = sin(angle), c = cos(angle);",
+ "vec2 tex = vTextureCoord * dimensions.xy;",
+ "vec2 point = vec2(",
+ "c * tex.x - s * tex.y,",
+ "s * tex.x + c * tex.y",
+ ") * scale;",
+ "return (sin(point.x) * sin(point.y)) * 4.0;",
+ "}",
+
+ "void main() {",
+ "vec4 color = texture2D(uSampler, vTextureCoord);",
+ "float average = (color.r + color.g + color.b) / 3.0;",
+ "gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern()), color.a);",
+ "}",
+ ];
+}
+
+PIXI.DotScreenFilter.prototype = Object.create( PIXI.DotScreenFilter.prototype );
+PIXI.DotScreenFilter.prototype.constructor = PIXI.DotScreenFilter;
+
+/**
+ *
+ * This describes the the scale
+ * @property scale
+ * @type Number
+ */
+Object.defineProperty(PIXI.DotScreenFilter.prototype, 'scale', {
+ get: function() {
+ return this.uniforms.scale.value;
+ },
+ set: function(value) {
+ this.dirty = true;
+ this.uniforms.scale.value = value;
+ }
+});
+
+/**
+ *
+ * This radius describes angle
+ * @property angle
+ * @type Number
+ */
+Object.defineProperty(PIXI.DotScreenFilter.prototype, 'angle', {
+ get: function() {
+ return this.uniforms.angle.value;
+ },
+ set: function(value) {
+ this.dirty = true;
+ this.uniforms.angle.value = value;
+ }
+});
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+
+PIXI.FilterBlock = function()
{
- this.graphics = mask
this.visible = true;
this.renderable = true;
}
-
-
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
-
-PIXI.MaskFilter = function(graphics)
+/**
+ *
+ * This turns your displayObjects to black and white.
+ * @class GreyFilter
+ * @contructor
+ */
+PIXI.GreyFilter = function()
{
- // the graphics data that will be used for filtering
- this.graphics;
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ grey: {type: 'f', value: 1},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform sampler2D uSampler;",
+ "uniform float grey;",
+ "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), grey);",
+ "gl_FragColor = gl_FragColor * vColor;",
+ "}"
+ ];
}
+PIXI.GreyFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.GreyFilter.prototype.constructor = PIXI.GreyFilter;
+/**
+The strength of the grey. 1 will make the object black and white, 0 will make the object its normal color
+@property grey
+*/
+Object.defineProperty(PIXI.GreyFilter.prototype, 'grey', {
+ get: function() {
+ return this.uniforms.grey.value;
+ },
+ set: function(value) {
+ this.uniforms.grey.value = value;
+ }
+});
+
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+/**
+ *
+ * This inverts your displayObjects colors.
+ * @class InvertFilter
+ * @contructor
+ */
+PIXI.InvertFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ invert: {type: 'f', value: 1},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float invert;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "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;",
+ "}"
+ ];
+
+}
+
+PIXI.InvertFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.InvertFilter.prototype.constructor = PIXI.InvertFilter;
+
+/**
+The strength of the invert. 1 will fully invert the colors, 0 will make the object its normal color
+@property invert
+*/
+Object.defineProperty(PIXI.InvertFilter.prototype, 'invert', {
+ get: function() {
+ return this.uniforms.invert.value;
+ },
+ set: function(value) {
+ this.uniforms.invert.value = value;
+ }
+});
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+/**
+ *
+ * This filter applies a pixlate effect making display objects appear "blocky"
+ * @class PixelateFilter
+ * @contructor
+ */
+PIXI.PixelateFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ invert: {type: 'f', value: 0},
+ dimensions: {type: 'f4', value:new Float32Array([10000, 100, 10, 10])},
+ pixelSize: {type: 'f2', value:{x:10, y:10}},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform vec2 testDim;",
+ "uniform vec4 dimensions;",
+ "uniform vec2 pixelSize;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "vec2 coord = vTextureCoord;",
+
+ "vec2 size = dimensions.xy/pixelSize;",
+
+ "vec2 color = floor( ( vTextureCoord * size ) ) / size + pixelSize/dimensions.xy * 0.5;",
+ "gl_FragColor = texture2D(uSampler, color);",
+ "}"
+ ];
+
+
+}
+
+PIXI.PixelateFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.PixelateFilter.prototype.constructor = PIXI.PixelateFilter;
+
+/**
+ *
+ * This a point that describes the size of the blocs. x is the width of the block and y is the the height
+ * @property size
+ * @type Point
+ */
+Object.defineProperty(PIXI.PixelateFilter.prototype, 'size', {
+ get: function() {
+ return this.uniforms.pixelSize.value;
+ },
+ set: function(value) {
+ this.dirty = true;
+ this.uniforms.pixelSize.value = value;
+ }
+});
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+
+PIXI.RGBSplitFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ red: {type: 'f2', value: {x:20, y:20}},
+ green: {type: 'f2', value: {x:-20, y:20}},
+ blue: {type: 'f2', value: {x:20, y:-20}},
+ dimensions: {type: 'f4', value:[0,0,0,0]}
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform vec2 red;",
+ "uniform vec2 green;",
+ "uniform vec2 blue;",
+ "uniform vec4 dimensions;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "gl_FragColor.r = texture2D(uSampler, vTextureCoord + red/dimensions.xy).r;",
+ "gl_FragColor.g = texture2D(uSampler, vTextureCoord + green/dimensions.xy).g;",
+ "gl_FragColor.b = texture2D(uSampler, vTextureCoord + blue/dimensions.xy).b;",
+ "gl_FragColor.a = texture2D(uSampler, vTextureCoord).a;",
+ "}"
+ ];
+}
+
+PIXI.RGBSplitFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.RGBSplitFilter.prototype.constructor = PIXI.RGBSplitFilter;
+
+Object.defineProperty(PIXI.RGBSplitFilter.prototype, 'angle', {
+ get: function() {
+ return this.uniforms.blur.value / (1/7000);
+ },
+ set: function(value) {
+ //this.padding = value;
+ this.uniforms.blur.value = (1/7000) * value;
+ }
+});
+
+/**
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
/**
- * The Graphics class contains a set of methods that you can use to create primitive shapes and lines.
+ *
+ * This applies a sepia effect to your displayObjects.
+ * @class SepiaFilter
+ * @contructor
+ */
+PIXI.SepiaFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ sepia: {type: 'f', value: 1},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float sepia;",
+ "uniform sampler2D uSampler;",
+
+ "const mat3 sepiaMatrix = mat3(0.3588, 0.7044, 0.1368, 0.2990, 0.5870, 0.1140, 0.2392, 0.4696, 0.0912);",
+ "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;",
+ "}"
+ ];
+
+}
+
+PIXI.SepiaFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.SepiaFilter.prototype.constructor = PIXI.SepiaFilter;
+
+/**
+The strength of the sepia. 1 will apply the full sepia effect, 0 will make the object its normal color
+@property sepia
+*/
+Object.defineProperty(PIXI.SepiaFilter.prototype, 'sepia', {
+ get: function() {
+ return this.uniforms.sepia.value;
+ },
+ set: function(value) {
+ this.uniforms.sepia.value = value;
+ }
+});
+
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+
+PIXI.SmartBlurFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ blur: {type: 'f', value: 1/512},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "uniform sampler2D uSampler;",
+ // "uniform vec2 delta;",
+ "const vec2 delta = vec2(1.0/10.0, 0.0);",
+ // "uniform float darkness;",
+
+ "float random(vec3 scale, float seed) {",
+ "return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);",
+ "}",
+
+
+ "void main(void) {",
+
+ "vec4 color = vec4(0.0);",
+ "float total = 0.0;",
+
+ "float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);",
+
+ "for (float t = -30.0; t <= 30.0; t++) {",
+ "float percent = (t + offset - 0.5) / 30.0;",
+ "float weight = 1.0 - abs(percent);",
+ "vec4 sample = texture2D(uSampler, vTextureCoord + delta * percent);",
+ "sample.rgb *= sample.a;",
+ "color += sample * weight;",
+ "total += weight;",
+ "}",
+
+ "gl_FragColor = color / total;",
+ "gl_FragColor.rgb /= gl_FragColor.a + 0.00001;",
+ // "gl_FragColor.rgb *= darkness;",
+ "}"
+ ];
+}
+
+PIXI.SmartBlurFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.SmartBlurFilter.prototype.constructor = PIXI.SmartBlurFilter;
+
+Object.defineProperty(PIXI.SmartBlurFilter.prototype, 'blur', {
+ get: function() {
+ return this.uniforms.blur.value;
+ },
+ set: function(value) {
+ this.uniforms.blur.value = value;
+ }
+});
+
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+/**
+ *
+ * This filter applies a pixlate effect making display objects appear "blocky"
+ * @class PixelateFilter
+ * @contructor
+ */
+PIXI.TwistFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ radius: {type: 'f', value:0.5},
+ angle: {type: 'f', value:5},
+ offset: {type: 'f2', value:{x:0.5, y:0.5}},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform vec4 dimensions;",
+ "uniform sampler2D uSampler;",
+
+ "uniform float radius;",
+ "uniform float angle;",
+ "uniform vec2 offset;",
+
+ "void main(void) {",
+ "vec2 coord = vTextureCoord - offset;",
+ "float distance = length(coord);",
+
+ "if (distance < radius){",
+
+ "float ratio = (radius - distance) / radius;",
+ "float angleMod = ratio * ratio * angle;",
+ "float s = sin(angleMod);",
+ "float c = cos(angleMod);",
+ "coord = vec2(coord.x * c - coord.y * s, coord.x * s + coord.y * c);",
+
+ "}",
+
+ "gl_FragColor = texture2D(uSampler, coord+offset);",
+ "}"
+ ];
+}
+
+PIXI.TwistFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.TwistFilter.prototype.constructor = PIXI.TwistFilter;
+
+/**
+ *
+ * This point describes the the offset of the twist
+ * @property size
+ * @type Point
+ */
+Object.defineProperty(PIXI.TwistFilter.prototype, 'offset', {
+ get: function() {
+ return this.uniforms.offset.value;
+ },
+ set: function(value) {
+ this.dirty = true;
+ this.uniforms.offset.value = value;
+ }
+});
+
+/**
+ *
+ * This radius describes size of the twist
+ * @property size
+ * @type Number
+ */
+Object.defineProperty(PIXI.TwistFilter.prototype, 'radius', {
+ get: function() {
+ return this.uniforms.radius.value;
+ },
+ set: function(value) {
+ this.dirty = true;
+ this.uniforms.radius.value = value;
+ }
+});
+
+/**
+ *
+ * This radius describes angle of the twist
+ * @property angle
+ * @type Number
+ */
+Object.defineProperty(PIXI.TwistFilter.prototype, 'angle', {
+ get: function() {
+ return this.uniforms.angle.value;
+ },
+ set: function(value) {
+ this.dirty = true;
+ this.uniforms.angle.value = value;
+ }
+});
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+/**
+ * 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
*
- * @class Graphics
+ * @class Graphics
* @extends DisplayObjectContainer
* @constructor
*/
PIXI.Graphics = function()
{
PIXI.DisplayObjectContainer.call( this );
-
+
this.renderable = true;
/**
@@ -2464,21 +3603,21 @@ 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.
*
* @method lineStyle
- * @param lineWidth {number} width of the line to draw, will update the object's stored style
- * @param color {number} color of the line to draw, will update the object's stored style
- * @param alpha {number} alpha of the line to draw, will update the object's stored style
+ * @param lineWidth {Number} width of the line to draw, will update the object's stored style
+ * @param color {Number} color of the line to draw, will update the object's stored style
+ * @param alpha {Number} alpha of the line to draw, will update the object's stored style
*/
PIXI.Graphics.prototype.lineStyle = function(lineWidth, color, alpha)
{
if(this.currentPath.points.length == 0)this.graphicsData.pop();
-
+
this.lineWidth = lineWidth || 0;
this.lineColor = color || 0;
this.lineAlpha = (alpha == undefined) ? 1 : alpha;
-
- this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
+
+ this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY};
-
+
this.graphicsData.push(this.currentPath);
}
@@ -2486,18 +3625,18 @@ 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 coord to move to
+ * @param y {Number} the Y coord to move to
*/
PIXI.Graphics.prototype.moveTo = function(x, y)
{
if(this.currentPath.points.length == 0)this.graphicsData.pop();
-
- this.currentPath = this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
+
+ this.currentPath = this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling, points:[], type:PIXI.Graphics.POLY};
-
+
this.currentPath.points.push(x, y);
-
+
this.graphicsData.push(this.currentPath);
}
@@ -2506,8 +3645,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 coord to draw to
+ * @param y {Number} the Y coord to draw to
*/
PIXI.Graphics.prototype.lineTo = function(x, y)
{
@@ -2521,7 +3660,7 @@ PIXI.Graphics.prototype.lineTo = function(x, y)
*
* @method beginFill
* @param color {uint} the color of the fill
- * @param alpha {number} the alpha
+ * @param alpha {Number} the alpha
*/
PIXI.Graphics.prototype.beginFill = function(color, alpha)
{
@@ -2545,19 +3684,19 @@ PIXI.Graphics.prototype.endFill = function()
/**
* @method drawRect
*
- * @param x {number} The X coord of the top-left of the rectangle
- * @param y {number} The Y coord of the top-left of the rectangle
- * @param width {number} The width of the rectangle
- * @param height {number} The height of the rectangle
+ * @param x {Number} The X coord of the top-left of the rectangle
+ * @param y {Number} The Y coord of the top-left of the rectangle
+ * @param width {Number} The width of the rectangle
+ * @param height {Number} The height of the rectangle
*/
PIXI.Graphics.prototype.drawRect = function( x, y, width, height )
{
if(this.currentPath.points.length == 0)this.graphicsData.pop();
-
- this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
- fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling,
+
+ this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
+ fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling,
points:[x, y, width, height], type:PIXI.Graphics.RECT};
-
+
this.graphicsData.push(this.currentPath);
this.dirty = true;
}
@@ -2566,18 +3705,18 @@ 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 radius {number} The radius of the circle
+ * @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 radius {Number} The radius of the circle
*/
PIXI.Graphics.prototype.drawCircle = function( x, y, radius)
{
if(this.currentPath.points.length == 0)this.graphicsData.pop();
-
- this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
- fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling,
+
+ this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
+ fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling,
points:[x, y, radius, radius], type:PIXI.Graphics.CIRC};
-
+
this.graphicsData.push(this.currentPath);
this.dirty = true;
}
@@ -2586,19 +3725,19 @@ PIXI.Graphics.prototype.drawCircle = function( x, y, radius)
* Draws an elipse.
*
* @method drawElipse
- * @param x {number}
- * @param y {number}
- * @param width {number}
- * @param height {number}
+ * @param x {Number}
+ * @param y {Number}
+ * @param width {Number}
+ * @param height {Number}
*/
PIXI.Graphics.prototype.drawElipse = function( x, y, width, height)
{
if(this.currentPath.points.length == 0)this.graphicsData.pop();
-
- this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
- fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling,
+
+ this.currentPath = {lineWidth:this.lineWidth, lineColor:this.lineColor, lineAlpha:this.lineAlpha,
+ fillColor:this.fillColor, fillAlpha:this.fillAlpha, fill:this.filling,
points:[x, y, width, height], type:PIXI.Graphics.ELIP};
-
+
this.graphicsData.push(this.currentPath);
this.dirty = true;
}
@@ -2612,10 +3751,85 @@ PIXI.Graphics.prototype.clear = function()
{
this.lineWidth = 0;
this.filling = false;
-
+
this.dirty = true;
this.clearDirty = true;
this.graphicsData = [];
+
+ this.bounds = null//new PIXI.Rectangle();
+}
+
+
+PIXI.Graphics.prototype.updateFilterBounds = function()
+{
+ if(!this.bounds)
+ {
+ 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;
+ };
+ }
+
+ };
+
+ this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY);
+
+ }
+
+// console.log(this.bounds);
}
// SOME TYPES:
@@ -2636,7 +3850,7 @@ PIXI.Graphics.ELIP = 3;
*/
PIXI.CanvasGraphics = function()
{
-
+
}
@@ -2652,33 +3866,33 @@ PIXI.CanvasGraphics = function()
PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
{
var worldAlpha = graphics.worldAlpha;
-
- for (var i=0; i < graphics.graphicsData.length; i++)
+
+ for (var i=0; i < graphics.graphicsData.length; i++)
{
var data = graphics.graphicsData[i];
var points = data.points;
-
+
context.strokeStyle = color = '#' + ('00000' + ( data.lineColor | 0).toString(16)).substr(-6);
context.lineWidth = data.lineWidth;
-
+
if(data.type == PIXI.Graphics.POLY)
{
context.beginPath();
-
+
context.moveTo(points[0], points[1]);
-
+
for (var j=1; j < points.length/2; j++)
{
context.lineTo(points[j * 2], points[j * 2 + 1]);
- }
-
+ }
+
// if the first and last point are the same close the path - much neater :)
if(points[0] == points[points.length-2] && points[1] == points[points.length-1])
{
context.closePath();
}
-
+
if(data.fill)
{
context.globalAlpha = data.fillAlpha * worldAlpha;
@@ -2693,21 +3907,20 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
}
else if(data.type == PIXI.Graphics.RECT)
{
-
- // TODO - need to be Undefined!
- if(data.fillColor)
+
+ if(data.fillColor || data.fillColor === 0)
{
context.globalAlpha = data.fillAlpha * worldAlpha;
context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6);
context.fillRect(points[0], points[1], points[2], points[3]);
-
+
}
if(data.lineWidth)
{
context.globalAlpha = data.lineAlpha * worldAlpha;
context.strokeRect(points[0], points[1], points[2], points[3]);
}
-
+
}
else if(data.type == PIXI.Graphics.CIRC)
{
@@ -2715,7 +3928,7 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
context.beginPath();
context.arc(points[0], points[1], points[2],0,2*Math.PI);
context.closePath();
-
+
if(data.fill)
{
context.globalAlpha = data.fillAlpha * worldAlpha;
@@ -2730,19 +3943,19 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
}
else if(data.type == PIXI.Graphics.ELIP)
{
-
+
// elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
-
+
var elipseData = data.points;
-
+
var w = elipseData[2] * 2;
var h = elipseData[3] * 2;
-
+
var x = elipseData[0] - w/2;
var y = elipseData[1] - h/2;
-
+
context.beginPath();
-
+
var kappa = .5522848,
ox = (w / 2) * kappa, // control point offset horizontal
oy = (h / 2) * kappa, // control point offset vertical
@@ -2750,15 +3963,15 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
ye = y + h, // y-end
xm = x + w / 2, // x-middle
ym = y + h / 2; // y-middle
-
+
context.moveTo(x, ym);
context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
-
+
context.closePath();
-
+
if(data.fill)
{
context.globalAlpha = data.fillAlpha * worldAlpha;
@@ -2771,7 +3984,7 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
context.stroke();
}
}
-
+
};
}
@@ -2787,35 +4000,37 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
{
var worldAlpha = graphics.worldAlpha;
-
+
var len = graphics.graphicsData.length;
+ if(len === 0)return;
+
if(len > 1)
{
len = 1;
console.log("Pixi.js warning: masks in canvas can only mask using the first path in the graphics object")
}
-
- for (var i=0; i < 1; i++)
+
+ for (var i=0; i < 1; i++)
{
var data = graphics.graphicsData[i];
var points = data.points;
-
+
if(data.type == PIXI.Graphics.POLY)
{
context.beginPath();
context.moveTo(points[0], points[1]);
-
+
for (var j=1; j < points.length/2; j++)
{
context.lineTo(points[j * 2], points[j * 2 + 1]);
- }
-
+ }
+
// if the first and last point are the same close the path - much neater :)
if(points[0] == points[points.length-2] && points[1] == points[points.length-1])
{
context.closePath();
}
-
+
}
else if(data.type == PIXI.Graphics.RECT)
{
@@ -2832,18 +4047,18 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
}
else if(data.type == PIXI.Graphics.ELIP)
{
-
+
// elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
var elipseData = data.points;
-
+
var w = elipseData[2] * 2;
var h = elipseData[3] * 2;
-
+
var x = elipseData[0] - w/2;
var y = elipseData[1] - h/2;
-
+
context.beginPath();
-
+
var kappa = .5522848,
ox = (w / 2) * kappa, // control point offset horizontal
oy = (h / 2) * kappa, // control point offset vertical
@@ -2851,7 +4066,7 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
ye = y + h, // y-end
xm = x + w / 2, // x-middle
ym = y + h / 2; // y-middle
-
+
context.moveTo(x, ym);
context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
@@ -2859,8 +4074,8 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
context.closePath();
}
-
-
+
+
};
}
@@ -2875,8 +4090,8 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
*
* @class CanvasRenderer
* @constructor
- * @param width=0 {number} the width of the canvas view
- * @param height=0 {number} the height of the canvas view
+ * @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
*/
@@ -2980,8 +4195,8 @@ PIXI.CanvasRenderer.prototype.render = function(stage)
* resizes the canvas view to the specified width and height
*
* @method resize
- * @param width {number} the new width of the canvas view
- * @param height {number} the new height of the canvas view
+ * @param width {Number} the new width of the canvas view
+ * @param height {Number} the new height of the canvas view
*/
PIXI.CanvasRenderer.prototype.resize = function(width, height)
{
@@ -3029,9 +4244,10 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject)
if(displayObject instanceof PIXI.Sprite)
{
+
var frame = displayObject.texture.frame;
- if(frame)
+ if(frame && frame.width && frame.height)
{
context.globalAlpha = displayObject.worldAlpha;
@@ -3060,6 +4276,7 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(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)
@@ -3069,27 +4286,36 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject)
}
else if(displayObject instanceof PIXI.FilterBlock)
{
- if(displayObject.open)
- {
- context.save();
-
- var cacheAlpha = displayObject.mask.alpha;
- var maskTransform = displayObject.mask.worldTransform;
-
- context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5])
-
- displayObject.mask.worldAlpha = 0.5;
-
- context.worldAlpha = 0;
-
- PIXI.CanvasGraphics.renderGraphicsMask(displayObject.mask, context);
- context.clip();
-
- displayObject.mask.worldAlpha = cacheAlpha;
+ 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();
+ }
}
else
{
- context.restore();
+ // only masks supported right now!
}
}
// count++
@@ -3234,6 +4460,250 @@ PIXI.CanvasRenderer.prototype.renderStrip = function(strip)
}
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+PIXI.PixiShader = function()
+{
+ // the webGL program..
+ this.program;
+
+ this.fragmentSrc = [
+ "precision lowp float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;",
+ "}"
+ ];
+
+}
+
+PIXI.PixiShader.prototype.init = function()
+{
+ var program = PIXI.compileProgram(this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc)
+
+ var gl = PIXI.gl;
+
+ gl.useProgram(program);
+
+ // get and store the uniforms for the shader
+ this.uSampler = gl.getUniformLocation(program, "uSampler");
+ this.projectionVector = gl.getUniformLocation(program, "projectionVector");
+ this.offsetVector = gl.getUniformLocation(program, "offsetVector");
+ //this.dimensions = gl.getUniformLocation(this.program, "dimensions");
+
+ // get and store the attributes
+ this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
+ this.colorAttribute = gl.getAttribLocation(program, "aColor");
+ this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord");
+
+ // add those custom shaders!
+ for (var key in this.uniforms)
+ {
+
+ // get the uniform locations..
+ // program[key] =
+ this.uniforms[key].uniformLocation = gl.getUniformLocation(program, key);
+
+
+ }
+
+ this.program = program;
+}
+
+PIXI.PixiShader.prototype.syncUniforms = function()
+{
+ var gl = PIXI.gl;
+
+ for (var key in this.uniforms)
+ {
+ //var
+ var type = this.uniforms[key].type;
+
+ // need to grow this!
+ if(type == "f")
+ {
+ gl.uniform1f(this.uniforms[key].uniformLocation, this.uniforms[key].value);
+ }
+ if(type == "f2")
+ {
+ // console.log(this.program[key])
+ gl.uniform2f(this.uniforms[key].uniformLocation, this.uniforms[key].value.x, this.uniforms[key].value.y);
+ }
+ else if(type == "f4")
+ {
+ // console.log(this.uniforms[key].value)
+ gl.uniform4fv(this.uniforms[key].uniformLocation, this.uniforms[key].value);
+ }
+ else if(type == "mat4")
+ {
+ gl.uniformMatrix4fv(this.uniforms[key].uniformLocation, false, this.uniforms[key].value);
+ }
+ else if(type == "sampler2D")
+ {
+ // first texture...
+ var texture = this.uniforms[key].value;
+
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, texture.baseTexture._glTexture);
+
+ gl.uniform1i(this.uniforms[key].uniformLocation, 1);
+
+ // activate texture..
+ // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
+ // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
+ }
+ }
+
+}
+
+PIXI.PixiShader.defaultVertexSrc = [
+ "attribute vec2 aVertexPosition;",
+ "attribute vec2 aTextureCoord;",
+ "attribute float aColor;",
+
+ "uniform vec2 projectionVector;",
+ "uniform vec2 offsetVector;",
+ "varying vec2 vTextureCoord;",
+
+ "varying float vColor;",
+
+ "const vec2 center = vec2(-1.0, 1.0);",
+ "void main(void) {",
+ "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);",
+ "vTextureCoord = aTextureCoord;",
+ "vColor = aColor;",
+ "}"
+];
+
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+PIXI.PrimitiveShader = function()
+{
+ // the webGL program..
+ this.program;
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec4 vColor;",
+ "void main(void) {",
+ "gl_FragColor = vColor;",
+ "}"
+ ];
+
+ this.vertexSrc = [
+ "attribute vec2 aVertexPosition;",
+ "attribute vec4 aColor;",
+ "uniform mat3 translationMatrix;",
+ "uniform vec2 projectionVector;",
+ "uniform vec2 offsetVector;",
+ "uniform float alpha;",
+ "varying vec4 vColor;",
+ "void main(void) {",
+ "vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);",
+ "v -= offsetVector.xyx;",
+ "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
+ "vColor = aColor * alpha;",
+ "}"
+ ];
+
+}
+
+PIXI.PrimitiveShader.prototype.init = function()
+{
+ var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc);
+
+ var gl = PIXI.gl;
+
+ gl.useProgram(program);
+
+ // get and store the uniforms for the shader
+ this.projectionVector = gl.getUniformLocation(program, "projectionVector");
+ this.offsetVector = gl.getUniformLocation(program, "offsetVector");
+
+ // get and store the attributes
+ this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
+ this.colorAttribute = gl.getAttribLocation(program, "aColor");
+
+ this.translationMatrix = gl.getUniformLocation(program, "translationMatrix");
+ this.alpha = gl.getUniformLocation(program, "alpha");
+
+ this.program = program;
+}
+
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+PIXI.StripShader = function()
+{
+ // the webGL program..
+ this.program;
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float alpha;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));",
+ "gl_FragColor = gl_FragColor * alpha;",
+ "}"
+ ];
+
+ this.vertexSrc = [
+ "attribute vec2 aVertexPosition;",
+ "attribute vec2 aTextureCoord;",
+ "attribute float aColor;",
+ "uniform mat3 translationMatrix;",
+ "uniform vec2 projectionVector;",
+ "varying vec2 vTextureCoord;",
+ "varying vec2 offsetVector;",
+ "varying float vColor;",
+ "void main(void) {",
+ "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
+ "v -= offsetVector.xyx;",
+ "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);",
+ "vTextureCoord = aTextureCoord;",
+ "vColor = aColor;",
+ "}"
+ ];
+}
+
+PIXI.StripShader.prototype.init = function()
+{
+ var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc)
+
+ var gl = PIXI.gl;
+
+ gl.useProgram(program);
+
+ // get and store the uniforms for the shader
+ this.uSampler = gl.getUniformLocation(program, "uSampler");
+ this.projectionVector = gl.getUniformLocation(program, "projectionVector");
+ this.offsetVector = gl.getUniformLocation(program, "offsetVector");
+ this.colorAttribute = gl.getAttribLocation(program, "aColor");
+ //this.dimensions = gl.getUniformLocation(this.program, "dimensions");
+
+ // get and store the attributes
+ this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
+ this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord");
+
+ this.translationMatrix = gl.getUniformLocation(program, "translationMatrix");
+ this.alpha = gl.getUniformLocation(program, "alpha");
+
+ this.program = program;
+}
+
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
@@ -3651,7 +5121,10 @@ PIXI.WebGLBatch.prototype.update = function()
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)
@@ -3679,17 +5152,17 @@ PIXI.WebGLBatch.prototype.update = function()
tx = worldTransform[2];
ty = worldTransform[5];
- this.verticies[index + 0 ] = a * w1 + c * h1 + tx;
- this.verticies[index + 1 ] = d * h1 + b * w1 + ty;
+ verticies[index + 0 ] = a * w1 + c * h1 + tx;
+ verticies[index + 1 ] = d * h1 + b * w1 + ty;
- this.verticies[index + 2 ] = a * w0 + c * h1 + tx;
- this.verticies[index + 3 ] = d * h1 + b * w0 + ty;
+ verticies[index + 2 ] = a * w0 + c * h1 + tx;
+ verticies[index + 3 ] = d * h1 + b * w0 + ty;
- this.verticies[index + 4 ] = a * w0 + c * h0 + tx;
- this.verticies[index + 5 ] = d * h0 + b * w0 + ty;
+ verticies[index + 4 ] = a * w0 + c * h0 + tx;
+ verticies[index + 5 ] = d * h0 + b * w0 + ty;
- this.verticies[index + 6] = a * w1 + c * h0 + tx;
- this.verticies[index + 7] = d * h0 + b * w1 + ty;
+ verticies[index + 6] = a * w1 + c * h0 + tx;
+ verticies[index + 7] = d * h0 + b * w1 + ty;
if(displayObject.updateFrame || displayObject.texture.updateFrame)
{
@@ -3701,17 +5174,17 @@ PIXI.WebGLBatch.prototype.update = function()
var tw = texture.baseTexture.width;
var th = texture.baseTexture.height;
- this.uvs[index + 0] = frame.x / tw;
- this.uvs[index +1] = frame.y / th;
+ uvs[index + 0] = frame.x / tw;
+ uvs[index +1] = frame.y / th;
- this.uvs[index +2] = (frame.x + frame.width) / tw;
- this.uvs[index +3] = frame.y / th;
+ uvs[index +2] = (frame.x + frame.width) / tw;
+ uvs[index +3] = frame.y / th;
- this.uvs[index +4] = (frame.x + frame.width) / tw;
- this.uvs[index +5] = (frame.y + frame.height) / th;
+ uvs[index +4] = (frame.x + frame.width) / tw;
+ uvs[index +5] = (frame.y + frame.height) / th;
- this.uvs[index +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
+ uvs[index +6] = frame.x / tw;
+ uvs[index +7] = (frame.y + frame.height) / th;
displayObject.updateFrame = false;
}
@@ -3722,7 +5195,7 @@ PIXI.WebGLBatch.prototype.update = function()
displayObject.cacheAlpha = displayObject.worldAlpha;
var colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
+ colors[colorIndex] = colors[colorIndex + 1] = colors[colorIndex + 2] = colors[colorIndex + 3] = displayObject.worldAlpha;
this.dirtyColors = true;
}
}
@@ -3730,17 +5203,7 @@ PIXI.WebGLBatch.prototype.update = function()
{
index = indexRun * 8;
- this.verticies[index + 0 ] = 0;
- this.verticies[index + 1 ] = 0;
-
- this.verticies[index + 2 ] = 0;
- this.verticies[index + 3 ] = 0;
-
- this.verticies[index + 4 ] = 0;
- this.verticies[index + 5 ] = 0;
-
- this.verticies[index + 6] = 0;
- this.verticies[index + 7] = 0;
+ 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++;
@@ -3772,15 +5235,18 @@ PIXI.WebGLBatch.prototype.render = function(start, end)
//TODO optimize this!
- var shaderProgram = PIXI.shaderProgram;
- gl.useProgram(shaderProgram);
+ 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.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
+ 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)
@@ -3789,7 +5255,7 @@ PIXI.WebGLBatch.prototype.render = function(start, end)
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs);
}
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribPointer(shaderProgram.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture);
@@ -3804,7 +5270,6 @@ PIXI.WebGLBatch.prototype.render = function(start, end)
}
gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
// dont need to upload!
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
@@ -3818,6 +5283,525 @@ PIXI.WebGLBatch.prototype.render = function(start, end)
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
+
+PIXI.WebGLFilterManager = function(transparent)
+{
+ this.transparent = transparent;
+
+ this.filterStack = [];
+ this.texturePool = [];
+
+ this.offsetX = 0;
+ this.offsetY = 0;
+
+ this.initShaderBuffers();
+}
+
+// API
+
+PIXI.WebGLFilterManager.prototype.begin = function(projection, buffer)
+{
+ this.width = projection.x * 2;
+ this.height = -projection.y * 2;
+ this.buffer = buffer;
+}
+
+PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
+{
+ var gl = PIXI.gl;
+
+ // filter program
+ // OPTIMISATION - the first filter is free if its a simple color change?
+ this.filterStack.push(filterBlock);
+
+ var filter = filterBlock.filterPasses[0];
+
+
+
+ this.offsetX += filterBlock.target.filterArea.x;
+ this.offsetY += filterBlock.target.filterArea.y;
+
+
+
+
+
+ var texture = this.texturePool.pop();
+ if(!texture)texture = new PIXI.FilterTexture(this.width, this.height);
+
+ gl.bindTexture(gl.TEXTURE_2D, texture.texture);
+
+ this.getBounds(filterBlock.target);
+
+ // addpadding?
+ //displayObject.filterArea.x
+
+ var filterArea = filterBlock.target.filterArea;
+
+ var padidng = filter.padding;
+ filterArea.x -= padidng;
+ filterArea.y -= padidng;
+ filterArea.width += padidng * 2;
+ filterArea.height += padidng * 2;
+
+ // cap filter to screen size..
+ if(filterArea.x < 0)filterArea.x = 0;
+ if(filterArea.width > this.width)filterArea.width = this.width;
+ if(filterArea.y < 0)filterArea.y = 0;
+ if(filterArea.height > this.height)filterArea.height = this.height;
+
+
+ //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer);
+
+ // console.log(filterArea)
+ // set view port
+ gl.viewport(0, 0, filterArea.width, filterArea.height);
+
+ PIXI.projection.x = filterArea.width/2;
+ PIXI.projection.y = -filterArea.height/2;
+
+ PIXI.offset.x = -filterArea.x;
+ PIXI.offset.y = -filterArea.y;
+
+ //console.log(PIXI.defaultShader.projectionVector)
+ // update projection
+ gl.uniform2f(PIXI.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2);
+ gl.uniform2f(PIXI.defaultShader.offsetVector, -filterArea.x, -filterArea.y);
+ //PIXI.primitiveProgram
+
+ gl.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")
+}
+
+
+PIXI.WebGLFilterManager.prototype.popFilter = function()
+{
+
+ var gl = PIXI.gl;
+
+ var filterBlock = this.filterStack.pop();
+
+
+
+ var filterArea = filterBlock.target.filterArea;
+
+ var texture = filterBlock._glFilterTexture;
+
+ if(filterBlock.filterPasses.length > 1)
+ {
+ gl.viewport(0, 0, filterArea.width, filterArea.height);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+
+ this.vertexArray[0] = 0;
+ this.vertexArray[1] = filterArea.height;
+
+ this.vertexArray[2] = filterArea.width;
+ this.vertexArray[3] = filterArea.height;
+
+ this.vertexArray[4] = 0;
+ this.vertexArray[5] = 0;
+
+ this.vertexArray[6] = filterArea.width;
+ this.vertexArray[7] = 0;
+
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray);
+
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
+ // nnow set the uvs..
+ this.uvArray[2] = filterArea.width/this.width;
+ this.uvArray[5] = filterArea.height/this.height;
+ this.uvArray[6] = filterArea.width/this.width;
+ this.uvArray[7] = filterArea.height/this.height;
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray);
+
+ var inputTexture = texture;
+ var outputTexture = this.texturePool.pop();
+ if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.width, this.height);
+
+ // need to clear this FBO as it may have some left over elements from a prvious filter.
+ gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer );
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ gl.disable(gl.BLEND);
+
+ for (var i = 0; i < filterBlock.filterPasses.length-1; i++)
+ {
+ var filterPass = filterBlock.filterPasses[i];
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer );
+
+ // set texture
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture);
+
+ // draw texture..
+ //filterPass.applyFilterPass(filterArea.width, filterArea.height);
+ this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height);
+
+ // swap the textures..
+ var temp = inputTexture;
+ inputTexture = outputTexture;
+ outputTexture = temp;
+
+ };
+
+ gl.enable(gl.BLEND);
+
+ texture = inputTexture;
+ this.texturePool.push(outputTexture);
+ }
+
+ var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1];
+
+ this.offsetX -= filterArea.x;
+ this.offsetY -= filterArea.y;
+
+
+ var sizeX = this.width;
+ var sizeY = this.height;
+
+ var offsetX = 0;
+ var offsetY = 0;
+
+ var buffer = this.buffer;
+
+ // time to render the filters texture to the previous scene
+ if(this.filterStack.length === 0)
+ {
+ gl.colorMask(true, true, true, this.transparent);
+ }
+ else
+ {
+ var currentFilter = this.filterStack[this.filterStack.length-1];
+ var filterArea = currentFilter.target.filterArea;
+
+ sizeX = filterArea.width;
+ sizeY = filterArea.height;
+
+ offsetX = filterArea.x;
+ offsetY = filterArea.y;
+
+ buffer = currentFilter._glFilterTexture.frameBuffer;
+ }
+
+
+
+ // TODO need toremove thease global elements..
+ PIXI.projection.x = sizeX/2;
+ PIXI.projection.y = -sizeY/2;
+
+ PIXI.offset.x = offsetX;
+ PIXI.offset.y = offsetY;
+
+
+ var filterArea = filterBlock.target.filterArea;
+ var x = filterArea.x-offsetX;
+ var y = filterArea.y-offsetY;
+
+ // update the buffers..
+ // make sure to flip the y!
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+
+ this.vertexArray[0] = x;
+ this.vertexArray[1] = y + filterArea.height;
+
+ this.vertexArray[2] = x + filterArea.width;
+ this.vertexArray[3] = y + filterArea.height;
+
+ this.vertexArray[4] = x;
+ this.vertexArray[5] = y;
+
+ this.vertexArray[6] = x + filterArea.width;
+ this.vertexArray[7] = y;
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
+
+ this.uvArray[2] = filterArea.width/this.width;
+ this.uvArray[5] = filterArea.height/this.height;
+ this.uvArray[6] = filterArea.width/this.width;
+ this.uvArray[7] = filterArea.height/this.height;
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray);
+
+ gl.viewport(0, 0, sizeX, sizeY);
+ // bind the buffer
+ gl.bindFramebuffer(gl.FRAMEBUFFER, buffer );
+
+ // set texture
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, texture.texture);
+
+ // apply!
+ //filter.applyFilterPass(sizeX, sizeY);
+ this.applyFilterPass(filter, filterArea, sizeX, sizeY);
+
+ // now restore the regular shader..
+ gl.useProgram(PIXI.defaultShader.program);
+ gl.uniform2f(PIXI.defaultShader.projectionVector, sizeX/2, -sizeY/2);
+ gl.uniform2f(PIXI.defaultShader.offsetVector, -offsetX, -offsetY);
+
+ // return the texture to the pool
+ this.texturePool.push(texture);
+ filterBlock._glFilterTexture = null;
+}
+
+PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea, width, height)
+{
+ // use program
+ var gl = PIXI.gl;
+
+ if(!filter.shader)
+ {
+ var shader = new PIXI.PixiShader();
+
+ shader.fragmentSrc = filter.fragmentSrc;
+ shader.uniforms = filter.uniforms;
+ shader.init();
+
+ filter.shader = shader;
+ }
+
+ var shader = filter.shader;
+
+ // set the shader
+ gl.useProgram(shader.program);
+
+ gl.uniform2f(shader.projectionVector, width/2, -height/2);
+ gl.uniform2f(shader.offsetVector, 0,0)
+
+ 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();
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
+ gl.vertexAttribPointer(shader.aTextureCoord, 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 );
+}
+
+PIXI.WebGLFilterManager.prototype.initShaderBuffers = function()
+{
+ var gl = PIXI.gl;
+
+ // create some buffers
+ this.vertexBuffer = gl.createBuffer();
+ this.uvBuffer = gl.createBuffer();
+ this.indexBuffer = gl.createBuffer();
+
+ // bind and upload the vertexs..
+ // keep a refferance to the vertexFloatData..
+ this.vertexArray = new Float32Array([0.0, 0.0,
+ 1.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 1.0]);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ gl.bufferData(
+ gl.ARRAY_BUFFER,
+ this.vertexArray,
+ gl.STATIC_DRAW);
+
+
+ // bind and upload the uv buffer
+ this.uvArray = new Float32Array([0.0, 0.0,
+ 1.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 1.0]);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
+ gl.bufferData(
+ gl.ARRAY_BUFFER,
+ this.uvArray,
+ gl.STATIC_DRAW);
+
+ // bind and upload the index
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
+ gl.bufferData(
+ gl.ELEMENT_ARRAY_BUFFER,
+ new Uint16Array([0, 1, 2, 1, 3, 2]),
+ gl.STATIC_DRAW);
+}
+
+PIXI.WebGLFilterManager.prototype.getBounds = function(displayObject)
+{
+ // time to get the width and height of the object!
+ var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, doTest;
+ var a, b, c, d, tx, ty, x1, x2, x3, x4, y1, y2, y3, y4;
+
+ 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;
+
+ }
+ while(tempObject != testObject)
+
+ // maximum bounds is the size of the screen..
+ //minX = minX > 0 ? minX : 0;
+ //minY = minY > 0 ? minY : 0;
+
+ displayObject.filterArea.x = minX;
+ displayObject.filterArea.y = minY;
+
+// console.log(maxX+ " : " + minX)
+ 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)
+{
+ 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);
+
+}
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
/**
* A set of functions used by the webGL renderer to draw the primitive graphics data
*
@@ -3862,7 +5846,6 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
PIXI.WebGLGraphics.updateGraphics(graphics);
}
-
PIXI.activatePrimitiveShader();
// This could be speeded up fo sure!
@@ -3872,30 +5855,29 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
// set the matrix transform for the
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m);
-
- gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y);
-
- gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha);
+ gl.uniformMatrix3fv(PIXI.primitiveShader.translationMatrix, false, m);
+
+ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y);
+ gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y);
+
+ gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha);
gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
- // WHY DOES THIS LINE NEED TO BE THERE???
- gl.vertexAttribPointer(PIXI.shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // its not even used.. but need to be set or it breaks?
- // only on pc though..
-
- gl.vertexAttribPointer(PIXI.primitiveProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 4 * 6, 0);
- gl.vertexAttribPointer(PIXI.primitiveProgram.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4);
+ gl.vertexAttribPointer(PIXI.primitiveShader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0);
+ gl.vertexAttribPointer(PIXI.primitiveShader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4);
// set the index buffer!
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer);
+
gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 );
+ PIXI.deactivatePrimitiveShader();
+
+
// return to default shader...
- PIXI.activateDefaultShader();
+// PIXI.activateShader(PIXI.defaultShader);
}
/**
@@ -4100,6 +6082,14 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
var points = graphicsData.points;
if(points.length == 0)return;
+ // if the line width is an odd number add 0.5 to align to a whole pixel
+ if(graphicsData.lineWidth%2)
+ {
+ for (var i = 0; i < points.length; i++) {
+ points[i] += 0.5;
+ };
+ }
+
// get first and last point.. figure out the middle!
var firstPoint = new PIXI.Point( points[0], points[1] );
var lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] );
@@ -4201,16 +6191,27 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y);
denom = a1*b2 - a2*b1;
-
- if (denom == 0) {
- denom+=1;
- }
+
+ if(Math.abs(denom) < 0.1 )
+ {
+
+ denom+=10.1;
+ verts.push(p2x - perpx , p2y - perpy,
+ r, g, b, alpha);
+
+ verts.push(p2x + perpx , p2y + perpy,
+ r, g, b, alpha);
+
+ continue;
+ }
px = (b1*c2 - b2*c1)/denom;
py = (a2*c1 - a1*c2)/denom;
+
pdist = (px -p2x) * (px -p2x) + (py -p2y) + (py -p2y);
+
if(pdist > 140 * 140)
{
perp3x = perpx - perp2x;
@@ -4235,6 +6236,7 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
}
else
{
+
verts.push(px , py);
verts.push(r, g, b, alpha);
@@ -4347,8 +6349,8 @@ PIXI.gl;
*
* @class WebGLRenderer
* @constructor
- * @param width=0 {number} the width of the canvas view
- * @param height=0 {number} the height of the canvas view
+ * @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 antialias=false {Boolean} sets antialias (only applicable in chrome at the moment)
@@ -4374,27 +6376,38 @@ PIXI.WebGLRenderer = function(width, height, view, transparent, antialias)
this.batchs = [];
- try
- {
- PIXI.gl = this.gl = this.view.getContext("experimental-webgl", {
- alpha: this.transparent,
- antialias:!!antialias, // SPEED UP??
- premultipliedAlpha:false,
- stencil:true
- });
- }
- catch (e)
- {
- throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this);
- }
+ var options = {
+ alpha: this.transparent,
+ antialias:!!antialias, // SPEED UP??
+ premultipliedAlpha:false,
+ stencil:true
+ }
- PIXI.initPrimitiveShader();
- PIXI.initDefaultShader();
- PIXI.initDefaultStripShader();
+ //try 'experimental-webgl'
+ try {
+ PIXI.gl = this.gl = this.view.getContext("experimental-webgl", options);
+ } catch (e) {
+ //try 'webgl'
+ try {
+ PIXI.gl = this.gl = this.view.getContext("webgl", options);
+ } catch (e) {
+ // fail, not able to get a context
+ throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this);
+ }
+ }
- PIXI.activateDefaultShader();
+ PIXI.initDefaultShaders();
+
+
+
+
+ // PIXI.activateDefaultShader();
var gl = this.gl;
+
+ gl.useProgram(PIXI.defaultShader.program);
+
+
PIXI.WebGLRenderer.gl = gl;
this.batch = new PIXI.WebGLBatch(gl);
@@ -4405,11 +6418,17 @@ PIXI.WebGLRenderer = function(width, height, view, transparent, antialias)
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;
- this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl);
+ //PIXI.pushShader(PIXI.defaultShader);
+
+ this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl, this.transparent);
+ // this.stageRenderGroup. = this.transparent
}
// constructor
@@ -4468,15 +6487,6 @@ PIXI.WebGLRenderer.prototype.render = function(stage)
this.__stage = stage;
this.stageRenderGroup.setRenderable(stage);
}
-
- // TODO not needed now...
- // update children if need be
- // best to remove first!
- /*for (var i=0; i < stage.__childrenRemoved.length; i++)
- {
- var group = stage.__childrenRemoved[i].__renderGroup
- if(group)group.removeDisplayObject(stage.__childrenRemoved[i]);
- }*/
// update any textures
PIXI.WebGLRenderer.updateTextures();
@@ -4499,6 +6509,10 @@ PIXI.WebGLRenderer.prototype.render = function(stage)
// HACK TO TEST
this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit;
+
+ PIXI.projection.x = this.width/2;
+ PIXI.projection.y = -this.height/2;
+
this.stageRenderGroup.render(PIXI.projection);
// interaction
@@ -4608,8 +6622,8 @@ PIXI.WebGLRenderer.destroyTexture = function(texture)
* resizes the webGL view to the specified width and height
*
* @method resize
- * @param width {number} the new width of the webGL view
- * @param height {number} the new height of the webGL view
+ * @param width {Number} the new width of the webGL view
+ * @param height {Number} the new height of the webGL view
*/
PIXI.WebGLRenderer.prototype.resize = function(width, height)
{
@@ -4624,7 +6638,10 @@ PIXI.WebGLRenderer.prototype.resize = function(width, height)
//var projectionMatrix = this.projectionMatrix;
PIXI.projection.x = this.width/2;
- PIXI.projection.y = this.height/2;
+ PIXI.projection.y = -this.height/2;
+
+ //PIXI.size.x = this.width/2;
+ //PIXI.size.y = -this.height/2;
// projectionMatrix[0] = 2/this.width;
// projectionMatrix[5] = -2/this.height;
@@ -4695,14 +6712,18 @@ PIXI.WebGLRenderer.prototype.handleContextRestored = function(event)
* @contructor
* @param gl {WebGLContext} An instance of the webGL context
*/
-PIXI.WebGLRenderGroup = function(gl)
+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
@@ -4736,19 +6757,20 @@ PIXI.WebGLRenderGroup.prototype.setRenderable = function(displayObject)
* @method render
* @param projection {Object}
*/
-PIXI.WebGLRenderGroup.prototype.render = function(projection)
+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.uniform2f(PIXI.shaderProgram.projectionVector, projection.x, projection.y);
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++)
{
@@ -4759,61 +6781,12 @@ PIXI.WebGLRenderGroup.prototype.render = function(projection)
continue;
}
- // non sprite batch..
- 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.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- /*
- * for now only masks are supported..
- */
- if(renderable.open)
- {
- gl.enable(gl.STENCIL_TEST);
-
- gl.colorMask(false, false, false, false);
- gl.stencilFunc(gl.ALWAYS,1,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
-
- PIXI.WebGLGraphics.renderGraphics(renderable.mask, projection);
-
- gl.colorMask(true, true, true, false);
- gl.stencilFunc(gl.NOTEQUAL,0,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
- }
- else
- {
- gl.disable(gl.STENCIL_TEST);
- }
- }
+ // render special
+ this.renderSpecial(renderable, projection);
}
}
-/**
- * Renders the stage to its webgl view
- *
- * @method handleFilter
- * @param filter {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.handleFilter = function(filter, projection)
-{
-
-}
-
/**
* Renders a specific displayObject
*
@@ -4822,13 +6795,14 @@ PIXI.WebGLRenderGroup.prototype.handleFilter = function(filter, projection)
* @param projection {Object}
* @private
*/
-PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection)
+PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection, buffer)
{
PIXI.WebGLRenderer.updateTextures();
-
var gl = this.gl;
- gl.uniform2f(PIXI.shaderProgram.projectionVector, projection.x, projection.y);
+ gl.uniform2f(PIXI.defaultShader.projectionVector, projection.x, projection.y);
+
+ this.filterManager.begin(projection, buffer);
// to do!
// render part of the scene...
@@ -4848,11 +6822,13 @@ PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, project
var nextRenderable = displayObject.first;
while(nextRenderable._iNext)
{
- nextRenderable = 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;
@@ -4882,13 +6858,11 @@ PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, project
}
// Get the LAST renderable object
- var lastRenderable = displayObject;
- var endBatch;
- var lastItem = displayObject;
- while(lastItem.children.length > 0)
+ var lastRenderable = displayObject.last;
+ while(lastRenderable._iPrev)
{
- lastItem = lastItem.children[lastItem.children.length-1];
- if(lastItem.renderable)lastRenderable = lastItem;
+ if(lastRenderable.renderable && lastRenderable.__renderGroup)break;
+ lastRenderable = lastRenderable._iNext;
}
if(lastRenderable instanceof PIXI.Sprite)
@@ -4917,6 +6891,7 @@ PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, project
endBatch = lastRenderable;
}
+ //console.log(endBatch);
// TODO - need to fold this up a bit!
if(startBatch == endBatch)
@@ -4982,8 +6957,10 @@ PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, project
*/
PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
{
+
var worldVisible = renderable.vcount === PIXI.visibleCount
+
if(renderable instanceof PIXI.TilingSprite)
{
if(worldVisible)this.renderTilingSprite(renderable, projection);
@@ -5002,29 +6979,76 @@ PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
}
else if(renderable instanceof PIXI.FilterBlock)
{
- /*
- * for now only masks are supported..
- */
+ this.handleFilterBlock(renderable, projection);
+ }
+}
- var gl = PIXI.gl;
+flip = false;
+var maskStack = [];
+var maskPosition = 0;
- if(renderable.open)
+//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)
{
- gl.enable(gl.STENCIL_TEST);
-
- gl.colorMask(false, false, false, false);
- gl.stencilFunc(gl.ALWAYS,1,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
-
- PIXI.WebGLGraphics.renderGraphics(renderable.mask, projection);
+ 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);
- // we know this is a render texture so enable alpha too..
gl.colorMask(true, true, true, true);
- gl.stencilFunc(gl.NOTEQUAL,0,0xff);
+ 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);
}
}
@@ -5090,7 +7114,7 @@ PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end)
* It keeps going back until it finds a sprite or the stage
*/
var previousRenderable = start;
- while(previousRenderable != this.root)
+ while(previousRenderable != this.root.first)
{
previousRenderable = previousRenderable._iPrev;
if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
@@ -5104,7 +7128,7 @@ PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end)
* scene graph
*/
var previousRenderable2 = end;
- while(previousRenderable2 != this.root)
+ while(previousRenderable2 != this.root.first)
{
previousRenderable2 = previousRenderable2._iPrev;
if(previousRenderable2.renderable && previousRenderable2.__renderGroup)break;
@@ -5476,6 +7500,7 @@ PIXI.WebGLRenderGroup.prototype.removeObject = function(displayObject)
}
}
+
/**
* Initializes a tiling sprite
*
@@ -5546,25 +7571,26 @@ PIXI.WebGLRenderGroup.prototype.initTilingSprite = function(sprite)
PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
{
var gl = this.gl;
- var shaderProgram = PIXI.shaderProgram;
-// mat
- //var mat4Real = PIXI.mat3.toMat4(strip.worldTransform);
- //PIXI.mat4.transpose(mat4Real);
- //PIXI.mat4.multiply(projectionMatrix, mat4Real, mat4Real )
+ PIXI.activateStripShader();
+
+ var shader = PIXI.stripShader;
+
+ var program = shader.program;
- gl.useProgram(PIXI.stripShaderProgram);
-
var m = PIXI.mat3.clone(strip.worldTransform);
PIXI.mat3.transpose(m);
+// console.log(projection)
// set the matrix transform for the
- gl.uniformMatrix3fv(PIXI.stripShaderProgram.translationMatrix, false, m);
- gl.uniform2f(PIXI.stripShaderProgram.projectionVector, projection.x, projection.y);
- gl.uniform1f(PIXI.stripShaderProgram.alpha, strip.worldAlpha);
+ 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);
@@ -5575,23 +7601,22 @@ PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
}
*/
-
+ //console.log("!!")
if(!strip.dirty)
- {
-
+ {
gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, strip.verticies)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
// update the uvs
gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
+ 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(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribPointer(shader.colorAttribute, 1, gl.FLOAT, false, 0, 0);
// dont need to upload!
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
@@ -5601,30 +7626,30 @@ PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
strip.dirty = false;
gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
+ 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(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
+ 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(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
+ 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);
}
- //console.log(gl.TRIANGLE_STRIP);
gl.drawElements(gl.TRIANGLE_STRIP, strip.indices.length, gl.UNSIGNED_SHORT, 0);
- gl.useProgram(PIXI.shaderProgram);
+ PIXI.deactivateStripShader();
+ //gl.useProgram(PIXI.currentProgram);
}
/**
@@ -5638,6 +7663,8 @@ PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
PIXI.WebGLRenderGroup.prototype.renderTilingSprite = function(sprite, projectionMatrix)
{
var gl = this.gl;
+
+
var shaderProgram = PIXI.shaderProgram;
var tilePosition = sprite.tilePosition;
@@ -5705,156 +7732,77 @@ PIXI.WebGLRenderGroup.prototype.initStrip = function(strip)
*/
-/*
- * the default suoer fast shader!
- */
+PIXI.initDefaultShaders = function()
+{
+ PIXI.primitiveShader = new PIXI.PrimitiveShader();
+ PIXI.primitiveShader.init();
-PIXI.shaderFragmentSrc = [
- "precision mediump float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));",
- "gl_FragColor = gl_FragColor * vColor;",
- "}"
-];
+ PIXI.stripShader = new PIXI.StripShader();
+ PIXI.stripShader.init();
-PIXI.shaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
- //"uniform mat4 uMVMatrix;",
+ PIXI.defaultShader = new PIXI.PixiShader();
+ PIXI.defaultShader.init();
+
+ var gl = PIXI.gl;
+ var shaderProgram = PIXI.defaultShader.program;
+
+
+ gl.useProgram(shaderProgram);
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- // "gl_Position = uMVMatrix * vec4(aVertexPosition, 1.0, 1.0);",
- "gl_Position = vec4( aVertexPosition.x / projectionVector.x -1.0, aVertexPosition.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
+ 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);
+}
/*
- * the triangle strip shader..
- */
-PIXI.stripShaderFragmentSrc = [
- "precision mediump float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform float alpha;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));",
- "gl_FragColor = gl_FragColor * alpha;",
- "}"
-];
-
-
-PIXI.stripShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-
-/*
- * primitive shader..
- */
-
-PIXI.primitiveShaderFragmentSrc = [
- "precision mediump float;",
- "varying vec4 vColor;",
- "void main(void) {",
- "gl_FragColor = vColor;",
- "}"
-];
-
-PIXI.primitiveShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec4 aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "uniform float alpha;",
- "varying vec4 vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vColor = aColor * alpha;",
- "}"
-];
-
-PIXI.initPrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- var shaderProgram = PIXI.compileProgram(PIXI.primitiveShaderVertexSrc, PIXI.primitiveShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
-
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
-
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- PIXI.primitiveProgram = shaderProgram;
-}
-
-PIXI.initDefaultShader = function()
-{
- var gl = this.gl;
- var shaderProgram = PIXI.compileProgram(PIXI.shaderVertexSrc, PIXI.shaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
-
- // shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
- shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
-
- PIXI.shaderProgram = shaderProgram;
-}
-
-PIXI.initDefaultStripShader = function()
-{
- var gl = this.gl;
- var shaderProgram = PIXI.compileProgram(PIXI.stripShaderVertexSrc, PIXI.stripShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
-
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
-
- shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
-
- PIXI.stripShaderProgram = shaderProgram;
-}
+SHADER COMPILER HELPERS
+*/
PIXI.CompileVertexShader = function(gl, shaderSrc)
{
@@ -5874,7 +7822,7 @@ PIXI._CompileShader = function(gl, shaderSrc, shaderType)
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- alert(gl.getShaderInfoLog(shader));
+ console.log(gl.getShaderInfoLog(shader));
return null;
}
@@ -5895,49 +7843,19 @@ PIXI.compileProgram = function(vertexSrc, fragmentSrc)
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- alert("Could not initialise shaders");
+ console.log("Could not initialise shaders");
}
return shaderProgram;
}
-
-PIXI.activateDefaultShader = function()
-{
- var gl = PIXI.gl;
- var shaderProgram = PIXI.shaderProgram;
-
- gl.useProgram(shaderProgram);
-
-
- gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
- gl.enableVertexAttribArray(shaderProgram.colorAttribute);
-}
-
-
-
-PIXI.activatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.disableVertexAttribArray(PIXI.shaderProgram.textureCoordAttribute);
- gl.disableVertexAttribArray(PIXI.shaderProgram.colorAttribute);
-
- gl.useProgram(PIXI.primitiveProgram);
-
- gl.enableVertexAttribArray(PIXI.primitiveProgram.vertexPositionAttribute);
- gl.enableVertexAttribArray(PIXI.primitiveProgram.colorAttribute);
-}
-
-
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
/**
* A Text Object will create a line(s) of text using bitmap font. To split a line you can use "\n", "\r" or "\r\n"
- * You can generate the fnt files using
+ * You can generate the fnt files using
* http://www.angelcode.com/products/bmfont/ for windows or
* http://www.bmglyph.com/ for mac.
*
@@ -6027,7 +7945,7 @@ PIXI.BitmapText.prototype.updateText = function()
prevCharCode = null;
continue;
}
-
+
var charData = data.chars[charCode];
if(!charData) continue;
@@ -6068,7 +7986,7 @@ PIXI.BitmapText.prototype.updateText = function()
this.addChild(c);
}
- this.width = maxLineWidth * scale;
+ this.width = pos.x * scale;
this.height = (pos.y + data.lineHeight) * scale;
};
@@ -6090,7 +8008,7 @@ PIXI.BitmapText.prototype.updateTransform = function()
this.dirty = false;
}
-
+
PIXI.DisplayObjectContainer.prototype.updateTransform.call(this);
};
@@ -6112,9 +8030,9 @@ PIXI.BitmapText.fonts = {};
* @param [style.fill="black"] {Object} A canvas fillstyle that will be used on the text eg "red", "#00FF00"
* @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right")
* @param [style.stroke] {String} A canvas fillstyle that will be used on the text stroke eg "blue", "#FCFF00"
- * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke)
+ * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke)
* @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used
- * @param [style.wordWrapWidth=100] {number} The width at which text will wrap
+ * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap
*/
PIXI.Text = function(text, style)
{
@@ -6124,7 +8042,7 @@ PIXI.Text = function(text, style)
this.setText(text);
this.setStyle(style);
-
+
this.updateText();
this.dirty = false;
};
@@ -6142,9 +8060,9 @@ PIXI.Text.prototype.constructor = PIXI.Text;
* @param [style.fill="black"] {Object} A canvas fillstyle that will be used on the text eg "red", "#00FF00"
* @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right")
* @param [style.stroke="black"] {String} A canvas fillstyle that will be used on the text stroke eg "blue", "#FCFF00"
- * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke)
+ * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke)
* @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used
- * @param [style.wordWrapWidth=100] {number} The width at which text will wrap
+ * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap
*/
PIXI.Text.prototype.setStyle = function(style)
{
@@ -6166,7 +8084,7 @@ PIXI.Text.prototype.setStyle = function(style)
* @methos setText
* @param {String} text The copy that you would like the text to display
*/
-PIXI.Sprite.prototype.setText = function(text)
+PIXI.Text.prototype.setText = function(text)
{
this.text = text.toString() || " ";
this.dirty = true;
@@ -6181,9 +8099,9 @@ PIXI.Sprite.prototype.setText = function(text)
PIXI.Text.prototype.updateText = function()
{
this.context.font = this.style.font;
-
+
var outputText = this.text;
-
+
// word wrap
// preserve original text
if(this.style.wordWrap)outputText = this.wordWrap(this.text);
@@ -6201,7 +8119,7 @@ PIXI.Text.prototype.updateText = function()
maxLineWidth = Math.max(maxLineWidth, lineWidth);
}
this.canvas.width = maxLineWidth + this.style.strokeThickness;
-
+
//calculate text height
var lineHeight = this.determineFontHeight("font: " + this.style.font + ";") + this.style.strokeThickness;
this.canvas.height = lineHeight * lines.length;
@@ -6209,7 +8127,7 @@ PIXI.Text.prototype.updateText = function()
//set canvas text styles
this.context.fillStyle = this.style.fill;
this.context.font = this.style.font;
-
+
this.context.strokeStyle = this.style.stroke;
this.context.lineWidth = this.style.strokeThickness;
@@ -6219,7 +8137,7 @@ PIXI.Text.prototype.updateText = function()
for (i = 0; i < lines.length; i++)
{
var linePosition = new PIXI.Point(this.style.strokeThickness / 2, this.style.strokeThickness / 2 + i * lineHeight);
-
+
if(this.style.align == "right")
{
linePosition.x += maxLineWidth - lineWidths[i];
@@ -6239,7 +8157,7 @@ PIXI.Text.prototype.updateText = function()
this.context.fillText(lines[i], linePosition.x, linePosition.y);
}
}
-
+
this.updateTexture();
};
@@ -6255,10 +8173,10 @@ PIXI.Text.prototype.updateTexture = function()
this.texture.baseTexture.height = this.canvas.height;
this.texture.frame.width = this.canvas.width;
this.texture.frame.height = this.canvas.height;
-
+
this._width = this.canvas.width;
this._height = this.canvas.height;
-
+
PIXI.texturesToUpdate.push(this.texture.baseTexture);
};
@@ -6272,10 +8190,10 @@ PIXI.Text.prototype.updateTransform = function()
{
if(this.dirty)
{
- this.updateText();
+ this.updateText();
this.dirty = false;
}
-
+
PIXI.Sprite.prototype.updateTransform.call(this);
};
@@ -6287,12 +8205,12 @@ PIXI.Text.prototype.updateTransform = function()
* @param fontStyle {Object}
* @private
*/
-PIXI.Text.prototype.determineFontHeight = function(fontStyle)
+PIXI.Text.prototype.determineFontHeight = function(fontStyle)
{
// build a little reference dictionary so if the font style has been used return a
// cached version...
var result = PIXI.Text.heightCache[fontStyle];
-
+
if(!result)
{
var body = document.getElementsByTagName("body")[0];
@@ -6301,18 +8219,19 @@ PIXI.Text.prototype.determineFontHeight = function(fontStyle)
dummy.appendChild(dummyText);
dummy.setAttribute("style", fontStyle + ';position:absolute;top:0;left:0');
body.appendChild(dummy);
-
+
result = dummy.offsetHeight;
PIXI.Text.heightCache[fontStyle] = result;
-
+
body.removeChild(dummy);
}
-
+
return result;
};
/**
- * A Text Object will apply wordwrap
+ * Applies newlines to a string to have it optimally fit into the horizontal
+ * bounds set by the Text object's wordWrapWidth property.
*
* @method wordWrap
* @param text {String}
@@ -6320,48 +8239,37 @@ PIXI.Text.prototype.determineFontHeight = function(fontStyle)
*/
PIXI.Text.prototype.wordWrap = function(text)
{
- // search good wrap position
- var searchWrapPos = function(ctx, text, start, end, wrapWidth)
- {
- var p = Math.floor((end-start) / 2) + start;
- if(p == start) {
- return 1;
- }
-
- if(ctx.measureText(text.substring(0,p)).width <= wrapWidth)
- {
- if(ctx.measureText(text.substring(0,p+1)).width > wrapWidth)
- {
- return p;
- }
- else
- {
- return arguments.callee(ctx, text, p, end, wrapWidth);
- }
- }
- else
- {
- return arguments.callee(ctx, text, start, p, wrapWidth);
- }
- };
-
- var lineWrap = function(ctx, text, wrapWidth)
- {
- if(ctx.measureText(text).width <= wrapWidth || text.length < 1)
- {
- return text;
- }
- var pos = searchWrapPos(ctx, text, 0, text.length, wrapWidth);
- return text.substring(0, pos) + "\n" + arguments.callee(ctx, text.substring(pos), wrapWidth);
- };
-
+ // Greedy wrapping algorithm that will wrap words as the line grows longer
+ // than its horizontal bounds.
var result = "";
var lines = text.split("\n");
for (var i = 0; i < lines.length; i++)
{
- result += lineWrap(this.context, lines[i], this.style.wordWrapWidth) + "\n";
+ var spaceLeft = this.style.wordWrapWidth;
+ var words = lines[i].split(" ");
+ for (var j = 0; j < words.length; j++)
+ {
+ var wordWidth = this.context.measureText(words[j]).width;
+ var wordWidthWithSpace = wordWidth + this.context.measureText(" ").width;
+ if(wordWidthWithSpace > spaceLeft)
+ {
+ // Skip printing the newline if it's the first word of the line that is
+ // greater than the word wrap width.
+ if(j > 0)
+ {
+ result += "\n";
+ }
+ result += words[j] + " ";
+ spaceLeft = this.style.wordWrapWidth - wordWidth;
+ }
+ else
+ {
+ spaceLeft -= wordWidthWithSpace;
+ result += words[j] + " ";
+ }
+ }
+ result += "\n";
}
-
return result;
};
@@ -6377,7 +8285,7 @@ PIXI.Text.prototype.destroy = function(destroyTexture)
{
this.texture.destroy();
}
-
+
};
PIXI.Text.heightCache = {};
@@ -6446,19 +8354,19 @@ PIXI.BaseTexture = function(source)
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 } );
@@ -6471,7 +8379,7 @@ PIXI.BaseTexture = function(source)
this.hasLoaded = true;
this.width = this.source.width;
this.height = this.source.height;
-
+
PIXI.texturesToUpdate.push(this);
}
@@ -6511,7 +8419,7 @@ PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin)
{
// new Image() breaks tex loading in some versions of Chrome.
// See https://code.google.com/p/chromium/issues/detail?id=238071
- var image = new Image();//document.createElement('img');
+ var image = new Image();//document.createElement('img');
if (crossorigin)
{
image.crossOrigin = '';
@@ -6539,7 +8447,7 @@ PIXI.FrameCache = {};
* @uses EventTarget
* @constructor
* @param baseTexture {BaseTexture} The base texture source to create the texture from
- * @param frmae {Rectangle} The rectangle frame of the texture to show
+ * @param frame {Rectangle} The rectangle frame of the texture to show
*/
PIXI.Texture = function(baseTexture, frame)
{
@@ -6584,7 +8492,7 @@ PIXI.Texture = function(baseTexture, frame)
{
if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
//console.log(frame)
-
+
this.setFrame(frame);
}
else
@@ -6663,13 +8571,13 @@ PIXI.Texture.prototype.setFrame = function(frame)
PIXI.Texture.fromImage = function(imageUrl, crossorigin)
{
var texture = PIXI.TextureCache[imageUrl];
-
+
if(!texture)
{
texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin));
PIXI.TextureCache[imageUrl] = texture;
}
-
+
return texture;
}
@@ -6719,7 +8627,7 @@ PIXI.Texture.addTextureToCache = function(texture, id)
}
/**
- * Remove a texture from the textureCache.
+ * Remove a texture from the textureCache.
*
* @static
* @method removeTextureFromCache
@@ -6766,8 +8674,8 @@ PIXI.Texture.frameUpdates = [];
@class RenderTexture
@extends Texture
@constructor
- @param width {number} The width of the render texture
- @param height {number} The height of the render texture
+ @param width {Number} The width of the render texture
+ @param height {Number} The height of the render texture
*/
PIXI.RenderTexture = function(width, height)
{
@@ -6830,12 +8738,10 @@ PIXI.RenderTexture.prototype.initWebGL = function()
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);
+ this.projection = new PIXI.Point(this.width/2 , -this.height/2);
// set the correct render function..
this.render = this.renderWebGL;
-
-
}
@@ -6848,7 +8754,7 @@ PIXI.RenderTexture.prototype.resize = function(width, height)
if(PIXI.gl)
{
this.projection.x = this.width/2
- this.projection.y = this.height/2;
+ this.projection.y = -this.height/2;
var gl = PIXI.gl;
gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture);
@@ -6912,9 +8818,8 @@ PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, cle
displayObject.worldTransform = PIXI.mat3.create();//sthis.indetityMatrix;
// modify to flip...
displayObject.worldTransform[4] = -1;
- displayObject.worldTransform[5] = this.projection.y * 2;
+ displayObject.worldTransform[5] = this.projection.y * -2;
-
if(position)
{
displayObject.worldTransform[2] = position.x;
@@ -6935,20 +8840,20 @@ PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, cle
{
if(displayObject == renderGroup.root)
{
- renderGroup.render(this.projection);
+ renderGroup.render(this.projection, this.glFramebuffer);
}
else
{
- renderGroup.renderSpecific(displayObject, this.projection);
+ 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.renderGroup.render(this.projection, this.glFramebuffer);
}
-
+
displayObject.worldTransform = originalWorldTransform;
}
@@ -6989,7 +8894,6 @@ PIXI.RenderTexture.prototype.renderCanvas = function(displayObject, position, cl
// PIXI.texturesToUpdate.push(this.baseTexture);
}
-
/**
* https://github.com/mrdoob/eventtarget.js/
* THankS mr DOob!
@@ -7010,14 +8914,14 @@ PIXI.RenderTexture.prototype.renderCanvas = function(displayObject, position, cl
PIXI.EventTarget = function () {
var listeners = {};
-
+
this.addEventListener = this.on = function ( type, listener ) {
-
-
+
+
if ( listeners[ type ] === undefined ) {
listeners[ type ] = [];
-
+
}
if ( listeners[ type ].indexOf( listener ) === - 1 ) {
@@ -7028,11 +8932,17 @@ PIXI.EventTarget = function () {
};
this.dispatchEvent = this.emit = function ( event ) {
-
- for ( var listener in listeners[ event.type ] ) {
- listeners[ event.type ][ listener ]( event );
-
+ if ( !listeners[ event.type ] || !listeners[ event.type ].length ) {
+
+ return;
+
+ }
+
+ for(var i = 0, l = listeners[ event.type ].length; i < l; i++) {
+
+ listeners[ event.type ][ i ]( event );
+
}
};
@@ -7055,7 +8965,7 @@ PIXI.EventTarget = function () {
PolyK library
url: http://polyk.ivank.net
Released under MIT licence.
-
+
Copyright (c) 2012 Ivan Kuckir
Permission is hereby granted, free of charge, to any person
@@ -7079,8 +8989,8 @@ PIXI.EventTarget = function () {
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
- This is an amazing lib!
-
+ This is an amazing lib!
+
slightly modified by mat groves (matgroves.com);
*/
@@ -7096,13 +9006,13 @@ PIXI.PolyK = {};
PIXI.PolyK.Triangulate = function(p)
{
var sign = true;
-
+
var n = p.length>>1;
if(n<3) return [];
var tgs = [];
var avl = [];
for(var i=0; i 3)
@@ -7110,11 +9020,11 @@ PIXI.PolyK.Triangulate = function(p)
var i0 = avl[(i+0)%al];
var i1 = avl[(i+1)%al];
var i2 = avl[(i+2)%al];
-
+
var ax = p[2*i0], ay = p[2*i0+1];
var bx = p[2*i1], by = p[2*i1+1];
var cx = p[2*i2], cy = p[2*i2+1];
-
+
var earFound = false;
if(PIXI.PolyK._convex(ax, ay, bx, by, cx, cy, sign))
{
@@ -7133,7 +9043,7 @@ PIXI.PolyK.Triangulate = function(p)
al--;
i = 0;
}
- else if(i++ > 3*al)
+ else if(i++ > 3*al)
{
// need to flip flip reverse it!
// reset!
@@ -7142,17 +9052,17 @@ PIXI.PolyK.Triangulate = function(p)
var tgs = [];
avl = [];
for(var i=0; i 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.alive)
- {
- args[0] = currentNode;
- callback.apply(callbackContext, args);
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
-
- }
+ this.iterate('alive', true, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
},
@@ -10364,23 +12382,121 @@ Phaser.Group.prototype = {
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').
+ */
+ iterate: function (key, value, returnType, callback, callbackContext, args) {
+
+ if (returnType == Phaser.Group.RETURN_TOTAL && this._container.children.length == 0)
+ {
+ return -1;
+ }
+
+ 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.alive == false)
+ if (currentNode[key] === value)
{
- args[0] = currentNode;
- callback.apply(callbackContext, args);
+ 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;
+ }
+
},
/**
@@ -10397,23 +12513,7 @@ Phaser.Group.prototype = {
state = true;
}
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.exists === state)
- {
- return currentNode;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
-
- return null;
+ return this.iterate('exists', state, Phaser.Group.RETURN_CHILD);
},
@@ -10426,23 +12526,7 @@ Phaser.Group.prototype = {
*/
getFirstAlive: function () {
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.alive)
- {
- return currentNode;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
-
- return null;
+ return this.iterate('alive', true, Phaser.Group.RETURN_CHILD);
},
@@ -10455,23 +12539,7 @@ Phaser.Group.prototype = {
*/
getFirstDead: function () {
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (!currentNode.alive)
- {
- return currentNode;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
-
- return null;
+ return this.iterate('alive', false, Phaser.Group.RETURN_CHILD);
},
@@ -10483,29 +12551,7 @@ Phaser.Group.prototype = {
*/
countLiving: function () {
- var total = 0;
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.alive)
- {
- total++;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
- else
- {
- total = -1;
- }
-
- return total;
+ return this.iterate('alive', true, Phaser.Group.RETURN_TOTAL);
},
@@ -10517,29 +12563,7 @@ Phaser.Group.prototype = {
*/
countDead: function () {
- var total = 0;
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (!currentNode.alive)
- {
- total++;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
- else
- {
- total = -1;
- }
-
- return total;
+ return this.iterate('alive', false, Phaser.Group.RETURN_TOTAL);
},
@@ -10684,6 +12708,48 @@ Phaser.Group.prototype = {
},
+ 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;
+
+ },
+
/**
* Dumps out a list of Group children and their index positions to the browser console. Useful for group debugging.
*
@@ -10790,7 +12856,8 @@ Phaser.Group.prototype = {
Object.defineProperty(Phaser.Group.prototype, "total", {
get: function () {
- return this._container.children.length;
+ return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
+ // return this._container.children.length;
}
});
@@ -10803,7 +12870,8 @@ Object.defineProperty(Phaser.Group.prototype, "total", {
Object.defineProperty(Phaser.Group.prototype, "length", {
get: function () {
- return this._container.children.length;
+ return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
+ // return this._container.children.length;
}
});
@@ -11173,6 +13241,22 @@ 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;
+ }
+
+});
+
/**
* @author Richard Davey
* @copyright 2013 Photon Storm Ltd.
@@ -11597,7 +13681,13 @@ Phaser.Game.prototype = {
this.time.update(time);
- if (!this._paused)
+ if (this._paused)
+ {
+ this.renderer.render(this.stage._stage);
+ this.plugins.render();
+ this.state.render();
+ }
+ else
{
this.plugins.preUpdate();
this.physics.preUpdate();
@@ -11612,6 +13702,7 @@ Phaser.Game.prototype = {
this.plugins.update();
this.world.postUpdate();
+ this.plugins.postUpdate();
this.renderer.render(this.stage._stage);
this.plugins.render();
@@ -13197,23 +15288,29 @@ Phaser.Mouse = function (game) {
this.callbackContext = this.game;
/**
- * @property {Description} mouseDownCallback - Description.
+ * @property {function} mouseDownCallback - Description.
* @default
*/
this.mouseDownCallback = null;
/**
- * @property {Description} mouseMoveCallback - Description.
+ * @property {function} mouseMoveCallback - Description.
* @default
*/
this.mouseMoveCallback = null;
/**
- * @property {Description} mouseUpCallback - Description.
+ * @property {function} mouseUpCallback - Description.
* @default
*/
this.mouseUpCallback = null;
+ /**
+ * @property {number} button- The type of click, either: Phaser.Mouse.NO_BUTTON, Phaser.Mouse.LEFT_BUTTON, Phaser.Mouse.MIDDLE_BUTTON or Phaser.Mouse.RIGHT_BUTTON.
+ * @default
+ */
+ this.button = -1;
+
/**
* You can disable all Input by setting disabled = true. While set all new input related events will be ignored.
* @property {boolean} disabled
@@ -13228,8 +15325,20 @@ Phaser.Mouse = function (game) {
*/
this.locked = false;
+ /**
+ * This event is dispatched when the browser enters or leaves pointer lock state.
+ * @property {Phaser.Signal} pointerLock
+ * @default
+ */
+ this.pointerLock = new Phaser.Signal;
+
};
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Mouse.NO_BUTTON = -1;
/**
* @constant
* @type {number}
@@ -13283,7 +15392,7 @@ Phaser.Mouse.prototype = {
},
/**
- * Description.
+ * The internal method that handles the mouse down event from the browser.
* @method Phaser.Mouse#onMouseDown
* @param {MouseEvent} event
*/
@@ -13291,6 +15400,19 @@ Phaser.Mouse.prototype = {
event.preventDefault();
+ if (event.which === 1)
+ {
+ this.button = Phaser.Mouse.LEFT_BUTTON;
+ }
+ else if (event.which === 2)
+ {
+ this.button = Phaser.Mouse.MIDDLE_BUTTON;
+ }
+ else if (event.which === 3)
+ {
+ this.button = Phaser.Mouse.RIGHT_BUTTON;
+ }
+
if (this.mouseDownCallback)
{
this.mouseDownCallback.call(this.callbackContext, event);
@@ -13308,7 +15430,7 @@ Phaser.Mouse.prototype = {
},
/**
- * Description
+ * The internal method that handles the mouse move event from the browser.
* @method Phaser.Mouse#onMouseMove
* @param {MouseEvent} event
*/
@@ -13333,7 +15455,7 @@ Phaser.Mouse.prototype = {
},
/**
- * Description.
+ * The internal method that handles the mouse up event from the browser.
* @method Phaser.Mouse#onMouseUp
* @param {MouseEvent} event
*/
@@ -13341,6 +15463,8 @@ Phaser.Mouse.prototype = {
event.preventDefault();
+ this.button = Phaser.Mouse.NO_BUTTON;
+
if (this.mouseUpCallback)
{
this.mouseUpCallback.call(this.callbackContext, event);
@@ -13358,7 +15482,9 @@ Phaser.Mouse.prototype = {
},
/**
- * Description.
+ * If the browser supports it you can request that the pointer be locked to the browser window.
+ * This is classically known as 'FPS controls', where the pointer can't leave the browser until the user presses an exit key.
+ * If the browser successfully enters a locked state the event Phaser.Mouse.pointerLock will be dispatched and the first parameter will be 'true'.
* @method Phaser.Mouse#requestPointerLock
*/
requestPointerLock: function () {
@@ -13377,15 +15503,15 @@ Phaser.Mouse.prototype = {
return _this.pointerLockChange(event);
};
- document.addEventListener('pointerlockchange', this._pointerLockChange, false);
- document.addEventListener('mozpointerlockchange', this._pointerLockChange, false);
- document.addEventListener('webkitpointerlockchange', this._pointerLockChange, false);
+ document.addEventListener('pointerlockchange', this._pointerLockChange, true);
+ document.addEventListener('mozpointerlockchange', this._pointerLockChange, true);
+ document.addEventListener('webkitpointerlockchange', this._pointerLockChange, true);
}
},
/**
- * Description.
+ * Internal pointerLockChange handler.
* @method Phaser.Mouse#pointerLockChange
* @param {MouseEvent} event
*/
@@ -13397,17 +15523,19 @@ Phaser.Mouse.prototype = {
{
// Pointer was successfully locked
this.locked = true;
+ this.pointerLock.dispatch(true);
}
else
{
// Pointer was unlocked
this.locked = false;
+ this.pointerLock.dispatch(false);
}
},
/**
- * Description.
+ * Internal release pointer lock handler.
* @method Phaser.Mouse#releasePointerLock
*/
releasePointerLock: function () {
@@ -13416,9 +15544,9 @@ Phaser.Mouse.prototype = {
document.exitPointerLock();
- document.removeEventListener('pointerlockchange', this._pointerLockChange);
- document.removeEventListener('mozpointerlockchange', this._pointerLockChange);
- document.removeEventListener('webkitpointerlockchange', this._pointerLockChange);
+ document.removeEventListener('pointerlockchange', this._pointerLockChange, true);
+ document.removeEventListener('mozpointerlockchange', this._pointerLockChange, true);
+ document.removeEventListener('webkitpointerlockchange', this._pointerLockChange, true);
},
@@ -13428,13 +15556,14 @@ Phaser.Mouse.prototype = {
*/
stop: function () {
- this.game.stage.canvas.removeEventListener('mousedown', this._onMouseDown);
- this.game.stage.canvas.removeEventListener('mousemove', this._onMouseMove);
- this.game.stage.canvas.removeEventListener('mouseup', this._onMouseUp);
+ this.game.stage.canvas.removeEventListener('mousedown', this._onMouseDown, true);
+ this.game.stage.canvas.removeEventListener('mousemove', this._onMouseMove, true);
+ this.game.stage.canvas.removeEventListener('mouseup', this._onMouseUp, true);
}
};
+
/**
* @author Richard Davey
* @copyright 2013 Photon Storm Ltd.
@@ -14017,7 +16146,6 @@ Phaser.Pointer.prototype = {
}
return this;
-
}
// Work out which object is on the top
@@ -15049,28 +17177,60 @@ Phaser.InputHandler.prototype = {
/**
* Is the Pointer over this Sprite?
* @method Phaser.InputHandler#pointerOver
- * @param {Pointer} pointer
- * @return {bool
+ * @param {number} [index] - The ID number of a Pointer to check. If you don't provide a number it will check all Pointers.
+ * @return {boolean} True if the given pointer (if a index was given, or any pointer if not) is over this object.
*/
- pointerOver: function (pointer) {
+ pointerOver: function (index) {
- pointer = pointer || 0;
+ if (this.enabled)
+ {
+ if (typeof index === 'undefined')
+ {
+ for (var i = 0; i < 10; i++)
+ {
+ if (this._pointerData[i].isOver)
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ return this._pointerData[index].isOver;
+ }
+ }
- return this._pointerData[pointer].isOver;
+ return false;
},
/**
* Is the Pointer outside of this Sprite?
* @method Phaser.InputHandler#pointerOut
- * @param {Pointer} pointer
- * @return {boolean}
+ * @param {number} [index] - The ID number of a Pointer to check. If you don't provide a number it will check all Pointers.
+ * @return {boolean} True if the given pointer (if a index was given, or any pointer if not) is out of this object.
*/
pointerOut: function (pointer) {
- pointer = pointer || 0;
+ if (this.enabled)
+ {
+ if (typeof index === 'undefined')
+ {
+ for (var i = 0; i < 10; i++)
+ {
+ if (this._pointerData[i].isOut)
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ return this._pointerData[index].isOut;
+ }
+ }
- return this._pointerData[pointer].isOut;
+ return false;
},
@@ -15146,12 +17306,13 @@ Phaser.InputHandler.prototype = {
},
/**
- * Description.
- * @method Phaser.InputHandler#checkPixel
- * @param {Description} x - Description.
- * @param {Description} y - Description.
- * @return {boolean}
- */
+ * Runs a pixel perfect check against the given x/y coordinates of the Sprite this InputHandler is bound to.
+ * It compares the alpha value of the pixel and if >= InputHandler.pixelPerfectAlpha it returns true.
+ * @method Phaser.InputHandler#checkPixel
+ * @param {number} x - The x coordinate to check.
+ * @param {number} y - The y coordinate to check.
+ * @return {boolean} true if there is the alpha of the pixel is >= InputHandler.pixelPerfectAlpha
+ */
checkPixel: function (x, y) {
// Grab a pixel from our image into the hitCanvas and then test it
@@ -15159,8 +17320,6 @@ Phaser.InputHandler.prototype = {
{
this.game.input.hitContext.clearRect(0, 0, 1, 1);
- // This will fail if the image is part of a texture atlas - need to modify the x/y values here
-
x += this.sprite.texture.frame.x;
y += this.sprite.texture.frame.y;
@@ -17554,7 +19713,7 @@ Phaser.BitmapText.prototype.destroy = function() {
this.group.remove(this);
}
- if (this.canvas.parentNode)
+ if (this.canvas && this.canvas.parentNode)
{
this.canvas.parentNode.removeChild(this.canvas);
}
@@ -17798,6 +19957,13 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame,
*/
this.freezeFrames = false;
+ /**
+ * When the Button is clicked you can optionally force the state to "out".
+ * @property {boolean} forceOut
+ * @default
+ */
+ this.forceOut = true;
+
this.setFrames(overFrame, outFrame, downFrame);
if (callback !== null)
@@ -17882,7 +20048,7 @@ Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) {
{
this._onDownFrameName = downFrame;
- if (this.input.pointerOver())
+ if (this.input.pointerDown())
{
this.frameName = downFrame;
}
@@ -17891,7 +20057,7 @@ Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) {
{
this._onDownFrameID = downFrame;
- if (this.input.pointerOver())
+ if (this.input.pointerDown())
{
this.frame = downFrame;
}
@@ -18142,10 +20308,23 @@ Phaser.Button.prototype.onInputUpHandler = function (pointer) {
this.onUpSound.play(this.onUpSoundMarker);
}
+ if (this.forceOut && this.freezeFrames == false)
+ {
+ if (this._onOutFrameName != null)
+ {
+ this.frameName = this._onOutFrameName;
+ }
+ else if (this._onOutFrameID != null)
+ {
+ this.frame = this._onOutFrameID;
+ }
+ }
+
if (this.onInputUp)
{
this.onInputUp.dispatch(this, pointer);
}
+
};
/**
@@ -18200,6 +20379,18 @@ Phaser.Graphics.prototype.destroy = function() {
}
+/*
+* Draws a {Phaser.Polygon} or a {PIXI.Polygon} filled
+*/
+Phaser.Graphics.prototype.drawPolygon = function (poly) {
+
+ graphics.moveTo(poly.points[0].x, poly.points[0].y);
+ for (var i = 1; i < poly.points.length; i += 1) {
+ graphics.lineTo(poly.points[i].x, poly.points[i].y);
+ }
+ graphics.lineTo(poly.points[0].x, poly.points[0].y);
+}
+
Object.defineProperty(Phaser.Graphics.prototype, 'angle', {
get: function() {
@@ -18582,45 +20773,19 @@ Phaser.Canvas = {
Phaser.StageScaleMode = function (game, width, height) {
/**
- * @property {number} _startHeight - Stage height when starting the game.
- * @default
- * @private
+ * @property {Phaser.Game} game - A reference to the currently running game.
*/
- this._startHeight = 0;
+ this.game = game;
/**
- * @property {boolean} forceLandscape - If the game should be forced to use Landscape mode, this is set to true by Game.Stage
- * @default
+ * @property {number} width - Width of the stage after calculation.
*/
- this.forceLandscape = false;
+ this.width = width;
/**
- * @property {boolean} forcePortrait - If the game should be forced to use Portrait mode, this is set to true by Game.Stage
- * @default
+ * @property {number} height - Height of the stage after calculation.
*/
- this.forcePortrait = false;
-
- /**
- * @property {boolean} incorrectOrientation - If the game should be forced to use a specific orientation and the device currently isn't in that orientation this is set to true.
- * @default
- */
- this.incorrectOrientation = false;
-
- /**
- * @property {boolean} pageAlignHorizontally - If you wish to align your game in the middle of the page then you can set this value to true.
-
It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.
-
It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.
- * @default
- */
- this.pageAlignHorizontally = false;
-
- /**
- * @property {boolean} pageAlignVertically - If you wish to align your game in the middle of the page then you can set this value to true.
-
It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.
-
It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.
@@ -864,7 +868,7 @@ Phaser.Animation.generateFrameNames = function (prefix, start, stop, suffix, zer
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:08 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:33 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/AnimationManager.js.html b/docs/AnimationManager.js.html
index 9835eb67..4c9a95a2 100644
--- a/docs/AnimationManager.js.html
+++ b/docs/AnimationManager.js.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -640,6 +644,27 @@ Phaser.AnimationManager.prototype = {
},
+ /**
+ * Returns an animation that was previously added by name.
+ *
+ * @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.
+ */
+ getAnimation: function (name) {
+
+ if (typeof name == 'string')
+ {
+ if (this._anims[name])
+ {
+ return this._anims[name];
+ }
+ }
+
+ return false;
+
+ },
+
/**
* Refreshes the current frame data back to the parent Sprite and also resets the texture data.
*
@@ -804,7 +829,7 @@ Object.defineProperty(Phaser.AnimationManager.prototype, "frameName", {
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:08 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:33 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/AnimationParser.js.html b/docs/AnimationParser.js.html
index 4440a4cc..e5234ffa 100644
--- a/docs/AnimationParser.js.html
+++ b/docs/AnimationParser.js.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -470,6 +474,36 @@ Phaser.Group = function (game, parent, name, useStage) {
};
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Group.RETURN_NONE = 0;
+
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Group.RETURN_TOTAL = 1;
+
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Group.RETURN_CHILD = 2;
+
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Group.SORT_ASCENDING = -1;
+
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Group.SORT_DESCENDING = 1;
+
Phaser.Group.prototype = {
/**
@@ -682,8 +716,48 @@ Phaser.Group.prototype = {
},
+ 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);
+
+ },
+
+ swapIndex: function (index1, index2) {
+
+ var child1 = this.getAt(index1);
+ var child2 = this.getAt(index2);
+
+ console.log('swapIndex ', index1, ' with ', index2);
+
+ this.swap(child1, child2);
+
+ },
+
/**
- * Swaps the position of two children in this Group.
+ * 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.
@@ -692,9 +766,8 @@ Phaser.Group.prototype = {
*/
swap: function (child1, child2) {
- if (child1 === child2 || !child1.parent || !child2.parent)
+ if (child1 === child2 || !child1.parent || !child2.parent || child1.group !== this || child2.group !== this)
{
- console.warn('You cannot swap a child with itself or swap un-parented children');
return false;
}
@@ -766,7 +839,7 @@ Phaser.Group.prototype = {
child2._iPrev = child1;
if (child2Prev) { child2Prev._iNext = child1; }
- if (child1Next) { child2Next._iPrev = child2; }
+ if (child1Next) { child1Next._iPrev = child2; }
if (child1.__renderGroup)
{
@@ -1133,7 +1206,7 @@ Phaser.Group.prototype = {
/**
* 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 you can add as many extra parameters as you like, which will all be passed to the child.
+ * 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.
@@ -1239,6 +1312,24 @@ Phaser.Group.prototype = {
},
+ /**
+ * 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.
@@ -1253,23 +1344,7 @@ Phaser.Group.prototype = {
var args = Array.prototype.splice.call(arguments, 2);
args.unshift(null);
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.alive)
- {
- args[0] = currentNode;
- callback.apply(callbackContext, args);
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
-
- }
+ this.iterate('alive', true, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
},
@@ -1287,23 +1362,121 @@ Phaser.Group.prototype = {
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').
+ */
+ iterate: function (key, value, returnType, callback, callbackContext, args) {
+
+ if (returnType == Phaser.Group.RETURN_TOTAL && this._container.children.length == 0)
+ {
+ return -1;
+ }
+
+ 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.alive == false)
+ if (currentNode[key] === value)
{
- args[0] = currentNode;
- callback.apply(callbackContext, args);
+ 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;
+ }
+
},
/**
@@ -1320,23 +1493,7 @@ Phaser.Group.prototype = {
state = true;
}
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.exists === state)
- {
- return currentNode;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
-
- return null;
+ return this.iterate('exists', state, Phaser.Group.RETURN_CHILD);
},
@@ -1349,23 +1506,7 @@ Phaser.Group.prototype = {
*/
getFirstAlive: function () {
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.alive)
- {
- return currentNode;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
-
- return null;
+ return this.iterate('alive', true, Phaser.Group.RETURN_CHILD);
},
@@ -1378,23 +1519,7 @@ Phaser.Group.prototype = {
*/
getFirstDead: function () {
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (!currentNode.alive)
- {
- return currentNode;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
-
- return null;
+ return this.iterate('alive', false, Phaser.Group.RETURN_CHILD);
},
@@ -1406,29 +1531,7 @@ Phaser.Group.prototype = {
*/
countLiving: function () {
- var total = 0;
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.alive)
- {
- total++;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
- else
- {
- total = -1;
- }
-
- return total;
+ return this.iterate('alive', true, Phaser.Group.RETURN_TOTAL);
},
@@ -1440,29 +1543,7 @@ Phaser.Group.prototype = {
*/
countDead: function () {
- var total = 0;
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (!currentNode.alive)
- {
- total++;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
- else
- {
- total = -1;
- }
-
- return total;
+ return this.iterate('alive', false, Phaser.Group.RETURN_TOTAL);
},
@@ -1607,6 +1688,48 @@ Phaser.Group.prototype = {
},
+ 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;
+
+ },
+
/**
* Dumps out a list of Group children and their index positions to the browser console. Useful for group debugging.
*
@@ -1713,7 +1836,8 @@ Phaser.Group.prototype = {
Object.defineProperty(Phaser.Group.prototype, "total", {
get: function () {
- return this._container.children.length;
+ return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
+ // return this._container.children.length;
}
});
@@ -1726,7 +1850,8 @@ Object.defineProperty(Phaser.Group.prototype, "total", {
Object.defineProperty(Phaser.Group.prototype, "length", {
get: function () {
- return this._container.children.length;
+ return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
+ // return this._container.children.length;
}
});
@@ -1855,7 +1980,7 @@ Object.defineProperty(Phaser.Group.prototype, "alpha", {
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:08 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:33 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Input.js.html b/docs/Input.js.html
index d5f1506f..aa9b7b2a 100644
--- a/docs/Input.js.html
+++ b/docs/Input.js.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -784,28 +788,60 @@ Phaser.InputHandler.prototype = {
/**
* Is the Pointer over this Sprite?
* @method Phaser.InputHandler#pointerOver
- * @param {Pointer} pointer
- * @return {bool
+ * @param {number} [index] - The ID number of a Pointer to check. If you don't provide a number it will check all Pointers.
+ * @return {boolean} True if the given pointer (if a index was given, or any pointer if not) is over this object.
*/
- pointerOver: function (pointer) {
+ pointerOver: function (index) {
- pointer = pointer || 0;
+ if (this.enabled)
+ {
+ if (typeof index === 'undefined')
+ {
+ for (var i = 0; i < 10; i++)
+ {
+ if (this._pointerData[i].isOver)
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ return this._pointerData[index].isOver;
+ }
+ }
- return this._pointerData[pointer].isOver;
+ return false;
},
/**
* Is the Pointer outside of this Sprite?
* @method Phaser.InputHandler#pointerOut
- * @param {Pointer} pointer
- * @return {boolean}
+ * @param {number} [index] - The ID number of a Pointer to check. If you don't provide a number it will check all Pointers.
+ * @return {boolean} True if the given pointer (if a index was given, or any pointer if not) is out of this object.
*/
pointerOut: function (pointer) {
- pointer = pointer || 0;
+ if (this.enabled)
+ {
+ if (typeof index === 'undefined')
+ {
+ for (var i = 0; i < 10; i++)
+ {
+ if (this._pointerData[i].isOut)
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ return this._pointerData[index].isOut;
+ }
+ }
- return this._pointerData[pointer].isOut;
+ return false;
},
@@ -881,12 +917,13 @@ Phaser.InputHandler.prototype = {
},
/**
- * Description.
- * @method Phaser.InputHandler#checkPixel
- * @param {Description} x - Description.
- * @param {Description} y - Description.
- * @return {boolean}
- */
+ * Runs a pixel perfect check against the given x/y coordinates of the Sprite this InputHandler is bound to.
+ * It compares the alpha value of the pixel and if >= InputHandler.pixelPerfectAlpha it returns true.
+ * @method Phaser.InputHandler#checkPixel
+ * @param {number} x - The x coordinate to check.
+ * @param {number} y - The y coordinate to check.
+ * @return {boolean} true if there is the alpha of the pixel is >= InputHandler.pixelPerfectAlpha
+ */
checkPixel: function (x, y) {
// Grab a pixel from our image into the hitCanvas and then test it
@@ -894,8 +931,6 @@ Phaser.InputHandler.prototype = {
{
this.game.input.hitContext.clearRect(0, 0, 1, 1);
- // This will fail if the image is part of a texture atlas - need to modify the x/y values here
-
x += this.sprite.texture.frame.x;
y += this.sprite.texture.frame.y;
@@ -1452,7 +1487,7 @@ Phaser.InputHandler.prototype = {
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:08 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:33 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/IntroDocs.js.html b/docs/IntroDocs.js.html
index 6c32b017..4cd57b7d 100644
--- a/docs/IntroDocs.js.html
+++ b/docs/IntroDocs.js.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -2871,7 +2875,7 @@ You could use this function to generate those by doing: Phaser.Animation.generat
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:09 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:34 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.AnimationManager.html b/docs/Phaser.AnimationManager.html
index 874564cd..dc5bd53f 100644
--- a/docs/Phaser.AnimationManager.html
+++ b/docs/Phaser.AnimationManager.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -2780,7 +2928,7 @@ The currentAnim property of the AnimationManager is automatically set to the ani
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:09 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:34 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.AnimationParser.html b/docs/Phaser.AnimationParser.html
index 91609250..8c442175 100644
--- a/docs/Phaser.AnimationParser.html
+++ b/docs/Phaser.AnimationParser.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -1545,7 +1549,7 @@ On OS X we recommend Glyph Designer:
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:09 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:34 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Button.html b/docs/Phaser.Button.html
index 0ce4a260..fc107494 100644
--- a/docs/Phaser.Button.html
+++ b/docs/Phaser.Button.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -3970,7 +4083,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 Fri Nov 01 2013 18:16:09 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:34 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Cache.html b/docs/Phaser.Cache.html
index 6dfde218..b6fb91c5 100644
--- a/docs/Phaser.Cache.html
+++ b/docs/Phaser.Cache.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -6870,7 +6874,7 @@ Normally you don't call this directly but instead use getImageKeys, getSoundKeys
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:09 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:34 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Camera.html b/docs/Phaser.Camera.html
index 930de0ad..5a501c95 100644
--- a/docs/Phaser.Camera.html
+++ b/docs/Phaser.Camera.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -3220,7 +3224,7 @@ without having to use game.camera.x and game.camera.y.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:09 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:34 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Canvas.html b/docs/Phaser.Canvas.html
index 70c501fd..d4f9fe2c 100644
--- a/docs/Phaser.Canvas.html
+++ b/docs/Phaser.Canvas.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -2464,7 +2468,7 @@ patchy on earlier browsers, especially on mobile.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:09 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:34 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Circle.html b/docs/Phaser.Circle.html
index 2ba740c4..8cbcbbbe 100644
--- a/docs/Phaser.Circle.html
+++ b/docs/Phaser.Circle.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -4244,7 +4248,7 @@ This method checks the radius distances between the two Circle objects to see if
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:10 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:35 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Color.html b/docs/Phaser.Color.html
index 5f108429..965c2f08 100644
--- a/docs/Phaser.Color.html
+++ b/docs/Phaser.Color.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -3573,7 +3577,7 @@ RGB format information and HSL information. Each section starts on a newline, 3
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:10 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:35 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Device.html b/docs/Phaser.Device.html
index c9809d4a..afa3b307 100644
--- a/docs/Phaser.Device.html
+++ b/docs/Phaser.Device.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -1857,7 +1861,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 Fri Nov 01 2013 18:16:11 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:36 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Game.html b/docs/Phaser.Game.html
index efe4da3d..897b6586 100644
--- a/docs/Phaser.Game.html
+++ b/docs/Phaser.Game.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -4616,7 +4620,7 @@ When a game is paused the onPause event is dispatched. When it is resumed the on
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:11 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:36 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.GameObjectFactory.html b/docs/Phaser.GameObjectFactory.html
index fe15f340..e4e143a7 100644
--- a/docs/Phaser.GameObjectFactory.html
+++ b/docs/Phaser.GameObjectFactory.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -4130,7 +4134,7 @@ at set intervals, and fixes their positions and velocities accorindgly.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:11 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:36 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Graphics.html b/docs/Phaser.Graphics.html
index 9074ef47..953c4c50 100644
--- a/docs/Phaser.Graphics.html
+++ b/docs/Phaser.Graphics.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -2774,7 +3078,7 @@ The child is added to the Group at the location specified by the index value, th
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 you can add as many extra parameters as you like, which will all be passed to the child.
+After the method parameter and context you can add as many extra parameters as you like, which will all be passed to the child.
@@ -2948,7 +3252,7 @@ After the method parameter you can add as many extra parameters as you like, whi
Allows you to call your own function on each alive member of this Group (where child.alive=true). You must pass the callback and context in which it will run.
+You can add as many parameters as you like, which will all be passed to the callback along with the child.
+For example: Group.forEachAlive(causeDamage, this, 500)
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
callback
+
+
+
+
+
+function
+
+
+
+
+
+
+
+
+
+
The function that will be called. Each child of the Group will be passed to it as its first parameter.
+
+
+
+
+
+
+
callbackContext
+
+
+
+
+
+Object
+
+
+
+
+
+
+
+
+
+
The context in which the function should be called (usually 'this').
Iterates over the children of the Group. When a child has a property matching key that equals the given value, it is considered as a match.
+Matched children can be sent to the optional callback, or simply returned or counted.
+You can add as many callback parameters as you like, which will all be passed to the callback along with the child, after the callbackContext parameter.
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
key
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The child property to check, i.e. 'exists', 'alive', 'health'
+
+
+
+
+
+
+
value
+
+
+
+
+
+any
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
If child.key === this value it will be considered a match. Note that a strict comparison is used.
+
+
+
+
+
+
+
returnType
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
How to return the data from this method. Either Phaser.Group.RETURN_NONE, Phaser.Group.RETURN_TOTAL or Phaser.Group.RETURN_CHILD.
+
+
+
+
+
+
+
callback
+
+
+
+
+
+function
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ null
+
+
+
+
+
Optional function that will be called on each matching child. Each child of the Group will be passed to it as its first parameter.
+
+
+
+
+
+
+
callbackContext
+
+
+
+
+
+Object
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The context in which the function should be called (usually 'this').
Call this function to sort the group according to a particular value and order.
+For example to depth sort Sprites for Zelda-style game you might call group.sort('y', Phaser.Group.SORT_ASCENDING) at the bottom of your State.update().
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
index
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ 'y'
+
+
+
+
+
The string name of the property you want to sort on.
+
+
+
+
+
+
+
order
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ Phaser.Group.SORT_ASCENDING
+
+
+
+
+
The Group constant that defines the sort order. Possible values are Phaser.Group.SORT_ASCENDING and Phaser.Group.SORT_DESCENDING.
@@ -7216,7 +8123,8 @@ Group.subAll('x', 10) will minus 10 from the child.x value.
-
Swaps the position of two children in this Group.
+
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.
@@ -7321,7 +8229,7 @@ Group.subAll('x', 10) will minus 10 from the child.x value.
@@ -7395,7 +8303,7 @@ Group.subAll('x', 10) will minus 10 from the child.x value.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:12 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:37 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Input.html b/docs/Phaser.Input.html
index dbcf6212..a132e7f6 100644
--- a/docs/Phaser.Input.html
+++ b/docs/Phaser.Input.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -7270,7 +7274,7 @@ If you need more then use this to create a new one, up to a maximum of 10.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:12 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:37 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.InputHandler.html b/docs/Phaser.InputHandler.html
index 1807f2f7..2627c7d7 100644
--- a/docs/Phaser.InputHandler.html
+++ b/docs/Phaser.InputHandler.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -3298,7 +3302,8 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
-
Description.
+
Runs a pixel perfect check against the given x/y coordinates of the Sprite this InputHandler is bound to.
+It compares the alpha value of the pixel and if >= InputHandler.pixelPerfectAlpha it returns true.
@@ -3338,7 +3343,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
-Description
+number
@@ -3348,7 +3353,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
-
Description.
+
The x coordinate to check.
@@ -3361,7 +3366,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
-Description
+number
@@ -3371,7 +3376,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
-
Description.
+
The y coordinate to check.
@@ -3403,7 +3408,7 @@ For example if you had a stack of 6 sprites with the same priority IDs and one c
@@ -7445,7 +7494,7 @@ This value is only set when the pointer is over this Sprite.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:12 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:37 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Key.html b/docs/Phaser.Key.html
index 206d4fea..f11cdd48 100644
--- a/docs/Phaser.Key.html
+++ b/docs/Phaser.Key.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -2492,7 +2496,7 @@ If the key is up it holds the duration of the previous down session.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:12 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:37 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Keyboard.html b/docs/Phaser.Keyboard.html
index a81a8f6e..900b3eb2 100644
--- a/docs/Phaser.Keyboard.html
+++ b/docs/Phaser.Keyboard.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -2919,7 +2923,7 @@ This is called automatically by Phaser.Input and should not normally be invoked
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:12 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:37 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.LinkedList.html b/docs/Phaser.LinkedList.html
index 5559cd17..ea3e575e 100644
--- a/docs/Phaser.LinkedList.html
+++ b/docs/Phaser.LinkedList.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -1411,7 +1415,7 @@ The function must exist on the member.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:12 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:37 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Loader.html b/docs/Phaser.Loader.html
index 7e09d445..43c90d7e 100644
--- a/docs/Phaser.Loader.html
+++ b/docs/Phaser.Loader.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -5881,7 +5885,7 @@ This allows you to easily make loading bars for games.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:12 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:37 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.LoaderParser.html b/docs/Phaser.LoaderParser.html
index 810d294a..96eaeadb 100644
--- a/docs/Phaser.LoaderParser.html
+++ b/docs/Phaser.LoaderParser.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -1676,7 +1680,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 Fri Nov 01 2013 18:16:13 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:38 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Math.html b/docs/Phaser.Math.html
index bb997bae..97ffb3c2 100644
--- a/docs/Phaser.Math.html
+++ b/docs/Phaser.Math.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -10142,7 +10146,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 Fri Nov 01 2013 18:16:13 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:38 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Mouse.html b/docs/Phaser.Mouse.html
index f70b4fe1..d676a68d 100644
--- a/docs/Phaser.Mouse.html
+++ b/docs/Phaser.Mouse.html
@@ -242,6 +242,10 @@
Pointer
+
If the browser supports it you can request that the pointer be locked to the browser window.
+This is classically known as 'FPS controls', where the pointer can't leave the browser until the user presses an exit key.
+If the browser successfully enters a locked state the event Phaser.Mouse.pointerLock will be dispatched and the first parameter will be 'true'.
@@ -1301,7 +1305,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 Fri Nov 01 2013 18:16:13 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:38 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Particles.Arcade.Emitter.html b/docs/Phaser.Particles.Arcade.Emitter.html
index 256cb53b..97066777 100644
--- a/docs/Phaser.Particles.Arcade.Emitter.html
+++ b/docs/Phaser.Particles.Arcade.Emitter.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -5626,7 +5630,7 @@ The child is added to the Group at the location specified by the index value, th
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 you can add as many extra parameters as you like, which will all be passed to the child.
+After the method parameter and context you can add as many extra parameters as you like, which will all be passed to the child.
@@ -5805,7 +5809,7 @@ After the method parameter you can add as many extra parameters as you like, whi
Allows you to call your own function on each alive member of this Group (where child.alive=true). You must pass the callback and context in which it will run.
+You can add as many parameters as you like, which will all be passed to the callback along with the child.
+For example: Group.forEachAlive(causeDamage, this, 500)
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
+
+
+
Description
+
+
+
+
+
+
+
+
+
callback
+
+
+
+
+
+function
+
+
+
+
+
+
+
+
+
+
The function that will be called. Each child of the Group will be passed to it as its first parameter.
+
+
+
+
+
+
+
callbackContext
+
+
+
+
+
+Object
+
+
+
+
+
+
+
+
+
+
The context in which the function should be called (usually 'this').
Iterates over the children of the Group. When a child has a property matching key that equals the given value, it is considered as a match.
+Matched children can be sent to the optional callback, or simply returned or counted.
+You can add as many callback parameters as you like, which will all be passed to the callback along with the child, after the callbackContext parameter.
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
key
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The child property to check, i.e. 'exists', 'alive', 'health'
+
+
+
+
+
+
+
value
+
+
+
+
+
+any
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
If child.key === this value it will be considered a match. Note that a strict comparison is used.
+
+
+
+
+
+
+
returnType
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
How to return the data from this method. Either Phaser.Group.RETURN_NONE, Phaser.Group.RETURN_TOTAL or Phaser.Group.RETURN_CHILD.
+
+
+
+
+
+
+
callback
+
+
+
+
+
+function
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ null
+
+
+
+
+
Optional function that will be called on each matching child. Each child of the Group will be passed to it as its first parameter.
+
+
+
+
+
+
+
callbackContext
+
+
+
+
+
+Object
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
The context in which the function should be called (usually 'this').
@@ -11000,6 +11439,189 @@ The operation parameter controls how the new value is assigned to the property,
+
+
+
+
+
+
sort(index, order)
+
+
+
+
+
+
+
+
Call this function to sort the group according to a particular value and order.
+For example to depth sort Sprites for Zelda-style game you might call group.sort('y', Phaser.Group.SORT_ASCENDING) at the bottom of your State.update().
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
index
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ 'y'
+
+
+
+
+
The string name of the property you want to sort on.
+
+
+
+
+
+
+
order
+
+
+
+
+
+number
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ Phaser.Group.SORT_ASCENDING
+
+
+
+
+
The Group constant that defines the sort order. Possible values are Phaser.Group.SORT_ASCENDING and Phaser.Group.SORT_DESCENDING.
@@ -11393,7 +12015,8 @@ Group.subAll('x', 10) will minus 10 from the child.x value.
-
Swaps the position of two children in this Group.
+
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.
@@ -11503,7 +12126,7 @@ Group.subAll('x', 10) will minus 10 from the child.x value.
@@ -11646,7 +12269,7 @@ Group.subAll('x', 10) will minus 10 from the child.x value.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:13 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:38 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Particles.html b/docs/Phaser.Particles.html
index 5aff66c8..1afe0077 100644
--- a/docs/Phaser.Particles.html
+++ b/docs/Phaser.Particles.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -6100,7 +6104,7 @@ touching.up = true means the collision happened to the top of this Body for exam
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:13 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:39 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Physics.Arcade.html b/docs/Phaser.Physics.Arcade.html
index 5910418c..d5441c71 100644
--- a/docs/Phaser.Physics.Arcade.html
+++ b/docs/Phaser.Physics.Arcade.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -7595,7 +7599,7 @@ One way to use this is: velocityFromRotation(rotation, 200, sprite.velocity) whi
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:13 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:39 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Physics.html b/docs/Phaser.Physics.html
index 884d3607..344a63a6 100644
--- a/docs/Phaser.Physics.html
+++ b/docs/Phaser.Physics.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -1763,7 +1872,7 @@ It is only called if active is set to true.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:14 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:39 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.PluginManager.html b/docs/Phaser.PluginManager.html
index 80c95fbb..43b491e6 100644
--- a/docs/Phaser.PluginManager.html
+++ b/docs/Phaser.PluginManager.html
@@ -242,6 +242,10 @@
Pointer
+
PostUpdate is the last thing to be called before the world render.
+In particular, it is called after the world postUpdate, which means the camera has been adjusted.
+It only calls plugins who have active=true.
@@ -1393,7 +1468,7 @@ It only calls plugins who have active=true.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:14 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:39 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Point.html b/docs/Phaser.Point.html
index a729ca09..dc2d5994 100644
--- a/docs/Phaser.Point.html
+++ b/docs/Phaser.Point.html
@@ -242,6 +242,10 @@
Pointer
+
The polygon represents a list of orderded points in space
+
+
+
+
+
+
+
+
+
+
+
new Polygon(points)
+
+
+
+
+
+
+
+
Creates a new Polygon. You have to provide a list of points.
+This can be an array of Points that form the polygon, a flat array of numbers that will be interpreted as [x,y, x,y, ...],
+or the arguments passed can be all the points of the polygon e.g. new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...), or the
+arguments passed can be flat x,y values e.g. new PIXI.Polygon(x,y, x,y, x,y, ...) where x and y are numbers.
@@ -1262,7 +1266,7 @@ Split the node into 4 subnodes
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:14 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:39 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.RandomDataGenerator.html b/docs/Phaser.RandomDataGenerator.html
index 872ff576..df270b8e 100644
--- a/docs/Phaser.RandomDataGenerator.html
+++ b/docs/Phaser.RandomDataGenerator.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -1955,7 +1959,7 @@ Random number generator from
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:14 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:39 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Rectangle.html b/docs/Phaser.Rectangle.html
index eb699bdc..41f3c612 100644
--- a/docs/Phaser.Rectangle.html
+++ b/docs/Phaser.Rectangle.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -7340,7 +7344,7 @@ This method checks the x, y, width, and height properties of the Rectangles.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:14 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.RenderTexture.html b/docs/Phaser.RenderTexture.html
index 4f820fd1..c68ae97d 100644
--- a/docs/Phaser.RenderTexture.html
+++ b/docs/Phaser.RenderTexture.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -1341,7 +1345,7 @@ once they update pixi to fix the typo, we'll fix it here too :)
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:14 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.RequestAnimationFrame.html b/docs/Phaser.RequestAnimationFrame.html
index 3e8dbe20..3acb8c90 100644
--- a/docs/Phaser.RequestAnimationFrame.html
+++ b/docs/Phaser.RequestAnimationFrame.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -5683,7 +5687,7 @@ This allows you to bundle multiple sounds together into a single audio file and
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:15 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.SoundManager.html b/docs/Phaser.SoundManager.html
index da4f87c0..23a45eb9 100644
--- a/docs/Phaser.SoundManager.html
+++ b/docs/Phaser.SoundManager.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -7423,7 +7427,7 @@ It will dispatch the onRevived event, you can listen to Sprite.events.onRevived
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:15 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Stage.html b/docs/Phaser.Stage.html
index 7f02fc8f..feb13f8c 100644
--- a/docs/Phaser.Stage.html
+++ b/docs/Phaser.Stage.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -1616,7 +1620,7 @@ focus handling, game resizing, scaling and the pause, boot and orientation scree
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:15 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.StageScaleMode.html b/docs/Phaser.StageScaleMode.html
index 00663b7d..84070174 100644
--- a/docs/Phaser.StageScaleMode.html
+++ b/docs/Phaser.StageScaleMode.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -2472,8 +2581,8 @@ If null it will scale to whatever width the browser can handle.
If you wish to align your game in the middle of the page then you can set this value to true.
- <ul><li>It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.</li>
- <li>It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.</li></ul>
+It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.
+It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.
@@ -2505,7 +2614,7 @@ If null it will scale to whatever width the browser can handle.
@@ -2579,8 +2688,8 @@ If null it will scale to whatever width the browser can handle.
If you wish to align your game in the middle of the page then you can set this value to true.
- <ul><li>It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.
- <li>It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.</li></ul>
+It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.
+It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.
@@ -2612,7 +2721,7 @@ If null it will scale to whatever width the browser can handle.
If you need your game to run in only one orientation you can force that to happen.
+The optional orientationImage is displayed when the game is in the incorrect orientation.
+
+
+
+
+
+
+
+
+
Parameters:
+
+
+
+
+
+
+
Name
+
+
+
Type
+
+
+
Argument
+
+
+
+
Default
+
+
+
Description
+
+
+
+
+
+
+
+
+
forceLandscape
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
true if the game should run in landscape mode only.
+
+
+
+
+
+
+
forcePortrait
+
+
+
+
+
+boolean
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
true if the game should run in portrait mode only.
+
+
+
+
+
+
+
forcePortrait
+
+
+
+
+
+string
+
+
+
+
+
+
+
+
+ <optional>
+
+
+
+
+
+
+
+
+
+
+
+ ''
+
+
+
+
+
The string of an image in the Phaser.Cache to display when this game is in the incorrect orientation.
@@ -3937,7 +4255,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 Fri Nov 01 2013 18:16:15 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:40 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.State.html b/docs/Phaser.State.html
index b34f2dfc..89d67faf 100644
--- a/docs/Phaser.State.html
+++ b/docs/Phaser.State.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -2530,7 +2534,7 @@ If you need to use the loader, you may need to use them here.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:15 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.StateManager.html b/docs/Phaser.StateManager.html
index c3e08086..44cdfb7a 100644
--- a/docs/Phaser.StateManager.html
+++ b/docs/Phaser.StateManager.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -2502,7 +2506,7 @@ Doesn't appear to be supported by most browsers on a canvas element yet.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:16 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Tween.html b/docs/Phaser.Tween.html
index c3c29b65..f7a6d3a6 100644
--- a/docs/Phaser.Tween.html
+++ b/docs/Phaser.Tween.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -3208,7 +3212,7 @@ Used in combination with repeat you can create endless loops.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:16 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.TweenManager.html b/docs/Phaser.TweenManager.html
index 034ee148..060bc355 100644
--- a/docs/Phaser.TweenManager.html
+++ b/docs/Phaser.TweenManager.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -1705,7 +1709,7 @@ Please see https://github.com/sole/tw
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:16 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Utils.Debug.html b/docs/Phaser.Utils.Debug.html
index 98af9a88..462a039e 100644
--- a/docs/Phaser.Utils.Debug.html
+++ b/docs/Phaser.Utils.Debug.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -5917,7 +5921,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 Fri Nov 01 2013 18:16:16 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:41 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.Utils.html b/docs/Phaser.Utils.html
index febf8b85..403d0ae1 100644
--- a/docs/Phaser.Utils.html
+++ b/docs/Phaser.Utils.html
@@ -242,6 +242,10 @@
Pointer
+
Javascript string pad http://www.webtoolkit.info/.
-pad = the string to pad it out with (defaults to a space)<br>
+pad = the string to pad it out with (defaults to a space)
dir = 1 (left), 2 (right), 3 (both)
@@ -2051,7 +2157,7 @@ If you need to adjust the bounds of the world
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:16 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:42 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Phaser.html b/docs/Phaser.html
index c36dfd2c..82c96a5d 100644
--- a/docs/Phaser.html
+++ b/docs/Phaser.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -429,6 +433,12 @@ Phaser.Plugin = function (game, parent) {
* @default
*/
this.hasUpdate = false;
+
+ /**
+ * @property {boolean} hasPostUpdate - A flag to indicate if this plugin has a postUpdate method.
+ * @default
+ */
+ this.hasPostUpdate = false;
/**
* @property {boolean} hasRender - A flag to indicate if this plugin has a render method.
@@ -513,7 +523,7 @@ Phaser.Plugin.prototype = {
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:08 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:33 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/PluginManager.js.html b/docs/PluginManager.js.html
index a31f2053..43e8e8bd 100644
--- a/docs/PluginManager.js.html
+++ b/docs/PluginManager.js.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -456,6 +460,12 @@ Phaser.PluginManager.prototype = {
result = true;
}
+ if (typeof plugin['postUpdate'] === 'function')
+ {
+ plugin.hasPostUpdate = true;
+ result = true;
+ }
+
if (typeof plugin['render'] === 'function')
{
plugin.hasRender = true;
@@ -555,6 +565,30 @@ Phaser.PluginManager.prototype = {
},
+ /**
+ * PostUpdate is the last thing to be called before the world render.
+ * In particular, it is called after the world postUpdate, which means the camera has been adjusted.
+ * It only calls plugins who have active=true.
+ *
+ * @method Phaser.PluginManager#postUpdate
+ */
+ postUpdate: function () {
+
+ if (this._pluginsLength == 0)
+ {
+ return;
+ }
+
+ for (this._p = 0; this._p < this._pluginsLength; this._p++)
+ {
+ if (this.plugins[this._p].active && this.plugins[this._p].hasPostUpdate)
+ {
+ this.plugins[this._p].postUpdate();
+ }
+ }
+
+ },
+
/**
* Render is called right after the Game Renderer completes, but before the State.render.
* It only calls plugins who have visible=true.
@@ -637,7 +671,7 @@ Phaser.PluginManager.prototype = {
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:08 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:33 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/Point.js.html b/docs/Point.js.html
index 652d3da0..133fb268 100644
--- a/docs/Point.js.html
+++ b/docs/Point.js.html
@@ -242,6 +242,10 @@
Pointer
+
/**
+* @author Richard Davey <rich@photonstorm.com>
+* @copyright 2013 Photon Storm Ltd.
+* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
+*/
+
+/**
+* Creates a new Polygon. You have to provide a list of points.
+* This can be an array of Points that form the polygon, a flat array of numbers that will be interpreted as [x,y, x,y, ...],
+* or the arguments passed can be all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the
+* arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are numbers.
+*
+* @class Phaser.Polygon
+* @classdesc The polygon represents a list of orderded points in space
+* @constructor
+* @param {Array<Phaser.Point>|Array<number>} points - The array of Points.
+*/
+Phaser.Polygon = function (points) {
+
+ PIXI.Polygon.call(this, points);
+
+ /**
+ * @property {number} type - The base object type.
+ */
+ this.type = Phaser.POLYGON;
+
+};
+
+Phaser.Polygon.prototype = Object.create(PIXI.Polygon.prototype);
+Phaser.Polygon.prototype.constructor = Phaser.Polygon;
@@ -396,45 +400,19 @@
Phaser.StageScaleMode = function (game, width, height) {
/**
- * @property {number} _startHeight - Stage height when starting the game.
- * @default
- * @private
+ * @property {Phaser.Game} game - A reference to the currently running game.
*/
- this._startHeight = 0;
+ this.game = game;
/**
- * @property {boolean} forceLandscape - If the game should be forced to use Landscape mode, this is set to true by Game.Stage
- * @default
+ * @property {number} width - Width of the stage after calculation.
*/
- this.forceLandscape = false;
+ this.width = width;
/**
- * @property {boolean} forcePortrait - If the game should be forced to use Portrait mode, this is set to true by Game.Stage
- * @default
+ * @property {number} height - Height of the stage after calculation.
*/
- this.forcePortrait = false;
-
- /**
- * @property {boolean} incorrectOrientation - If the game should be forced to use a specific orientation and the device currently isn't in that orientation this is set to true.
- * @default
- */
- this.incorrectOrientation = false;
-
- /**
- * @property {boolean} pageAlignHorizontally - If you wish to align your game in the middle of the page then you can set this value to true.
- <ul><li>It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.</li>
- <li>It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.</li></ul>
- * @default
- */
- this.pageAlignHorizontally = false;
-
- /**
- * @property {boolean} pageAlignVertically - If you wish to align your game in the middle of the page then you can set this value to true.
- <ul><li>It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.
- <li>It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.</li></ul>
- * @default
- */
- this.pageAlignVertically = false;
+ this.height = height;
/**
* @property {number} minWidth - Minimum width the canvas should be scaled to (in pixels).
@@ -463,14 +441,45 @@ Phaser.StageScaleMode = function (game, width, height) {
this.maxHeight = null;
/**
- * @property {number} width - Width of the stage after calculation.
+ * @property {number} _startHeight - Stage height when starting the game.
+ * @default
+ * @private
*/
- this.width = width;
+ this._startHeight = 0;
/**
- * @property {number} height - Height of the stage after calculation.
+ * @property {boolean} forceLandscape - If the game should be forced to use Landscape mode, this is set to true by Game.Stage
+ * @default
*/
- this.height = height;
+ this.forceLandscape = false;
+
+ /**
+ * @property {boolean} forcePortrait - If the game should be forced to use Portrait mode, this is set to true by Game.Stage
+ * @default
+ */
+ this.forcePortrait = false;
+
+ /**
+ * @property {boolean} incorrectOrientation - If the game should be forced to use a specific orientation and the device currently isn't in that orientation this is set to true.
+ * @default
+ */
+ this.incorrectOrientation = false;
+
+ /**
+ * @property {boolean} pageAlignHorizontally - If you wish to align your game in the middle of the page then you can set this value to true.
+ * It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.
+ * It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.
+ * @default
+ */
+ this.pageAlignHorizontally = false;
+
+ /**
+ * @property {boolean} pageAlignVertically - If you wish to align your game in the middle of the page then you can set this value to true.
+ * It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.
+ * It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.
+ * @default
+ */
+ this.pageAlignVertically = false;
/**
* @property {number} _width - Cached stage width for full screen mode.
@@ -492,18 +501,20 @@ Phaser.StageScaleMode = function (game, width, height) {
*/
this.maxIterations = 5;
- /**
- * @property {Phaser.Game} game - A reference to the currently running game.
- */
- this.game = game;
/**
- * @property {Description} enterLandscape - Description.
+ * @property {PIXI.Sprite} orientationSprite - The Sprite that is optionally displayed if the browser enters an unsupported orientation.
+ * @default
+ */
+ this.orientationSprite = null;
+
+ /**
+ * @property {Phaser.Signal} enterLandscape - The event that is dispatched when the browser enters landscape orientation.
*/
this.enterLandscape = new Phaser.Signal();
/**
- * @property {Description} enterPortrait - Description.
+ * @property {Phaser.Signal} enterPortrait - The event that is dispatched when the browser enters horizontal orientation.
*/
this.enterPortrait = new Phaser.Signal();
@@ -524,7 +535,7 @@ Phaser.StageScaleMode = function (game, width, height) {
}
/**
- * @property {Description} scaleFactor - Description.
+ * @property {Phaser.Point} scaleFactor - The scale factor based on the game dimensions vs. the scaled dimensions.
*/
this.scaleFactor = new Phaser.Point(1, 1);
@@ -677,6 +688,54 @@ Phaser.StageScaleMode.prototype = {
},
+ /**
+ * If you need your game to run in only one orientation you can force that to happen.
+ * The optional orientationImage is displayed when the game is in the incorrect orientation.
+ * @method Phaser.StageScaleMode#forceOrientation
+ * @param {boolean} forceLandscape - true if the game should run in landscape mode only.
+ * @param {boolean} forcePortrait - true if the game should run in portrait mode only.
+ * @param {string} [forcePortrait=''] - The string of an image in the Phaser.Cache to display when this game is in the incorrect orientation.
+ */
+ forceOrientation: function (forceLandscape, forcePortrait, orientationImage) {
+
+ this.forceLandscape = forceLandscape;
+
+ if (typeof forcePortrait === 'undefined')
+ {
+ this.forcePortrait = false;
+ }
+
+ if (typeof orientationImage !== 'undefined')
+ {
+ if (orientationImage == null || this.game.cache.checkImageKey(orientationImage) == false)
+ {
+ orientationImage = '__default';
+ }
+
+ this.orientationSprite = new PIXI.Sprite(PIXI.TextureCache[orientationImage]);
+ this.orientationSprite.anchor.x = 0.5;
+ this.orientationSprite.anchor.y = 0.5;
+ this.orientationSprite.position.x = this.game.width / 2;
+ this.orientationSprite.position.y = this.game.height / 2;
+
+ this.checkOrientationState();
+
+ if (this.incorrectOrientation)
+ {
+ this.orientationSprite.visible = true;
+ this.game.world.visible = false;
+ }
+ else
+ {
+ this.orientationSprite.visible = false;
+ this.game.world.visible = true;
+ }
+
+ this.game.stage._stage.addChild(this.orientationSprite);
+ }
+
+ },
+
/**
* Checks if the browser is in the correct orientation for your game (if forceLandscape or forcePortrait have been set)
* @method Phaser.StageScaleMode#checkOrientationState
@@ -691,6 +750,13 @@ Phaser.StageScaleMode.prototype = {
// Back to normal
this.game.paused = false;
this.incorrectOrientation = false;
+
+ if (this.orientationSprite)
+ {
+ this.orientationSprite.visible = false;
+ this.game.world.visible = true;
+ }
+
this.refresh();
}
}
@@ -701,6 +767,13 @@ Phaser.StageScaleMode.prototype = {
// Show orientation screen
this.game.paused = true;
this.incorrectOrientation = true;
+
+ if (this.orientationSprite && this.orientationSprite.visible == false)
+ {
+ this.orientationSprite.visible = true;
+ this.game.world.visible = false;
+ }
+
this.refresh();
}
}
@@ -760,6 +833,9 @@ Phaser.StageScaleMode.prototype = {
{
this.refresh();
}
+
+ this.checkOrientationState();
+
},
/**
@@ -799,7 +875,7 @@ Phaser.StageScaleMode.prototype = {
/**
* Set screen size automatically based on the scaleMode.
- * @param {Description} force - If force is true it will try to resize the game regardless of the document dimensions.
+ * @param {boolean} force - If force is true it will try to resize the game regardless of the document dimensions.
*/
setScreenSize: function (force) {
@@ -912,6 +988,8 @@ Phaser.StageScaleMode.prototype = {
this.scaleFactor.x = this.game.width / this.width;
this.scaleFactor.y = this.game.height / this.height;
+ this.checkOrientationState();
+
},
/**
@@ -1032,7 +1110,7 @@ Object.defineProperty(Phaser.StageScaleMode.prototype, "isLandscape", {
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:08 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:33 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/State.js.html b/docs/State.js.html
index 8a7645ab..86321a5e 100644
--- a/docs/State.js.html
+++ b/docs/State.js.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -389,6 +393,12 @@
*/
Phaser.Utils = {
+ /**
+ * A standard Fisher-Yates Array shuffle implementation.
+ * @method Phaser.Utils.shuffle
+ * @param {array} array - The array to shuffle.
+ * @return {array} The shuffled array.
+ */
shuffle: function (array) {
for (var i = array.length - 1; i > 0; i--)
@@ -405,14 +415,14 @@ Phaser.Utils = {
/**
* Javascript string pad http://www.webtoolkit.info/.
- * pad = the string to pad it out with (defaults to a space)<br>
+ * pad = the string to pad it out with (defaults to a space)
* dir = 1 (left), 2 (right), 3 (both)
* @method Phaser.Utils.pad
* @param {string} str - The target string.
* @param {number} len - Description.
* @param {number} pad - the string to pad it out with (defaults to a space).
* @param {number} [dir=3] the direction dir = 1 (left), 2 (right), 3 (both).
- * @return {string}
+ * @return {string} The padded string
*/
pad: function (str, len, pad, dir) {
@@ -625,7 +635,7 @@ if (typeof Function.prototype.bind != 'function') {
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:08 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:33 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/World.js.html b/docs/World.js.html
index d972d47e..3bbdfea7 100644
--- a/docs/World.js.html
+++ b/docs/World.js.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -1016,7 +1020,7 @@ However it does affect the width property.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:08 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:33 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/index.html b/docs/index.html
index 85841a5c..d1854bfe 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -509,7 +513,7 @@ and my love of game development originate.
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:08 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:33 GMT-0000 (GMT) using the DocStrap template.
diff --git a/docs/namespaces.list.html b/docs/namespaces.list.html
index aad693b5..efe346e1 100644
--- a/docs/namespaces.list.html
+++ b/docs/namespaces.list.html
@@ -242,6 +242,10 @@
Pointer
+
@@ -691,7 +698,7 @@
Documentation generated by JSDoc 3.3.0-dev
- on Fri Nov 01 2013 18:16:08 GMT-0000 (GMT) using the DocStrap template.
+ on Thu Nov 07 2013 06:07:33 GMT-0000 (GMT) using the DocStrap template.
diff --git a/examples/_site/examples.json b/examples/_site/examples.json
index 4c9052a5..93340fd0 100644
--- a/examples/_site/examples.json
+++ b/examples/_site/examples.json
@@ -226,6 +226,10 @@
"file": "create+sprite+in+a+group.js",
"title": "create sprite in a group"
},
+ {
+ "file": "depth+sort.js",
+ "title": "depth sort"
+ },
{
"file": "display+order.js",
"title": "display order"
diff --git a/examples/_site/view_full.html b/examples/_site/view_full.html
index f8c2cd99..ce7a420b 100644
--- a/examples/_site/view_full.html
+++ b/examples/_site/view_full.html
@@ -15,34 +15,64 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/_site/view_lite.html b/examples/_site/view_lite.html
index 2768996c..8e51476a 100644
--- a/examples/_site/view_lite.html
+++ b/examples/_site/view_lite.html
@@ -15,32 +15,61 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
-
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/examples/assets/games/orbit/background.png b/examples/assets/games/orbit/background.png
new file mode 100644
index 00000000..8b4f9d69
Binary files /dev/null and b/examples/assets/games/orbit/background.png differ
diff --git a/examples/assets/games/orbit/ball.png b/examples/assets/games/orbit/ball.png
new file mode 100644
index 00000000..d3b30f67
Binary files /dev/null and b/examples/assets/games/orbit/ball.png differ
diff --git a/examples/assets/games/orbit/bg.png b/examples/assets/games/orbit/bg.png
new file mode 100644
index 00000000..6bb3c369
Binary files /dev/null and b/examples/assets/games/orbit/bg.png differ
diff --git a/examples/assets/games/orbit/bricks.png b/examples/assets/games/orbit/bricks.png
new file mode 100644
index 00000000..1a29cbbb
Binary files /dev/null and b/examples/assets/games/orbit/bricks.png differ
diff --git a/examples/assets/games/orbit/lazer.png b/examples/assets/games/orbit/lazer.png
new file mode 100644
index 00000000..a8478589
Binary files /dev/null and b/examples/assets/games/orbit/lazer.png differ
diff --git a/examples/assets/games/orbit/levels.json b/examples/assets/games/orbit/levels.json
new file mode 100644
index 00000000..54f1847d
--- /dev/null
+++ b/examples/assets/games/orbit/levels.json
@@ -0,0 +1,72 @@
+{ "height":30,
+ "layers":[
+ {
+ "height":30,
+ "image":"background.png",
+ "name":"background",
+ "opacity":1,
+ "type":"imagelayer",
+ "visible":true,
+ "width":10,
+ "x":0,
+ "y":0
+ },
+ {
+ "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 0, 0, 0, 0, 0, 0, 0, 14, 3, 3, 14, 0, 0, 0, 0, 0, 14, 13, 3, 3, 13, 14, 0, 0, 0, 0, 13, 3, 3, 3, 3, 13, 0, 0, 0, 14, 13, 3, 3, 3, 3, 13, 14, 0, 0, 14, 13, 3, 3, 3, 3, 13, 14, 0, 0, 14, 13, 2, 3, 3, 2, 13, 14, 0, 0, 14, 13, 3, 3, 3, 3, 13, 14, 0, 0, 14, 13, 3, 3, 3, 3, 13, 14, 0, 0, 14, 13, 3, 3, 3, 3, 13, 14, 0, 0, 14, 13, 5, 5, 5, 5, 13, 14, 0, 0, 14, 13, 1, 1, 1, 1, 13, 14, 0, 0, 0, 14, 1, 1, 1, 1, 14, 0, 0, 0, 0, 14, 13, 1, 1, 13, 14, 0, 0, 0, 0, 0, 14, 13, 13, 14, 0, 0, 0, 0, 0, 0, 0, 14, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ "height":30,
+ "name":"level 02",
+ "opacity":1,
+ "type":"tilelayer",
+ "visible":false,
+ "width":10,
+ "x":0,
+ "y":0
+ },
+ {
+ "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 14, 0, 0, 0, 0, 14, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 13, 13, 13, 13, 13, 13, 13, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 10, 10, 10, 10, 10, 10, 10, 10, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 4, 4, 4, 4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 8, 8, 8, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ "height":30,
+ "name":"level 01",
+ "opacity":1,
+ "type":"tilelayer",
+ "visible":true,
+ "width":10,
+ "x":0,
+ "y":0
+ },
+ {
+ "height":30,
+ "image":"wall.png",
+ "name":"walls",
+ "opacity":1,
+ "type":"imagelayer",
+ "visible":true,
+ "width":10,
+ "x":0,
+ "y":0
+ }],
+ "orientation":"orthogonal",
+ "properties":
+ {
+
+ },
+ "tileheight":16,
+ "tilesets":[
+ {
+ "firstgid":1,
+ "image":"bricks.png",
+ "imageheight":32,
+ "imagewidth":224,
+ "margin":0,
+ "name":"bricks",
+ "properties":
+ {
+
+ },
+ "spacing":0,
+ "tileheight":16,
+ "tilewidth":32
+ }],
+ "tilewidth":32,
+ "version":1,
+ "width":10
+}
\ No newline at end of file
diff --git a/examples/assets/games/orbit/levels.tmx b/examples/assets/games/orbit/levels.tmx
new file mode 100644
index 00000000..fecf95da
--- /dev/null
+++ b/examples/assets/games/orbit/levels.tmx
@@ -0,0 +1,22 @@
+
+
diff --git a/examples/assets/games/orbit/orbit.png b/examples/assets/games/orbit/orbit.png
new file mode 100644
index 00000000..9b5ff378
Binary files /dev/null and b/examples/assets/games/orbit/orbit.png differ
diff --git a/examples/assets/games/orbit/paddle1.png b/examples/assets/games/orbit/paddle1.png
new file mode 100644
index 00000000..a9ded501
Binary files /dev/null and b/examples/assets/games/orbit/paddle1.png differ
diff --git a/examples/assets/games/orbit/paddle2.png b/examples/assets/games/orbit/paddle2.png
new file mode 100644
index 00000000..ca54849f
Binary files /dev/null and b/examples/assets/games/orbit/paddle2.png differ
diff --git a/examples/assets/games/orbit/powerup_ball.png b/examples/assets/games/orbit/powerup_ball.png
new file mode 100644
index 00000000..fea3374b
Binary files /dev/null and b/examples/assets/games/orbit/powerup_ball.png differ
diff --git a/examples/assets/games/orbit/powerup_lazer.png b/examples/assets/games/orbit/powerup_lazer.png
new file mode 100644
index 00000000..323e5a89
Binary files /dev/null and b/examples/assets/games/orbit/powerup_lazer.png differ
diff --git a/examples/assets/games/orbit/powerup_multiball.png b/examples/assets/games/orbit/powerup_multiball.png
new file mode 100644
index 00000000..5e050eee
Binary files /dev/null and b/examples/assets/games/orbit/powerup_multiball.png differ
diff --git a/examples/assets/games/orbit/powerup_p.png b/examples/assets/games/orbit/powerup_p.png
new file mode 100644
index 00000000..5e5fa6fc
Binary files /dev/null and b/examples/assets/games/orbit/powerup_p.png differ
diff --git a/examples/assets/games/orbit/powerup_s.png b/examples/assets/games/orbit/powerup_s.png
new file mode 100644
index 00000000..30ae8f6b
Binary files /dev/null and b/examples/assets/games/orbit/powerup_s.png differ
diff --git a/examples/assets/games/orbit/powerup_x.png b/examples/assets/games/orbit/powerup_x.png
new file mode 100644
index 00000000..74dcc831
Binary files /dev/null and b/examples/assets/games/orbit/powerup_x.png differ
diff --git a/examples/assets/games/orbit/wall.png b/examples/assets/games/orbit/wall.png
new file mode 100644
index 00000000..1739a4a7
Binary files /dev/null and b/examples/assets/games/orbit/wall.png differ
diff --git a/examples/assets/maps/burd.json b/examples/assets/maps/burd.json
new file mode 100644
index 00000000..b807e39d
--- /dev/null
+++ b/examples/assets/maps/burd.json
@@ -0,0 +1,65 @@
+{ "height":19,
+ "layers":[
+ {
+ "data":[1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 11, 1, 1, 9, 13, 1, 1, 1, 1, 11, 1, 1, 1, 1, 1, 1, 5, 12, 1, 1, 1, 2, 1, 3, 1, 1, 8, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 9, 1, 13, 1, 1, 8, 1, 1, 1, 5, 1, 1, 6, 1, 1, 1, 9, 1, 4, 1, 1, 1, 3, 1, 13, 1, 1, 1, 1, 1, 1, 2, 1, 1, 1, 1, 1, 1, 1, 1, 10, 1, 1, 1, 1, 1, 6, 1, 1, 1, 8, 1, 1, 1, 7, 1, 4, 1, 1, 9, 1, 12, 12, 1, 6, 1, 9, 1, 1, 11, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 9, 1, 1, 1, 3, 1, 1, 1, 1, 1, 5, 1, 1, 1, 2, 1, 1, 1, 1, 11, 7, 1, 1, 4, 1, 1, 1, 1, 1, 13, 1, 1, 1, 3, 1, 1, 1, 1, 9, 1, 9, 1, 2, 1, 1, 2, 1, 12, 1, 9, 1, 1, 9, 1, 1, 1, 8, 1, 1, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 4, 1, 1, 1, 3, 1, 1, 3, 1, 1, 1, 3, 1, 7, 1, 1, 2, 1, 3, 1, 13, 2, 10, 1, 3, 1, 1, 1, 9, 1, 4, 1, 1, 1, 11, 1, 1, 1, 1, 1, 7, 1, 1, 3, 1, 1, 1, 1, 1, 1, 6, 1, 8, 1, 1, 2, 1, 12, 1, 1, 1, 11, 12, 8, 1, 1, 1, 1, 11, 1, 1, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 5, 1, 1, 1, 1, 6, 1, 1, 3, 1, 1, 1, 7, 1, 1, 1, 6, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 1, 9, 1, 1, 1, 1, 6, 1, 1, 1, 1, 1, 9, 1, 1, 1, 1, 1, 1, 10, 1, 1, 9, 1, 2, 1, 1, 1, 1, 7, 1, 1, 1, 5, 1, 3, 1, 1, 11, 1, 1, 1, 7, 1, 1, 1, 1, 1, 1, 1, 1, 10, 1, 1, 1, 2, 1, 1, 3, 1, 1, 8, 1, 1, 1, 1, 1, 1, 1, 3, 1, 1, 1, 1, 13, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 6, 1, 8, 1, 1, 3, 1, 1, 3, 1, 8, 6, 1, 1, 1, 11, 1, 1, 1, 1, 1, 11, 1, 1, 1, 1, 3, 1, 1, 1, 1, 12, 1, 1, 9, 1, 1, 2, 5, 3, 1, 1, 2, 3, 1, 8, 4, 6, 1, 3, 1, 9, 6, 1, 4, 1, 5, 9, 1, 8, 1],
+ "height":19,
+ "name":"Tile Layer 1",
+ "opacity":1,
+ "type":"tilelayer",
+ "visible":true,
+ "width":25,
+ "x":0,
+ "y":0
+ },
+ {
+ "data":[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 29, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 28, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 29, 0, 0, 33, 0, 0, 31, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 30, 0, 0, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 31, 0, 0, 0, 31, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 33, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 28, 0, 0, 0, 0, 33, 0, 0, 31, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0],
+ "height":19,
+ "name":"Tile Layer 2",
+ "opacity":1,
+ "type":"tilelayer",
+ "visible":true,
+ "width":25,
+ "x":0,
+ "y":0
+ }],
+ "orientation":"orthogonal",
+ "properties":
+ {
+
+ },
+ "tileheight":32,
+ "tilesets":[
+ {
+ "firstgid":1,
+ "image":"ground_1x1.png",
+ "imageheight":32,
+ "imagewidth":800,
+ "margin":0,
+ "name":"ground_1x1",
+ "properties":
+ {
+
+ },
+ "spacing":0,
+ "tileheight":32,
+ "tilewidth":32
+ },
+ {
+ "firstgid":26,
+ "image":"walls_1x2.png",
+ "imageheight":64,
+ "imagewidth":256,
+ "margin":0,
+ "name":"walls_1x2",
+ "properties":
+ {
+
+ },
+ "spacing":0,
+ "tileheight":64,
+ "tilewidth":32
+ }],
+ "tilewidth":32,
+ "version":1,
+ "width":25
+}
\ No newline at end of file
diff --git a/examples/assets/maps/burd.tmx b/examples/assets/maps/burd.tmx
new file mode 100644
index 00000000..cd06b7c4
--- /dev/null
+++ b/examples/assets/maps/burd.tmx
@@ -0,0 +1,19 @@
+
+
diff --git a/examples/assets/maps/ground_1x1.png b/examples/assets/maps/ground_1x1.png
new file mode 100644
index 00000000..7299cffb
Binary files /dev/null and b/examples/assets/maps/ground_1x1.png differ
diff --git a/examples/assets/maps/walls_1x2.png b/examples/assets/maps/walls_1x2.png
new file mode 100644
index 00000000..5d268af7
Binary files /dev/null and b/examples/assets/maps/walls_1x2.png differ
diff --git a/examples/assets/pics/forgotten_worlds.png b/examples/assets/pics/forgotten_worlds.png
new file mode 100644
index 00000000..7e713b30
Binary files /dev/null and b/examples/assets/pics/forgotten_worlds.png differ
diff --git a/examples/assets/sprites/atlas json array trimmed.tps b/examples/assets/sprites/atlas json array trimmed.tps
new file mode 100644
index 00000000..df5a2a99
--- /dev/null
+++ b/examples/assets/sprites/atlas json array trimmed.tps
@@ -0,0 +1,190 @@
+
+
+
+ fileFormatVersion
+ 1
+ variation
+ main
+ verbose
+
+ autoSDSettings
+
+ allowRotation
+
+ quiet
+
+ premultiplyAlpha
+
+ shapeDebug
+
+ dpi
+ 72
+ dataFormat
+ json-array
+ textureFileName
+ atlas_json_array_trimmed.png
+ flipPVR
+
+ ditherType
+ NearestNeighbour
+ backgroundColor
+ 0
+ libGdx
+
+ filtering
+
+ x
+ Linear
+ y
+ Linear
+
+
+ shapePadding
+ 2
+ jpgQuality
+ 80
+ pngOptimizationLevel
+ 0
+ textureSubPath
+
+ textureFormat
+ png
+ borderPadding
+ 2
+ maxTextureSize
+
+ width
+ 1024
+ height
+ 1024
+
+ fixedTextureSize
+
+ width
+ -1
+ height
+ -1
+
+ reduceBorderArtifacts
+
+ algorithmSettings
+
+ algorithm
+ MaxRects
+ freeSizeMode
+ Best
+ sizeConstraints
+ POT
+ forceSquared
+
+ forceWordAligned
+
+ maxRects
+
+ heuristic
+ Best
+
+ basic
+
+ sortBy
+ Best
+ order
+ Ascending
+
+
+ andEngine
+
+ minFilter
+ Linear
+ packageName
+ Texture
+ javaFileName
+ atlas_json_array_trimmed.java
+ wrap
+
+ s
+ Clamp
+ t
+ Clamp
+
+ magFilter
+ MagLinear
+
+ dataFileName
+ atlas_json_array_trimmed.json
+ multiPack
+
+ mainExtension
+
+ forceIdenticalLayout
+
+ outputFormat
+ RGBA8888
+ contentProtection
+
+ key
+
+
+ autoAliasEnabled
+
+ trimSpriteNames
+
+ globalSpriteSettings
+
+ scale
+ 1
+ scaleMode
+ Smooth
+ innerPadding
+ 0
+ extrude
+ 0
+ trimThreshold
+ 1
+ trimMode
+ Trim
+ heuristicMask
+
+
+ fileList
+
+ ../pics/titan_mech.png
+ ../pics/shocktroopers_lulu2.png
+ ../pics/spyro.png
+ ../pics/contra3.png
+ ../pics/cactuar.png
+ ../pics/contra1.png
+ ../pics/nanoha_taiken_blue.png
+ ../pics/ladycop.png
+ darkwing_crazy.png
+ oz_pov_melting_disk.png
+ sonic_havok_sanity.png
+ slime.png
+ wizball.png
+ phaser-dude.png
+ pangball.png
+ thrust_ship.png
+ tomato.png
+ onion.png
+ pepper.png
+ pineapple.png
+ diamond.png
+ eggplant.png
+ firstaid.png
+ melon.png
+ mushroom.png
+ phaser_tiny.png
+ carrot.png
+
+ ignoreFileList
+
+ replaceList
+
+ ignoredWarnings
+
+ commonDivisorX
+ 1
+ commonDivisorY
+ 1
+
+
diff --git a/examples/assets/sprites/atlas_json_array_trimmed.json b/examples/assets/sprites/atlas_json_array_trimmed.json
new file mode 100644
index 00000000..f70ecfe9
--- /dev/null
+++ b/examples/assets/sprites/atlas_json_array_trimmed.json
@@ -0,0 +1,228 @@
+{"frames": [
+
+{
+ "filename": "cactuar",
+ "frame": {"x":2,"y":205,"w":213,"h":159},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":213,"h":159},
+ "sourceSize": {"w":231,"h":175}
+},
+{
+ "filename": "carrot",
+ "frame": {"x":217,"y":247,"w":22,"h":21},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":22,"h":21},
+ "sourceSize": {"w":22,"h":21}
+},
+{
+ "filename": "contra1",
+ "frame": {"x":160,"y":366,"w":83,"h":169},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":83,"h":169},
+ "sourceSize": {"w":83,"h":169}
+},
+{
+ "filename": "contra3",
+ "frame": {"x":2,"y":2,"w":246,"h":201},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":246,"h":201},
+ "sourceSize": {"w":246,"h":201}
+},
+{
+ "filename": "darkwing_crazy",
+ "frame": {"x":431,"y":364,"w":53,"h":49},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":53,"h":49},
+ "sourceSize": {"w":53,"h":49}
+},
+{
+ "filename": "diamond",
+ "frame": {"x":194,"y":571,"w":32,"h":28},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":32,"h":28},
+ "sourceSize": {"w":32,"h":28}
+},
+{
+ "filename": "eggplant",
+ "frame": {"x":491,"y":72,"w":16,"h":21},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":16,"h":21},
+ "sourceSize": {"w":16,"h":21}
+},
+{
+ "filename": "firstaid",
+ "frame": {"x":160,"y":547,"w":32,"h":32},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
+ "sourceSize": {"w":32,"h":32}
+},
+{
+ "filename": "ladycop",
+ "frame": {"x":2,"y":736,"w":87,"h":231},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":87,"h":231},
+ "sourceSize": {"w":87,"h":231}
+},
+{
+ "filename": "melon",
+ "frame": {"x":217,"y":344,"w":20,"h":20},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":20,"h":20},
+ "sourceSize": {"w":20,"h":20}
+},
+{
+ "filename": "mushroom",
+ "frame": {"x":217,"y":300,"w":21,"h":21},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":21,"h":21},
+ "sourceSize": {"w":21,"h":21}
+},
+{
+ "filename": "nanoha_taiken_blue",
+ "frame": {"x":2,"y":366,"w":156,"h":224},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":156,"h":224},
+ "sourceSize": {"w":156,"h":224}
+},
+{
+ "filename": "onion",
+ "frame": {"x":217,"y":323,"w":21,"h":19},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":21,"h":19},
+ "sourceSize": {"w":21,"h":19}
+},
+{
+ "filename": "oz_pov_melting_disk",
+ "frame": {"x":431,"y":246,"w":62,"h":116},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":62,"h":116},
+ "sourceSize": {"w":62,"h":116}
+},
+{
+ "filename": "pangball",
+ "frame": {"x":195,"y":537,"w":32,"h":32},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":32,"h":32},
+ "sourceSize": {"w":32,"h":32}
+},
+{
+ "filename": "pepper",
+ "frame": {"x":491,"y":2,"w":19,"h":24},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":19,"h":24},
+ "sourceSize": {"w":19,"h":24}
+},
+{
+ "filename": "phaser-dude",
+ "frame": {"x":217,"y":205,"w":27,"h":40},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":27,"h":40},
+ "sourceSize": {"w":27,"h":40}
+},
+{
+ "filename": "phaser_tiny",
+ "frame": {"x":160,"y":537,"w":33,"h":8},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":33,"h":8},
+ "sourceSize": {"w":33,"h":8}
+},
+{
+ "filename": "pineapple",
+ "frame": {"x":491,"y":47,"w":16,"h":23},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":16,"h":23},
+ "sourceSize": {"w":16,"h":23}
+},
+{
+ "filename": "shocktroopers_lulu2",
+ "frame": {"x":229,"y":546,"w":131,"h":188},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":1,"y":0,"w":131,"h":188},
+ "sourceSize": {"w":133,"h":188}
+},
+{
+ "filename": "slime",
+ "frame": {"x":431,"y":415,"w":48,"h":52},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":48,"h":52},
+ "sourceSize": {"w":48,"h":52}
+},
+{
+ "filename": "sonic_havok_sanity",
+ "frame": {"x":403,"y":469,"w":98,"h":167},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":98,"h":167},
+ "sourceSize": {"w":98,"h":167}
+},
+{
+ "filename": "spyro",
+ "frame": {"x":245,"y":430,"w":156,"h":114},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":0,"y":0,"w":156,"h":114},
+ "sourceSize": {"w":176,"h":130}
+},
+{
+ "filename": "thrust_ship",
+ "frame": {"x":217,"y":270,"w":21,"h":28},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":21,"h":28},
+ "sourceSize": {"w":21,"h":28}
+},
+{
+ "filename": "titan_mech",
+ "frame": {"x":250,"y":2,"w":239,"h":242},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":239,"h":242},
+ "sourceSize": {"w":239,"h":242}
+},
+{
+ "filename": "tomato",
+ "frame": {"x":491,"y":28,"w":18,"h":17},
+ "rotated": false,
+ "trimmed": false,
+ "spriteSourceSize": {"x":0,"y":0,"w":18,"h":17},
+ "sourceSize": {"w":18,"h":17}
+},
+{
+ "filename": "wizball",
+ "frame": {"x":246,"y":246,"w":183,"h":182},
+ "rotated": false,
+ "trimmed": true,
+ "spriteSourceSize": {"x":4,"y":2,"w":183,"h":182},
+ "sourceSize": {"w":195,"h":188}
+}],
+"meta": {
+ "app": "http://www.codeandweb.com/texturepacker ",
+ "version": "1.0",
+ "image": "atlas_json_array_trimmed.png",
+ "format": "RGBA8888",
+ "size": {"w":512,"h":1024},
+ "scale": "1",
+ "smartupdate": "$TexturePacker:SmartUpdate:c3013af70e8e46c48c1f140e4eb1a651:1/1$"
+}
+}
diff --git a/examples/assets/sprites/atlas_json_array_trimmed.png b/examples/assets/sprites/atlas_json_array_trimmed.png
new file mode 100644
index 00000000..f844e71c
Binary files /dev/null and b/examples/assets/sprites/atlas_json_array_trimmed.png differ
diff --git a/examples/games/starstruck.js b/examples/games/starstruck.js
index bd78c37e..5ddf9526 100644
--- a/examples/games/starstruck.js
+++ b/examples/games/starstruck.js
@@ -1,5 +1,5 @@
-var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create,update:update});
+var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
function preload() {
@@ -110,4 +110,13 @@ function update() {
jumpTimer = game.time.now + 750;
}
+ // player.scale.x += 0.001;
+ // player.scale.y += 0.001;
+
+}
+
+function render () {
+
+ game.debug.renderSpriteBody(player);
+
}
diff --git a/examples/groups/depth sort.js b/examples/groups/depth sort.js
new file mode 100644
index 00000000..fc7f319f
--- /dev/null
+++ b/examples/groups/depth sort.js
@@ -0,0 +1,79 @@
+var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update });
+
+function preload() {
+
+ game.load.image('phaser', 'assets/sprites/phaser-dude.png');
+ game.load.tilemap('desert', 'assets/maps/burd.json', null, Phaser.Tilemap.TILED_JSON);
+ game.load.tileset('tiles', 'assets/maps/ground_1x1.png', 32, 32);
+ game.load.spritesheet('trees', 'assets/maps/walls_1x2.png', 32, 64);
+
+}
+
+var map;
+var tileset;
+var layer;
+
+var sprite;
+var group;
+var oldY = 0;
+var cursors;
+
+function create() {
+
+ // Create our tilemap to walk around
+ map = game.add.tilemap('desert');
+ tileset = game.add.tileset('tiles');
+ layer = game.add.tilemapLayer(0, 0, 800, 600, tileset, map, 0);
+
+ // This group will hold the main player + all the tree sprites to depth sort against
+ group = game.add.group();
+
+ // The player
+ sprite = group.create(300, 200, 'phaser');
+
+ // Some trees
+ for (var i = 0; i < 50; i++)
+ {
+ var x = game.math.snapTo(game.world.randomX, 32);
+ var y = game.math.snapTo(game.world.randomY, 32);
+ group.create(x, y, 'trees', game.rnd.integerInRange(0, 8));
+ }
+
+ // Move it
+ cursors = game.input.keyboard.createCursorKeys();
+
+}
+
+function update() {
+
+ sprite.body.velocity.x = 0;
+ sprite.body.velocity.y = 0;
+
+ if (cursors.left.isDown)
+ {
+ sprite.body.velocity.x = -200;
+ }
+ else if (cursors.right.isDown)
+ {
+ sprite.body.velocity.x = 200;
+ }
+
+ if (cursors.up.isDown)
+ {
+ sprite.body.velocity.y = -200;
+ }
+ else if (cursors.down.isDown)
+ {
+ sprite.body.velocity.y = 200;
+ }
+
+ if (sprite.y !== oldY)
+ {
+ // Group.sort() is an expensive operation
+ // You really want to minimise how often it is called as much as possible.
+ // So this little check helps at least, but if you can do it even less than this.
+ group.sort();
+ oldY = sprite.y;
+ }
+
+}
diff --git a/examples/input/keyboard.js b/examples/input/keyboard.js
index fac2a581..4b88b5c2 100644
--- a/examples/input/keyboard.js
+++ b/examples/input/keyboard.js
@@ -59,7 +59,7 @@ function update() {
ufo.angle = -15;
leftBtn.alpha = 0.6;
}
- else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT)
+ else if (game.input.keyboard.isDown(Phaser.Keyboard.RIGHT))
{
ufo.x += speed;
ufo.angle = 15;
diff --git a/examples/wip/pivot.js b/examples/wip/pivot.js
new file mode 100644
index 00000000..3bc4b2ed
--- /dev/null
+++ b/examples/wip/pivot.js
@@ -0,0 +1,49 @@
+var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('atari', 'assets/sprites/atari130xe.png');
+ game.load.image('mushroom', 'assets/sprites/mushroom2.png');
+
+}
+
+var sprite1;
+var sprite2;
+
+function create() {
+
+ game.stage.backgroundColor = '#2d2d2d';
+
+ // This will check Sprite vs. Sprite collision
+
+ sprite1 = game.add.sprite(300, 300, 'atari');
+ sprite1.name = 'atari';
+ sprite1.body.immovable = true;
+
+ sprite1.anchor.setTo(0.5, 0.5);
+ sprite1.pivot.x = 250;
+ sprite1.pivot.y = 300;
+
+ // sprite2 = game.add.sprite(0, 0, 'mushroom');
+ // sprite2.name = 'mushroom';
+
+}
+
+function update() {
+
+ sprite1.angle += 1;
+ sprite1.pivot.x = game.input.x;
+ sprite1.pivot.y = game.input.y;
+
+}
+
+function render() {
+
+ game.debug.renderPixel(sprite1.pivot.x, sprite1.pivot.y);
+
+ // game.debug.renderSpriteInfo(sprite1, 100, 400);
+ game.debug.renderSpriteBounds(sprite1);
+ // game.debug.renderSpriteInfo(sprite2, 100, 100);
+ // game.debug.renderSpriteBounds(sprite2);
+}
+
diff --git a/examples/wip/pixelpick atlas trimmed.js b/examples/wip/pixelpick atlas trimmed.js
new file mode 100644
index 00000000..47bfc6d5
--- /dev/null
+++ b/examples/wip/pixelpick atlas trimmed.js
@@ -0,0 +1,51 @@
+
+var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create });
+
+function preload() {
+
+ game.load.atlas('atlas', 'assets/sprites/atlas_json_array_trimmed.png', 'assets/sprites/atlas_json_array_trimmed.json');
+
+}
+
+var wizball;
+// var chick;
+// var mech;
+// var robot;
+// var cop;
+
+function create() {
+
+ game.stage.backgroundColor = '#404040';
+
+ // This demonstrates pixel perfect click detection even if using sprites in a texture atlas.
+
+ // chick = game.add.sprite(64, 64, 'atlas');
+ // chick.frameName = 'budbrain_chick.png';
+ // chick.inputEnabled = true;
+ // chick.input.pixelPerfect = true;
+ // chick.input.useHandCursor = true;
+
+ // cop = game.add.sprite(600, 64, 'atlas');
+ // cop.frameName = 'ladycop.png';
+ // cop.inputEnabled = true;
+ // cop.input.pixelPerfect = true;
+ // cop.input.useHandCursor = true;
+
+ // robot = game.add.sprite(50, 300, 'atlas');
+ // robot.frameName = 'robot.png';
+ // robot.inputEnabled = true;
+ // robot.input.pixelPerfect = true;
+ // robot.input.useHandCursor = true;
+
+ wizball = game.add.sprite(100, 400, 'atlas', 'wizball');
+ wizball.inputEnabled = true;
+ wizball.input.pixelPerfect = true;
+ wizball.input.useHandCursor = true;
+
+ // mech = game.add.sprite(250, 100, 'atlas');
+ // mech.frameName = 'titan_mech.png';
+ // mech.inputEnabled = true;
+ // mech.input.pixelPerfect = true;
+ // mech.input.useHandCursor = true;
+
+}
diff --git a/examples/wip/sort.js b/examples/wip/sort.js
new file mode 100644
index 00000000..fc7f319f
--- /dev/null
+++ b/examples/wip/sort.js
@@ -0,0 +1,79 @@
+var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update });
+
+function preload() {
+
+ game.load.image('phaser', 'assets/sprites/phaser-dude.png');
+ game.load.tilemap('desert', 'assets/maps/burd.json', null, Phaser.Tilemap.TILED_JSON);
+ game.load.tileset('tiles', 'assets/maps/ground_1x1.png', 32, 32);
+ game.load.spritesheet('trees', 'assets/maps/walls_1x2.png', 32, 64);
+
+}
+
+var map;
+var tileset;
+var layer;
+
+var sprite;
+var group;
+var oldY = 0;
+var cursors;
+
+function create() {
+
+ // Create our tilemap to walk around
+ map = game.add.tilemap('desert');
+ tileset = game.add.tileset('tiles');
+ layer = game.add.tilemapLayer(0, 0, 800, 600, tileset, map, 0);
+
+ // This group will hold the main player + all the tree sprites to depth sort against
+ group = game.add.group();
+
+ // The player
+ sprite = group.create(300, 200, 'phaser');
+
+ // Some trees
+ for (var i = 0; i < 50; i++)
+ {
+ var x = game.math.snapTo(game.world.randomX, 32);
+ var y = game.math.snapTo(game.world.randomY, 32);
+ group.create(x, y, 'trees', game.rnd.integerInRange(0, 8));
+ }
+
+ // Move it
+ cursors = game.input.keyboard.createCursorKeys();
+
+}
+
+function update() {
+
+ sprite.body.velocity.x = 0;
+ sprite.body.velocity.y = 0;
+
+ if (cursors.left.isDown)
+ {
+ sprite.body.velocity.x = -200;
+ }
+ else if (cursors.right.isDown)
+ {
+ sprite.body.velocity.x = 200;
+ }
+
+ if (cursors.up.isDown)
+ {
+ sprite.body.velocity.y = -200;
+ }
+ else if (cursors.down.isDown)
+ {
+ sprite.body.velocity.y = 200;
+ }
+
+ if (sprite.y !== oldY)
+ {
+ // Group.sort() is an expensive operation
+ // You really want to minimise how often it is called as much as possible.
+ // So this little check helps at least, but if you can do it even less than this.
+ group.sort();
+ oldY = sprite.y;
+ }
+
+}
diff --git a/examples/wip/swap.js b/examples/wip/swap.js
new file mode 100644
index 00000000..cc330394
--- /dev/null
+++ b/examples/wip/swap.js
@@ -0,0 +1,89 @@
+var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
+
+function preload() {
+
+ game.load.image('phaser', 'assets/sprites/phaser-dude.png');
+ game.load.spritesheet('veggies', 'assets/sprites/fruitnveg32wh37.png', 32, 32);
+
+}
+
+var group;
+var start = false;
+var swapCount = 0;
+var time = 0;
+var test = 0;
+
+function create() {
+
+ game.stage.backgroundColor = '#2d2d2d';
+
+ group = game.add.group();
+
+ for (var i = 0; i < 500; i++)
+ {
+ var c = group.create(game.world.randomX, game.world.randomY, 'veggies', game.rnd.integerInRange(0, 36));
+ c.name = 'veg' + i;
+ }
+
+ test = group.length;
+
+ game.input.onUp.add(toggleSwap, this);
+
+}
+
+function toggleSwap () {
+
+ if (start)
+ {
+ start = false;
+ }
+ else
+ {
+ start = true;
+ }
+
+}
+
+function update() {
+
+ if (start && game.time.now > time)
+ {
+ var a = group.getRandom();
+ var b = group.getRandom();
+
+ if (a.name !== b.name)
+ {
+ // console.log('************************ NEW ROUND *********************');
+ // group.dump(true);
+ // console.log('Group Size: ' + group.length);
+ group.swap(a, b);
+ swapCount++;
+
+ if (group.length !== test)
+ {
+ start = false;
+ console.log('************************ SHIT *********************');
+ group.dump(true);
+ console.log('************************ SHIT *********************');
+ }
+
+ if (group.validate() == false)
+ {
+ start = false;
+ console.log('************************ VALIDATE FAIL *********************');
+ group.dump(true);
+ console.log('************************ VALIDATE FAIL *********************');
+ }
+
+ }
+
+ // time = game.time.now + 50;
+ }
+
+}
+
+function render() {
+
+ game.debug.renderText('Swap: ' + swapCount, 32, 32);
+
+}
\ No newline at end of file
diff --git a/package.json b/package.json
index e301619c..e8eab2d6 100644
--- a/package.json
+++ b/package.json
@@ -1,7 +1,13 @@
{
"name": "Phaser",
- "version": "1.1.2",
- "description": "HTML5 game framework",
+ "version": "1.1.3",
+ "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",
+ "homepage": "http://phaser.io",
+ "bugs": "https://github.com/photonstorm/phaser/issues",
+ "license": "MIT",
+ "licenseUrl": "http://www.opensource.org/licenses/mit-license.php",
"repository": {
"type": "git",
"url": "https://photonstorm@github.com/photonstorm/phaser.git"
@@ -10,10 +16,14 @@
"HTML5",
"game",
"canvas",
- "2d"
+ "2d",
+ "WebGL",
+ "web audio",
+ "physics",
+ "tweens",
+ "javascript",
+ "typescript"
],
- "author": "Richard Davey",
- "license": "MIT",
"devDependencies": {
"grunt": "~0.4.1",
"grunt-contrib-concat": "~0.3.0",
diff --git a/resources/Project Templates/Basic/MainMenu.js b/resources/Project Templates/Basic/MainMenu.js
index 968bca66..fe2a1ae1 100644
--- a/resources/Project Templates/Basic/MainMenu.js
+++ b/resources/Project Templates/Basic/MainMenu.js
@@ -10,7 +10,7 @@ BasicGame.MainMenu.prototype = {
create: function () {
- // We've already preloaded our assets, so let's kick right into the Main Menu itself
+ // We've already preloaded our assets, so let's kick right into the Main Menu itself.
// Here all we're doing is playing some music and adding a picture and button
// Naturally I expect you to do something significantly better :)
diff --git a/resources/Project Templates/Basic/Preloader.js b/resources/Project Templates/Basic/Preloader.js
index 1b7e2c81..1eefba51 100644
--- a/resources/Project Templates/Basic/Preloader.js
+++ b/resources/Project Templates/Basic/Preloader.js
@@ -17,12 +17,13 @@ BasicGame.Preloader.prototype = {
this.background = this.add.sprite(0, 0, 'preloaderBackground');
this.preloadBar = this.add.sprite(300, 400, 'preloaderBar');
- // This sets the preloadBar sprite as a loader sprite, basically
- // what that does is automatically crop the sprite from 0 to full-width
+ // This sets the preloadBar sprite as a loader sprite.
+ // What that does is automatically crop the sprite from 0 to full-width
// as the files below are loaded in.
this.load.setPreloadSprite(this.preloadBar);
- // Here we load most of the assets our game needs
+ // Here we load the rest of the assets our game needs.
+ // As this is just a Project Template I've not provided these assets, swap them for your own.
this.load.image('titlepage', 'images/title.jpg');
this.load.atlas('playButton', 'images/play_button.png', 'images/play_button.json');
this.load.audio('titleMusic', ['audio/main_menu.mp3']);
@@ -33,7 +34,7 @@ BasicGame.Preloader.prototype = {
create: function () {
- // Once the load has finished we disable the crop because we're going to sit in the update loop for a short while
+ // Once the load has finished we disable the crop because we're going to sit in the update loop for a short while as the music decodes
this.preloadBar.cropEnabled = false;
},
@@ -51,7 +52,7 @@ BasicGame.Preloader.prototype = {
if (this.cache.isSoundDecoded('titleMusic') && this.ready == false)
{
- this.ready = false;
+ this.ready = true;
this.game.state.start('MainMenu');
}
diff --git a/resources/Project Templates/Basic/index.html b/resources/Project Templates/Basic/index.html
index 0c85cf8e..76d93862 100644
--- a/resources/Project Templates/Basic/index.html
+++ b/resources/Project Templates/Basic/index.html
@@ -3,6 +3,7 @@
Phaser Basic Project Template
+
@@ -17,7 +18,7 @@
window.onload = function() {
// Create your Phaser game and inject it into the gameContainer div.
- // We did it in a window.onload event, but you can do it anywhere (requireJS load, anonymous function, jQuery dom ready, etc - whatever floats your boat)
+ // We did it in a window.onload event, but you can do it anywhere (requireJS load, anonymous function, jQuery dom ready, - whatever floats your boat)
var game = new Phaser.Game(1024, 768, Phaser.AUTO, 'gameContainer');
// Add the States your game has.
diff --git a/resources/wip/rotations.png b/resources/wip/rotations.png
new file mode 100644
index 00000000..2b2f1402
Binary files /dev/null and b/resources/wip/rotations.png differ
diff --git a/src/Phaser.js b/src/Phaser.js
index 07b3aaeb..3eb9cd72 100644
--- a/src/Phaser.js
+++ b/src/Phaser.js
@@ -10,7 +10,7 @@
var Phaser = Phaser || {
VERSION: '<%= version %>',
- DEV_VERSION: '1.1.2',
+ DEV_VERSION: '1.1.3',
GAMES: [],
AUTO: 0,
CANVAS: 1,
@@ -28,6 +28,7 @@ var Phaser = Phaser || {
TILEMAP: 9,
TILEMAPLAYER: 10,
EMITTER: 11,
+ POLYGON: 12,
NONE: 0,
LEFT: 1,
diff --git a/src/animation/AnimationManager.js b/src/animation/AnimationManager.js
index 68f6d445..0de12ac3 100644
--- a/src/animation/AnimationManager.js
+++ b/src/animation/AnimationManager.js
@@ -261,6 +261,27 @@ Phaser.AnimationManager.prototype = {
},
+ /**
+ * Returns an animation that was previously added by name.
+ *
+ * @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.
+ */
+ getAnimation: function (name) {
+
+ if (typeof name == 'string')
+ {
+ if (this._anims[name])
+ {
+ return this._anims[name];
+ }
+ }
+
+ return false;
+
+ },
+
/**
* Refreshes the current frame data back to the parent Sprite and also resets the texture data.
*
diff --git a/src/core/Game.js b/src/core/Game.js
index ca1a0635..f6dbc4f7 100644
--- a/src/core/Game.js
+++ b/src/core/Game.js
@@ -422,7 +422,13 @@ Phaser.Game.prototype = {
this.time.update(time);
- if (!this._paused)
+ if (this._paused)
+ {
+ this.renderer.render(this.stage._stage);
+ this.plugins.render();
+ this.state.render();
+ }
+ else
{
this.plugins.preUpdate();
this.physics.preUpdate();
@@ -437,6 +443,7 @@ Phaser.Game.prototype = {
this.plugins.update();
this.world.postUpdate();
+ this.plugins.postUpdate();
this.renderer.render(this.stage._stage);
this.plugins.render();
diff --git a/src/core/Group.js b/src/core/Group.js
index 28070872..c83f4baf 100644
--- a/src/core/Group.js
+++ b/src/core/Group.js
@@ -91,6 +91,36 @@ Phaser.Group = function (game, parent, name, useStage) {
};
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Group.RETURN_NONE = 0;
+
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Group.RETURN_TOTAL = 1;
+
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Group.RETURN_CHILD = 2;
+
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Group.SORT_ASCENDING = -1;
+
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Group.SORT_DESCENDING = 1;
+
Phaser.Group.prototype = {
/**
@@ -303,8 +333,48 @@ Phaser.Group.prototype = {
},
+ 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);
+
+ },
+
+ swapIndex: function (index1, index2) {
+
+ var child1 = this.getAt(index1);
+ var child2 = this.getAt(index2);
+
+ console.log('swapIndex ', index1, ' with ', index2);
+
+ this.swap(child1, child2);
+
+ },
+
/**
- * Swaps the position of two children in this Group.
+ * 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.
@@ -313,9 +383,8 @@ Phaser.Group.prototype = {
*/
swap: function (child1, child2) {
- if (child1 === child2 || !child1.parent || !child2.parent)
+ if (child1 === child2 || !child1.parent || !child2.parent || child1.group !== this || child2.group !== this)
{
- console.warn('You cannot swap a child with itself or swap un-parented children');
return false;
}
@@ -387,7 +456,7 @@ Phaser.Group.prototype = {
child2._iPrev = child1;
if (child2Prev) { child2Prev._iNext = child1; }
- if (child1Next) { child2Next._iPrev = child2; }
+ if (child1Next) { child1Next._iPrev = child2; }
if (child1.__renderGroup)
{
@@ -754,7 +823,7 @@ Phaser.Group.prototype = {
/**
* 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 you can add as many extra parameters as you like, which will all be passed to the child.
+ * 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.
@@ -860,6 +929,24 @@ Phaser.Group.prototype = {
},
+ /**
+ * 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.
@@ -874,23 +961,7 @@ Phaser.Group.prototype = {
var args = Array.prototype.splice.call(arguments, 2);
args.unshift(null);
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.alive)
- {
- args[0] = currentNode;
- callback.apply(callbackContext, args);
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
-
- }
+ this.iterate('alive', true, Phaser.Group.RETURN_TOTAL, callback, callbackContext, args);
},
@@ -908,23 +979,121 @@ Phaser.Group.prototype = {
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').
+ */
+ iterate: function (key, value, returnType, callback, callbackContext, args) {
+
+ if (returnType == Phaser.Group.RETURN_TOTAL && this._container.children.length == 0)
+ {
+ return -1;
+ }
+
+ 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.alive == false)
+ if (currentNode[key] === value)
{
- args[0] = currentNode;
- callback.apply(callbackContext, args);
+ 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;
+ }
+
},
/**
@@ -941,23 +1110,7 @@ Phaser.Group.prototype = {
state = true;
}
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.exists === state)
- {
- return currentNode;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
-
- return null;
+ return this.iterate('exists', state, Phaser.Group.RETURN_CHILD);
},
@@ -970,23 +1123,7 @@ Phaser.Group.prototype = {
*/
getFirstAlive: function () {
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.alive)
- {
- return currentNode;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
-
- return null;
+ return this.iterate('alive', true, Phaser.Group.RETURN_CHILD);
},
@@ -999,23 +1136,7 @@ Phaser.Group.prototype = {
*/
getFirstDead: function () {
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (!currentNode.alive)
- {
- return currentNode;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
-
- return null;
+ return this.iterate('alive', false, Phaser.Group.RETURN_CHILD);
},
@@ -1027,29 +1148,7 @@ Phaser.Group.prototype = {
*/
countLiving: function () {
- var total = 0;
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (currentNode.alive)
- {
- total++;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
- else
- {
- total = -1;
- }
-
- return total;
+ return this.iterate('alive', true, Phaser.Group.RETURN_TOTAL);
},
@@ -1061,29 +1160,7 @@ Phaser.Group.prototype = {
*/
countDead: function () {
- var total = 0;
-
- if (this._container.children.length > 0 && this._container.first._iNext)
- {
- var currentNode = this._container.first._iNext;
-
- do
- {
- if (!currentNode.alive)
- {
- total++;
- }
-
- currentNode = currentNode._iNext;
- }
- while (currentNode != this._container.last._iNext);
- }
- else
- {
- total = -1;
- }
-
- return total;
+ return this.iterate('alive', false, Phaser.Group.RETURN_TOTAL);
},
@@ -1228,6 +1305,48 @@ Phaser.Group.prototype = {
},
+ 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;
+
+ },
+
/**
* Dumps out a list of Group children and their index positions to the browser console. Useful for group debugging.
*
@@ -1334,7 +1453,8 @@ Phaser.Group.prototype = {
Object.defineProperty(Phaser.Group.prototype, "total", {
get: function () {
- return this._container.children.length;
+ return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
+ // return this._container.children.length;
}
});
@@ -1347,7 +1467,8 @@ Object.defineProperty(Phaser.Group.prototype, "total", {
Object.defineProperty(Phaser.Group.prototype, "length", {
get: function () {
- return this._container.children.length;
+ return this.iterate('exists', true, Phaser.Group.RETURN_TOTAL);
+ // return this._container.children.length;
}
});
diff --git a/src/core/Plugin.js b/src/core/Plugin.js
index 14cfc3d8..68a03029 100644
--- a/src/core/Plugin.js
+++ b/src/core/Plugin.js
@@ -50,6 +50,12 @@ Phaser.Plugin = function (game, parent) {
* @default
*/
this.hasUpdate = false;
+
+ /**
+ * @property {boolean} hasPostUpdate - A flag to indicate if this plugin has a postUpdate method.
+ * @default
+ */
+ this.hasPostUpdate = false;
/**
* @property {boolean} hasRender - A flag to indicate if this plugin has a render method.
diff --git a/src/core/PluginManager.js b/src/core/PluginManager.js
index 98eaea40..932d7bab 100644
--- a/src/core/PluginManager.js
+++ b/src/core/PluginManager.js
@@ -77,6 +77,12 @@ Phaser.PluginManager.prototype = {
result = true;
}
+ if (typeof plugin['postUpdate'] === 'function')
+ {
+ plugin.hasPostUpdate = true;
+ result = true;
+ }
+
if (typeof plugin['render'] === 'function')
{
plugin.hasRender = true;
@@ -176,6 +182,30 @@ Phaser.PluginManager.prototype = {
},
+ /**
+ * PostUpdate is the last thing to be called before the world render.
+ * In particular, it is called after the world postUpdate, which means the camera has been adjusted.
+ * It only calls plugins who have active=true.
+ *
+ * @method Phaser.PluginManager#postUpdate
+ */
+ postUpdate: function () {
+
+ if (this._pluginsLength == 0)
+ {
+ return;
+ }
+
+ for (this._p = 0; this._p < this._pluginsLength; this._p++)
+ {
+ if (this.plugins[this._p].active && this.plugins[this._p].hasPostUpdate)
+ {
+ this.plugins[this._p].postUpdate();
+ }
+ }
+
+ },
+
/**
* Render is called right after the Game Renderer completes, but before the State.render.
* It only calls plugins who have visible=true.
diff --git a/src/core/Stage.js b/src/core/Stage.js
index cff07d74..c19b69c0 100644
--- a/src/core/Stage.js
+++ b/src/core/Stage.js
@@ -45,6 +45,7 @@ Phaser.Stage = function (game, width, height) {
*/
this._stage = new PIXI.Stage(0x000000, false);
this._stage.name = '_stage_root';
+ this._stage.interactive = false;
/**
* @property {number} scaleMode - The current scaleMode.
diff --git a/src/core/World.js b/src/core/World.js
index 61bc6692..3f2d4609 100644
--- a/src/core/World.js
+++ b/src/core/World.js
@@ -258,3 +258,19 @@ 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/BitmapText.js b/src/gameobjects/BitmapText.js
index d9671e37..a6bcc596 100644
--- a/src/gameobjects/BitmapText.js
+++ b/src/gameobjects/BitmapText.js
@@ -155,7 +155,7 @@ Phaser.BitmapText.prototype.destroy = function() {
this.group.remove(this);
}
- if (this.canvas.parentNode)
+ if (this.canvas && this.canvas.parentNode)
{
this.canvas.parentNode.removeChild(this.canvas);
}
diff --git a/src/gameobjects/Button.js b/src/gameobjects/Button.js
index 2b09aafd..77ad8b1d 100644
--- a/src/gameobjects/Button.js
+++ b/src/gameobjects/Button.js
@@ -169,6 +169,13 @@ Phaser.Button = function (game, x, y, key, callback, callbackContext, overFrame,
*/
this.freezeFrames = false;
+ /**
+ * When the Button is clicked you can optionally force the state to "out".
+ * @property {boolean} forceOut
+ * @default
+ */
+ this.forceOut = true;
+
this.setFrames(overFrame, outFrame, downFrame);
if (callback !== null)
@@ -253,7 +260,7 @@ Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) {
{
this._onDownFrameName = downFrame;
- if (this.input.pointerOver())
+ if (this.input.pointerDown())
{
this.frameName = downFrame;
}
@@ -262,7 +269,7 @@ Phaser.Button.prototype.setFrames = function (overFrame, outFrame, downFrame) {
{
this._onDownFrameID = downFrame;
- if (this.input.pointerOver())
+ if (this.input.pointerDown())
{
this.frame = downFrame;
}
@@ -513,8 +520,21 @@ Phaser.Button.prototype.onInputUpHandler = function (pointer) {
this.onUpSound.play(this.onUpSoundMarker);
}
+ if (this.forceOut && this.freezeFrames == false)
+ {
+ if (this._onOutFrameName != null)
+ {
+ this.frameName = this._onOutFrameName;
+ }
+ else if (this._onOutFrameID != null)
+ {
+ this.frame = this._onOutFrameID;
+ }
+ }
+
if (this.onInputUp)
{
this.onInputUp.dispatch(this, pointer);
}
+
};
diff --git a/src/gameobjects/Graphics.js b/src/gameobjects/Graphics.js
index e2303e9f..a164dd71 100644
--- a/src/gameobjects/Graphics.js
+++ b/src/gameobjects/Graphics.js
@@ -50,6 +50,18 @@ Phaser.Graphics.prototype.destroy = function() {
}
+/*
+* Draws a {Phaser.Polygon} or a {PIXI.Polygon} filled
+*/
+Phaser.Graphics.prototype.drawPolygon = function (poly) {
+
+ graphics.moveTo(poly.points[0].x, poly.points[0].y);
+ for (var i = 1; i < poly.points.length; i += 1) {
+ graphics.lineTo(poly.points[i].x, poly.points[i].y);
+ }
+ graphics.lineTo(poly.points[0].x, poly.points[0].y);
+}
+
Object.defineProperty(Phaser.Graphics.prototype, 'angle', {
get: function() {
diff --git a/src/geom/Polygon.js b/src/geom/Polygon.js
new file mode 100644
index 00000000..671c44e5
--- /dev/null
+++ b/src/geom/Polygon.js
@@ -0,0 +1,30 @@
+/**
+* @author Richard Davey
+* @copyright 2013 Photon Storm Ltd.
+* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
+*/
+
+/**
+* Creates a new Polygon. You have to provide a list of points.
+* This can be an array of Points that form the polygon, a flat array of numbers that will be interpreted as [x,y, x,y, ...],
+* or the arguments passed can be all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the
+* arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are numbers.
+*
+* @class Phaser.Polygon
+* @classdesc The polygon represents a list of orderded points in space
+* @constructor
+* @param {Array|Array} points - The array of Points.
+*/
+Phaser.Polygon = function (points) {
+
+ PIXI.Polygon.call(this, points);
+
+ /**
+ * @property {number} type - The base object type.
+ */
+ this.type = Phaser.POLYGON;
+
+};
+
+Phaser.Polygon.prototype = Object.create(PIXI.Polygon.prototype);
+Phaser.Polygon.prototype.constructor = Phaser.Polygon;
\ No newline at end of file
diff --git a/src/input/InputHandler.js b/src/input/InputHandler.js
index 711f4c31..7b4f89d2 100644
--- a/src/input/InputHandler.js
+++ b/src/input/InputHandler.js
@@ -405,28 +405,60 @@ Phaser.InputHandler.prototype = {
/**
* Is the Pointer over this Sprite?
* @method Phaser.InputHandler#pointerOver
- * @param {Pointer} pointer
- * @return {bool
+ * @param {number} [index] - The ID number of a Pointer to check. If you don't provide a number it will check all Pointers.
+ * @return {boolean} True if the given pointer (if a index was given, or any pointer if not) is over this object.
*/
- pointerOver: function (pointer) {
+ pointerOver: function (index) {
- pointer = pointer || 0;
+ if (this.enabled)
+ {
+ if (typeof index === 'undefined')
+ {
+ for (var i = 0; i < 10; i++)
+ {
+ if (this._pointerData[i].isOver)
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ return this._pointerData[index].isOver;
+ }
+ }
- return this._pointerData[pointer].isOver;
+ return false;
},
/**
* Is the Pointer outside of this Sprite?
* @method Phaser.InputHandler#pointerOut
- * @param {Pointer} pointer
- * @return {boolean}
+ * @param {number} [index] - The ID number of a Pointer to check. If you don't provide a number it will check all Pointers.
+ * @return {boolean} True if the given pointer (if a index was given, or any pointer if not) is out of this object.
*/
pointerOut: function (pointer) {
- pointer = pointer || 0;
+ if (this.enabled)
+ {
+ if (typeof index === 'undefined')
+ {
+ for (var i = 0; i < 10; i++)
+ {
+ if (this._pointerData[i].isOut)
+ {
+ return true;
+ }
+ }
+ }
+ else
+ {
+ return this._pointerData[index].isOut;
+ }
+ }
- return this._pointerData[pointer].isOut;
+ return false;
},
@@ -502,12 +534,13 @@ Phaser.InputHandler.prototype = {
},
/**
- * Description.
- * @method Phaser.InputHandler#checkPixel
- * @param {Description} x - Description.
- * @param {Description} y - Description.
- * @return {boolean}
- */
+ * Runs a pixel perfect check against the given x/y coordinates of the Sprite this InputHandler is bound to.
+ * It compares the alpha value of the pixel and if >= InputHandler.pixelPerfectAlpha it returns true.
+ * @method Phaser.InputHandler#checkPixel
+ * @param {number} x - The x coordinate to check.
+ * @param {number} y - The y coordinate to check.
+ * @return {boolean} true if there is the alpha of the pixel is >= InputHandler.pixelPerfectAlpha
+ */
checkPixel: function (x, y) {
// Grab a pixel from our image into the hitCanvas and then test it
@@ -515,8 +548,6 @@ Phaser.InputHandler.prototype = {
{
this.game.input.hitContext.clearRect(0, 0, 1, 1);
- // This will fail if the image is part of a texture atlas - need to modify the x/y values here
-
x += this.sprite.texture.frame.x;
y += this.sprite.texture.frame.y;
diff --git a/src/input/Mouse.js b/src/input/Mouse.js
index 3a781c01..155666c0 100644
--- a/src/input/Mouse.js
+++ b/src/input/Mouse.js
@@ -25,23 +25,29 @@ Phaser.Mouse = function (game) {
this.callbackContext = this.game;
/**
- * @property {Description} mouseDownCallback - Description.
+ * @property {function} mouseDownCallback - Description.
* @default
*/
this.mouseDownCallback = null;
/**
- * @property {Description} mouseMoveCallback - Description.
+ * @property {function} mouseMoveCallback - Description.
* @default
*/
this.mouseMoveCallback = null;
/**
- * @property {Description} mouseUpCallback - Description.
+ * @property {function} mouseUpCallback - Description.
* @default
*/
this.mouseUpCallback = null;
+ /**
+ * @property {number} button- The type of click, either: Phaser.Mouse.NO_BUTTON, Phaser.Mouse.LEFT_BUTTON, Phaser.Mouse.MIDDLE_BUTTON or Phaser.Mouse.RIGHT_BUTTON.
+ * @default
+ */
+ this.button = -1;
+
/**
* You can disable all Input by setting disabled = true. While set all new input related events will be ignored.
* @property {boolean} disabled
@@ -56,8 +62,20 @@ Phaser.Mouse = function (game) {
*/
this.locked = false;
+ /**
+ * This event is dispatched when the browser enters or leaves pointer lock state.
+ * @property {Phaser.Signal} pointerLock
+ * @default
+ */
+ this.pointerLock = new Phaser.Signal;
+
};
+/**
+* @constant
+* @type {number}
+*/
+Phaser.Mouse.NO_BUTTON = -1;
/**
* @constant
* @type {number}
@@ -111,7 +129,7 @@ Phaser.Mouse.prototype = {
},
/**
- * Description.
+ * The internal method that handles the mouse down event from the browser.
* @method Phaser.Mouse#onMouseDown
* @param {MouseEvent} event
*/
@@ -119,6 +137,19 @@ Phaser.Mouse.prototype = {
event.preventDefault();
+ if (event.which === 1)
+ {
+ this.button = Phaser.Mouse.LEFT_BUTTON;
+ }
+ else if (event.which === 2)
+ {
+ this.button = Phaser.Mouse.MIDDLE_BUTTON;
+ }
+ else if (event.which === 3)
+ {
+ this.button = Phaser.Mouse.RIGHT_BUTTON;
+ }
+
if (this.mouseDownCallback)
{
this.mouseDownCallback.call(this.callbackContext, event);
@@ -136,7 +167,7 @@ Phaser.Mouse.prototype = {
},
/**
- * Description
+ * The internal method that handles the mouse move event from the browser.
* @method Phaser.Mouse#onMouseMove
* @param {MouseEvent} event
*/
@@ -161,7 +192,7 @@ Phaser.Mouse.prototype = {
},
/**
- * Description.
+ * The internal method that handles the mouse up event from the browser.
* @method Phaser.Mouse#onMouseUp
* @param {MouseEvent} event
*/
@@ -169,6 +200,8 @@ Phaser.Mouse.prototype = {
event.preventDefault();
+ this.button = Phaser.Mouse.NO_BUTTON;
+
if (this.mouseUpCallback)
{
this.mouseUpCallback.call(this.callbackContext, event);
@@ -186,7 +219,9 @@ Phaser.Mouse.prototype = {
},
/**
- * Description.
+ * If the browser supports it you can request that the pointer be locked to the browser window.
+ * This is classically known as 'FPS controls', where the pointer can't leave the browser until the user presses an exit key.
+ * If the browser successfully enters a locked state the event Phaser.Mouse.pointerLock will be dispatched and the first parameter will be 'true'.
* @method Phaser.Mouse#requestPointerLock
*/
requestPointerLock: function () {
@@ -205,15 +240,15 @@ Phaser.Mouse.prototype = {
return _this.pointerLockChange(event);
};
- document.addEventListener('pointerlockchange', this._pointerLockChange, false);
- document.addEventListener('mozpointerlockchange', this._pointerLockChange, false);
- document.addEventListener('webkitpointerlockchange', this._pointerLockChange, false);
+ document.addEventListener('pointerlockchange', this._pointerLockChange, true);
+ document.addEventListener('mozpointerlockchange', this._pointerLockChange, true);
+ document.addEventListener('webkitpointerlockchange', this._pointerLockChange, true);
}
},
/**
- * Description.
+ * Internal pointerLockChange handler.
* @method Phaser.Mouse#pointerLockChange
* @param {MouseEvent} event
*/
@@ -225,17 +260,19 @@ Phaser.Mouse.prototype = {
{
// Pointer was successfully locked
this.locked = true;
+ this.pointerLock.dispatch(true);
}
else
{
// Pointer was unlocked
this.locked = false;
+ this.pointerLock.dispatch(false);
}
},
/**
- * Description.
+ * Internal release pointer lock handler.
* @method Phaser.Mouse#releasePointerLock
*/
releasePointerLock: function () {
@@ -244,9 +281,9 @@ Phaser.Mouse.prototype = {
document.exitPointerLock();
- document.removeEventListener('pointerlockchange', this._pointerLockChange);
- document.removeEventListener('mozpointerlockchange', this._pointerLockChange);
- document.removeEventListener('webkitpointerlockchange', this._pointerLockChange);
+ document.removeEventListener('pointerlockchange', this._pointerLockChange, true);
+ document.removeEventListener('mozpointerlockchange', this._pointerLockChange, true);
+ document.removeEventListener('webkitpointerlockchange', this._pointerLockChange, true);
},
@@ -256,10 +293,10 @@ Phaser.Mouse.prototype = {
*/
stop: function () {
- this.game.stage.canvas.removeEventListener('mousedown', this._onMouseDown);
- this.game.stage.canvas.removeEventListener('mousemove', this._onMouseMove);
- this.game.stage.canvas.removeEventListener('mouseup', this._onMouseUp);
+ this.game.stage.canvas.removeEventListener('mousedown', this._onMouseDown, true);
+ this.game.stage.canvas.removeEventListener('mousemove', this._onMouseMove, true);
+ this.game.stage.canvas.removeEventListener('mouseup', this._onMouseUp, true);
}
-};
\ No newline at end of file
+};
diff --git a/src/input/Pointer.js b/src/input/Pointer.js
index 402e2e55..855846a6 100644
--- a/src/input/Pointer.js
+++ b/src/input/Pointer.js
@@ -397,7 +397,6 @@ Phaser.Pointer.prototype = {
}
return this;
-
}
// Work out which object is on the top
diff --git a/src/physics/arcade/ArcadePhysics.js b/src/physics/arcade/ArcadePhysics.js
index c825042f..533461b3 100644
--- a/src/physics/arcade/ArcadePhysics.js
+++ b/src/physics/arcade/ArcadePhysics.js
@@ -172,19 +172,19 @@ Phaser.Physics.Arcade.prototype = {
// If you're wondering why the velocity is halved and applied twice, read this: http://www.niksula.hut.fi/~hkankaan/Homepages/gravity.html
// Rotation
- this._velocityDelta = (this.computeVelocity(0, body, body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) / 2;
+ this._velocityDelta = (this.computeVelocity(0, body, body.angularVelocity, body.angularAcceleration, body.angularDrag, body.maxAngular) - body.angularVelocity) * this.game.time.physicsElapsed * 0.5 * 60;
body.angularVelocity += this._velocityDelta;
body.rotation += (body.angularVelocity * this.game.time.physicsElapsed);
body.angularVelocity += this._velocityDelta;
// Horizontal
- this._velocityDelta = (this.computeVelocity(1, body, body.velocity.x, body.acceleration.x, body.drag.x, body.maxVelocity.x) - body.velocity.x) / 2;
+ this._velocityDelta = (this.computeVelocity(1, body, body.velocity.x, body.acceleration.x, body.drag.x, body.maxVelocity.x) - body.velocity.x) * this.game.time.physicsElapsed * 0.5 * 60;
body.velocity.x += this._velocityDelta;
body.x += (body.velocity.x * this.game.time.physicsElapsed);
body.velocity.x += this._velocityDelta;
// Vertical
- this._velocityDelta = (this.computeVelocity(2, body, body.velocity.y, body.acceleration.y, body.drag.y, body.maxVelocity.y) - body.velocity.y) / 2;
+ this._velocityDelta = (this.computeVelocity(2, body, body.velocity.y, body.acceleration.y, body.drag.y, body.maxVelocity.y) - body.velocity.y) * this.game.time.physicsElapsed * 0.5 * 60;
body.velocity.y += this._velocityDelta;
body.y += (body.velocity.y * this.game.time.physicsElapsed);
body.velocity.y += this._velocityDelta;
diff --git a/src/pixi/InteractionManager.js b/src/pixi/InteractionManager.js
index bd803339..ad111752 100644
--- a/src/pixi/InteractionManager.js
+++ b/src/pixi/InteractionManager.js
@@ -1,10 +1,8 @@
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
-
-
-
-/**
+
+ /**
* The interaction manager deals with mouse and touch events. Any DisplayObject can be interactive
* This manager also supports multitouch.
*
@@ -50,6 +48,17 @@ PIXI.InteractionManager = function(stage)
this.pool = [];
this.interactiveItems = [];
+ this.interactionDOMElement = null;
+
+ //this will make it so that you dont have to call bind all the time
+ this.onMouseMove = this.onMouseMove.bind( this );
+ this.onMouseDown = this.onMouseDown.bind(this);
+ this.onMouseOut = this.onMouseOut.bind(this);
+ this.onMouseUp = this.onMouseUp.bind(this);
+
+ this.onTouchStart = this.onTouchStart.bind(this);
+ this.onTouchEnd = this.onTouchEnd.bind(this);
+ this.onTouchMove = this.onTouchMove.bind(this);
this.last = 0;
@@ -111,27 +120,68 @@ PIXI.InteractionManager.prototype.collectInteractiveSprite = function(displayObj
*/
PIXI.InteractionManager.prototype.setTarget = function(target)
{
+ this.target = target;
+
+ //check if the dom element has been set. If it has don't do anything
+ if( this.interactionDOMElement === null ) {
+
+ 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
+ * to receive those events
+ *
+ * @method setTargetDomElement
+ * @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);
+ }
+
+
if (window.navigator.msPointerEnabled)
{
// time to remove some of that zoom in ja..
- target.view.style["-ms-content-zooming"] = "none";
- target.view.style["-ms-touch-action"] = "none"
+ domElement.style['-ms-content-zooming'] = 'none';
+ domElement.style['-ms-touch-action'] = 'none';
// DO some window specific touch!
}
-
- this.target = target;
- target.view.addEventListener('mousemove', this.onMouseMove.bind(this), true);
- target.view.addEventListener('mousedown', this.onMouseDown.bind(this), true);
- document.body.addEventListener('mouseup', this.onMouseUp.bind(this), true);
- target.view.addEventListener('mouseout', this.onMouseOut.bind(this), true);
-
- // aint no multi touch just yet!
- target.view.addEventListener("touchstart", this.onTouchStart.bind(this), true);
- target.view.addEventListener("touchend", this.onTouchEnd.bind(this), true);
- target.view.addEventListener("touchmove", this.onTouchMove.bind(this), true);
+
+ this.interactionDOMElement = domElement;
+
+ domElement.addEventListener('mousemove', this.onMouseMove, true);
+ domElement.addEventListener('mousedown', this.onMouseDown, true);
+ domElement.addEventListener('mouseout', this.onMouseOut, true);
+
+ // aint no multi touch just yet!
+ domElement.addEventListener('touchstart', this.onTouchStart, true);
+ domElement.addEventListener('touchend', this.onTouchEnd, true);
+ domElement.addEventListener('touchmove', this.onTouchMove, true);
}
+
/**
* updates the state of interactive objects
*
@@ -173,7 +223,7 @@ PIXI.InteractionManager.prototype.update = function()
// loop through interactive objects!
var length = this.interactiveItems.length;
- this.target.view.style.cursor = "default";
+ this.interactionDOMElement.style.cursor = "default";
for (var i = 0; i < length; i++)
{
@@ -196,7 +246,7 @@ PIXI.InteractionManager.prototype.update = function()
// loks like there was a hit!
if(item.__hit)
{
- if(item.buttonMode)this.target.view.style.cursor = "pointer";
+ if(item.buttonMode) this.interactionDOMElement.style.cursor = "pointer";
if(!item.__isOver)
{
@@ -231,7 +281,7 @@ PIXI.InteractionManager.prototype.onMouseMove = function(event)
{
this.mouse.originalEvent = event || window.event; //IE uses window.event
// TODO optimize by not check EVERY TIME! maybe half as often? //
- var rect = this.target.view.getBoundingClientRect();
+ var rect = this.interactionDOMElement.getBoundingClientRect();
this.mouse.global.x = (event.clientX - rect.left) * (this.target.width / rect.width);
this.mouse.global.y = (event.clientY - rect.top) * ( this.target.height / rect.height);
@@ -302,7 +352,7 @@ PIXI.InteractionManager.prototype.onMouseOut = function(event)
{
var length = this.interactiveItems.length;
- this.target.view.style.cursor = "default";
+ this.interactionDOMElement.style.cursor = "default";
for (var i = 0; i < length; i++)
{
@@ -451,7 +501,7 @@ PIXI.InteractionManager.prototype.hitTest = function(item, interactionData)
*/
PIXI.InteractionManager.prototype.onTouchMove = function(event)
{
- var rect = this.target.view.getBoundingClientRect();
+ var rect = this.interactionDOMElement.getBoundingClientRect();
var changedTouches = event.changedTouches;
for (var i=0; i < changedTouches.length; i++)
@@ -482,7 +532,7 @@ PIXI.InteractionManager.prototype.onTouchMove = function(event)
*/
PIXI.InteractionManager.prototype.onTouchStart = function(event)
{
- var rect = this.target.view.getBoundingClientRect();
+ var rect = this.interactionDOMElement.getBoundingClientRect();
var changedTouches = event.changedTouches;
for (var i=0; i < changedTouches.length; i++)
@@ -532,7 +582,7 @@ PIXI.InteractionManager.prototype.onTouchStart = function(event)
PIXI.InteractionManager.prototype.onTouchEnd = function(event)
{
//this.mouse.originalEvent = event || window.event; //IE uses window.event
- var rect = this.target.view.getBoundingClientRect();
+ var rect = this.interactionDOMElement.getBoundingClientRect();
var changedTouches = event.changedTouches;
for (var i=0; i < changedTouches.length; i++)
diff --git a/src/pixi/Outro.js b/src/pixi/Outro.js
index e53cad5e..bf38bbc7 100644
--- a/src/pixi/Outro.js
+++ b/src/pixi/Outro.js
@@ -2,14 +2,14 @@
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
- if (typeof exports !== 'undefined') {
- if (typeof module !== 'undefined' && module.exports) {
- exports = module.exports = PIXI;
+ if (typeof exports !== 'undefined') {
+ if (typeof module !== 'undefined' && module.exports) {
+ exports = module.exports = PIXI;
+ }
+ exports.PIXI = PIXI;
+ } else if (typeof define !== 'undefined' && define.amd) {
+ define(PIXI);
+ } else {
+ root.PIXI = PIXI;
}
- exports.PIXI = PIXI;
- } else {
- root.PIXI = PIXI;
- }
-
-
}).call(this);
\ No newline at end of file
diff --git a/src/pixi/core/Circle.js b/src/pixi/core/Circle.js
index e36abe74..e2728335 100644
--- a/src/pixi/core/Circle.js
+++ b/src/pixi/core/Circle.js
@@ -7,9 +7,9 @@
*
* @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 radius {number} The radius of the circle
+ * @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 radius {Number} The radius of the circle
*/
PIXI.Circle = function(x, y, radius)
{
@@ -19,7 +19,7 @@ PIXI.Circle = function(x, y, radius)
* @default 0
*/
this.x = x || 0;
-
+
/**
* @property y
* @type Number
@@ -50,8 +50,8 @@ PIXI.Circle.prototype.clone = function()
* Checks if the x, and y coords 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
+ * @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
*/
PIXI.Circle.prototype.contains = function(x, y)
@@ -69,5 +69,6 @@ PIXI.Circle.prototype.contains = function(x, y)
return (dx + dy <= r2);
}
+// constructor
PIXI.Circle.prototype.constructor = PIXI.Circle;
diff --git a/src/pixi/core/Ellipse.js b/src/pixi/core/Ellipse.js
index 27428d39..1a95d20a 100644
--- a/src/pixi/core/Ellipse.js
+++ b/src/pixi/core/Ellipse.js
@@ -7,10 +7,10 @@
*
* @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 width {number} The overall height of this ellipse
- * @param height {number} The overall width of this ellipse
+ * @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 width {Number} The overall width of this ellipse
+ * @param height {Number} The overall height of this ellipse
*/
PIXI.Ellipse = function(x, y, width, height)
{
@@ -20,21 +20,21 @@ PIXI.Ellipse = function(x, y, width, height)
* @default 0
*/
this.x = x || 0;
-
+
/**
* @property y
* @type Number
* @default 0
*/
this.y = y || 0;
-
+
/**
* @property width
* @type Number
* @default 0
*/
this.width = width || 0;
-
+
/**
* @property height
* @type Number
@@ -58,8 +58,8 @@ PIXI.Ellipse.prototype.clone = function()
* Checks if the x, and y coords 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
+ * @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
*/
PIXI.Ellipse.prototype.contains = function(x, y)
@@ -83,5 +83,5 @@ PIXI.Ellipse.getBounds = function()
return new PIXI.Rectangle(this.x, this.y, this.width, this.height);
}
+// constructor
PIXI.Ellipse.prototype.constructor = PIXI.Ellipse;
-
diff --git a/src/pixi/core/Matrix.js b/src/pixi/core/Matrix.js
index 780fcd68..923682c6 100644
--- a/src/pixi/core/Matrix.js
+++ b/src/pixi/core/Matrix.js
@@ -27,7 +27,7 @@ PIXI.mat3.create = function()
matrix[6] = 0;
matrix[7] = 0;
matrix[8] = 1;
-
+
return matrix;
}
@@ -43,7 +43,7 @@ PIXI.mat3.identity = function(matrix)
matrix[6] = 0;
matrix[7] = 0;
matrix[8] = 1;
-
+
return matrix;
}
@@ -70,35 +70,35 @@ PIXI.mat4.create = function()
matrix[13] = 0;
matrix[14] = 0;
matrix[15] = 1;
-
+
return matrix;
}
-PIXI.mat3.multiply = function (mat, mat2, dest)
+PIXI.mat3.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],
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;
}
@@ -115,11 +115,11 @@ PIXI.mat3.clone = function(mat)
matrix[6] = mat[6];
matrix[7] = mat[7];
matrix[8] = mat[8];
-
+
return matrix;
}
-PIXI.mat3.transpose = function (mat, dest)
+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) {
@@ -147,30 +147,30 @@ PIXI.mat3.transpose = function (mat, dest)
return dest;
}
-PIXI.mat3.toMat4 = function (mat, 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;
}
@@ -198,19 +198,19 @@ PIXI.mat4.create = function()
matrix[13] = 0;
matrix[14] = 0;
matrix[15] = 1;
-
+
return matrix;
}
-PIXI.mat4.transpose = function (mat, dest)
+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 (!dest || mat === dest)
{
var a01 = mat[1], a02 = mat[2], a03 = mat[3],
a12 = mat[6], a13 = mat[7],
a23 = mat[11];
-
+
mat[1] = mat[4];
mat[2] = mat[8];
mat[3] = mat[12];
@@ -225,7 +225,7 @@ PIXI.mat4.transpose = function (mat, dest)
mat[14] = a23;
return mat;
}
-
+
dest[0] = mat[0];
dest[1] = mat[4];
dest[2] = mat[8];
@@ -245,18 +245,18 @@ PIXI.mat4.transpose = function (mat, dest)
return dest;
}
-PIXI.mat4.multiply = function (mat, mat2, dest)
+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];
+ 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;
diff --git a/src/pixi/core/Point.js b/src/pixi/core/Point.js
index d68175aa..7c7fe2d7 100644
--- a/src/pixi/core/Point.js
+++ b/src/pixi/core/Point.js
@@ -6,19 +6,19 @@
* The Point object represents a location in a two-dimensional coordinate system, where x represents the horizontal axis and y represents the vertical axis.
*
* @class Point
- * @constructor
- * @param x {number} position of the point
- * @param y {number} position of the point
+ * @constructor
+ * @param x {Number} position of the point
+ * @param y {Number} position of the point
*/
PIXI.Point = function(x, y)
{
/**
- * @property x
+ * @property x
* @type Number
* @default 0
*/
this.x = x || 0;
-
+
/**
* @property y
* @type Number
diff --git a/src/pixi/core/Polygon.js b/src/pixi/core/Polygon.js
index e40f13aa..4ef74f11 100644
--- a/src/pixi/core/Polygon.js
+++ b/src/pixi/core/Polygon.js
@@ -6,7 +6,7 @@
* @class Polygon
* @constructor
* @param points* {Array|Array|Point...|Number...} This can be an array of Points that form the polygon,
- * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arugments passed can be
+ * a flat array of numbers that will be interpreted as [x,y, x,y, ...], or the arguments passed can be
* all the points of the polygon e.g. `new PIXI.Polygon(new PIXI.Point(), new PIXI.Point(), ...)`, or the
* arguments passed can be flat x,y values e.g. `new PIXI.Polygon(x,y, x,y, x,y, ...)` where `x` and `y` are
* Numbers.
@@ -52,8 +52,8 @@ PIXI.Polygon.prototype.clone = function()
* Checks if the x, and y coords 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
+ * @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
*/
PIXI.Polygon.prototype.contains = function(x, y)
@@ -73,5 +73,5 @@ PIXI.Polygon.prototype.contains = function(x, y)
return inside;
}
+// constructor
PIXI.Polygon.prototype.constructor = PIXI.Polygon;
-
diff --git a/src/pixi/core/Rectangle.js b/src/pixi/core/Rectangle.js
index 7a7ba086..8a0e0402 100644
--- a/src/pixi/core/Rectangle.js
+++ b/src/pixi/core/Rectangle.js
@@ -6,11 +6,11 @@
* the Rectangle object is an area defined by its position, as indicated by its top-left corner point (x, y) and by its width and its height.
*
* @class Rectangle
- * @constructor
- * @param x {number} The X coord of the upper-left corner of the rectangle
- * @param y {number} The Y coord of the upper-left corner of the rectangle
- * @param width {number} The overall wisth of this rectangle
- * @param height {number} The overall height of this rectangle
+ * @constructor
+ * @param x {Number} The X coord of the upper-left corner of the rectangle
+ * @param y {Number} The Y coord of the upper-left corner of the rectangle
+ * @param width {Number} The overall width of this rectangle
+ * @param height {Number} The overall height of this rectangle
*/
PIXI.Rectangle = function(x, y, width, height)
{
@@ -20,21 +20,21 @@ PIXI.Rectangle = function(x, y, width, height)
* @default 0
*/
this.x = x || 0;
-
+
/**
* @property y
* @type Number
* @default 0
*/
this.y = y || 0;
-
+
/**
* @property width
* @type Number
* @default 0
*/
this.width = width || 0;
-
+
/**
* @property height
* @type Number
@@ -58,8 +58,8 @@ PIXI.Rectangle.prototype.clone = function()
* Checks if the x, and y coords 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
+ * @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
*/
PIXI.Rectangle.prototype.contains = function(x, y)
@@ -71,7 +71,7 @@ PIXI.Rectangle.prototype.contains = function(x, y)
if(x >= x1 && x <= x1 + this.width)
{
var y1 = this.y;
-
+
if(y >= y1 && y <= y1 + this.height)
{
return true;
diff --git a/src/pixi/display/DisplayObject.js b/src/pixi/display/DisplayObject.js
index 82d53663..256c8caa 100644
--- a/src/pixi/display/DisplayObject.js
+++ b/src/pixi/display/DisplayObject.js
@@ -12,7 +12,6 @@ PIXI.DisplayObject = function()
{
this.last = this;
this.first = this;
-
/**
* The coordinate of the object relative to the local coordinates of the parent.
*
@@ -165,6 +164,9 @@ PIXI.DisplayObject = function()
this._sr = 0;
this._cr = 1;
+
+ this.filterArea = new PIXI.Rectangle(0,0,1,1);
+
/*
* MOUSE Callbacks
*/
@@ -289,16 +291,71 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', {
},
set: function(value) {
- this._mask = value;
-
+
if(value)
{
- this.addFilter(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.removeFilter(this._mask);
+ this._mask.renderable = true;
}
+
+ this._mask = value;
+ }
+});
+
+/**
+ * Sets the filters for the displayObject.
+ * * IMPORTANT: This is a webGL only feature and will be ignored by the canvas renderer.
+ * To remove filters simply set this property to 'null'
+ * @property filters
+ * @type Array An array of filters
+ */
+Object.defineProperty(PIXI.DisplayObject.prototype, 'filters', {
+ get: function() {
+ return this._filters;
+ },
+ set: function(value) {
+
+ 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++)
+ {
+ var filterPasses = value[i].passes;
+ for (var j = 0; j < filterPasses.length; j++)
+ {
+ passes.push(filterPasses[j]);
+ };
+ };
+
+ value.start.filterPasses = passes;
+ }
+ else
+ {
+ if(this._filters)this.removeFilter(this._filters);
+ }
+
+ this._filters = value;
+
+
+
+
}
});
@@ -309,23 +366,31 @@ Object.defineProperty(PIXI.DisplayObject.prototype, 'mask', {
* @param mask {Graphics} the graphics object to use as a filter
* @private
*/
-PIXI.DisplayObject.prototype.addFilter = function(mask)
+PIXI.DisplayObject.prototype.addFilter = function(data)
{
- if(this.filter)return;
- this.filter = true;
+ //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();
- start.mask = mask;
- end.mask = mask;
+ 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
*/
@@ -397,8 +462,6 @@ PIXI.DisplayObject.prototype.addFilter = function(mask)
this.__renderGroup.addFilterBlocks(start, end);
}
- mask.renderable = false;
-
}
/*
@@ -407,13 +470,14 @@ PIXI.DisplayObject.prototype.addFilter = function(mask)
* @method removeFilter
* @private
*/
-PIXI.DisplayObject.prototype.removeFilter = function()
+PIXI.DisplayObject.prototype.removeFilter = function(data)
{
- if(!this.filter)return;
- this.filter = false;
-
+ //if(!this.filter)return;
+ //this.filter = false;
+ console.log("YUOIO")
// modify the list..
- var startBlock = this.first;
+ var startBlock = data.start;
+
var nextObject = startBlock._iNext;
var previousObject = startBlock._iPrev;
@@ -423,9 +487,8 @@ PIXI.DisplayObject.prototype.removeFilter = function()
this.first = startBlock._iNext;
-
// remove the end filter
- var lastBlock = this.last;
+ var lastBlock = data.end;
var nextObject = lastBlock._iNext;
var previousObject = lastBlock._iPrev;
@@ -444,9 +507,6 @@ PIXI.DisplayObject.prototype.removeFilter = function()
if(!updateLast)break;
}
- var mask = startBlock.mask
- mask.renderable = true;
-
// if webGL...
if(this.__renderGroup)
{
diff --git a/src/pixi/display/DisplayObjectContainer.js b/src/pixi/display/DisplayObjectContainer.js
index 43891296..09d5b0ce 100644
--- a/src/pixi/display/DisplayObjectContainer.js
+++ b/src/pixi/display/DisplayObjectContainer.js
@@ -29,18 +29,6 @@ PIXI.DisplayObjectContainer = function()
PIXI.DisplayObjectContainer.prototype = Object.create( PIXI.DisplayObject.prototype );
PIXI.DisplayObjectContainer.prototype.constructor = PIXI.DisplayObjectContainer;
-//TODO make visible a getter setter
-/*
-Object.defineProperty(PIXI.DisplayObjectContainer.prototype, 'visible', {
- get: function() {
- return this._visible;
- },
- set: function(value) {
- this._visible = value;
-
- }
-});*/
-
/**
* Adds a child to the container.
*
@@ -84,7 +72,7 @@ PIXI.DisplayObjectContainer.prototype.addChild = function(child)
var previousObject;
// this could be wrong if there is a filter??
- if(this.filter)
+ if(this._filters || this._mask)
{
previousObject = this.last._iPrev;
}
@@ -134,7 +122,7 @@ PIXI.DisplayObjectContainer.prototype.addChild = function(child)
*
* @method addChildAt
* @param child {DisplayObject} The child to add
- * @param index {number} The index to place the child in
+ * @param index {Number} The index to place the child in
*/
PIXI.DisplayObjectContainer.prototype.addChildAt = function(child, index)
{
@@ -269,7 +257,7 @@ PIXI.DisplayObjectContainer.prototype.swapChildren = function(child, child2)
* Returns the Child at the specified index
*
* @method getChildAt
- * @param index {number} The index to get the child from
+ * @param index {Number} The index to get the child from
*/
PIXI.DisplayObjectContainer.prototype.getChildAt = function(index)
{
@@ -365,4 +353,4 @@ PIXI.DisplayObjectContainer.prototype.updateTransform = function()
{
this.children[i].updateTransform();
}
-}
+}
\ No newline at end of file
diff --git a/src/pixi/display/MovieClip.js b/src/pixi/display/MovieClip.js
index 5f984078..8a669d92 100644
--- a/src/pixi/display/MovieClip.js
+++ b/src/pixi/display/MovieClip.js
@@ -13,7 +13,7 @@
PIXI.MovieClip = function(textures)
{
PIXI.Sprite.call(this, textures[0]);
-
+
/**
* The array of textures that make up the animation
*
@@ -21,7 +21,7 @@ PIXI.MovieClip = function(textures)
* @type Array
*/
this.textures = textures;
-
+
/**
* The speed that the MovieClip will play at. Higher is faster, lower is slower
*
@@ -47,7 +47,7 @@ PIXI.MovieClip = function(textures)
* @type Function
*/
this.onComplete = null;
-
+
/**
* [read-only] The index MovieClips current frame (this may not have to be a whole number)
*
@@ -56,8 +56,8 @@ PIXI.MovieClip = function(textures)
* @default 0
* @readOnly
*/
- this.currentFrame = 0;
-
+ this.currentFrame = 0;
+
/**
* [read-only] Indicates if the MovieClip is currently playing
*
@@ -72,6 +72,23 @@ PIXI.MovieClip = function(textures)
PIXI.MovieClip.prototype = Object.create( PIXI.Sprite.prototype );
PIXI.MovieClip.prototype.constructor = PIXI.MovieClip;
+/**
+* [read-only] totalFrames is the total number of frames in the MovieClip. This is the same as number of textures
+* assigned to the MovieClip.
+*
+* @property totalFrames
+* @type Number
+* @default 0
+* @readOnly
+*/
+Object.defineProperty( PIXI.MovieClip.prototype, 'totalFrames', {
+ get: function() {
+
+ return this.textures.length;
+ }
+});
+
+
/**
* Stops the MovieClip
*
@@ -96,7 +113,7 @@ PIXI.MovieClip.prototype.play = function()
* Stops the MovieClip and goes to a specific frame
*
* @method gotoAndStop
- * @param frameNumber {number} frame index to stop at
+ * @param frameNumber {Number} frame index to stop at
*/
PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber)
{
@@ -110,7 +127,7 @@ PIXI.MovieClip.prototype.gotoAndStop = function(frameNumber)
* Goes to a specific frame and begins playing the MovieClip
*
* @method gotoAndPlay
- * @param frameNumber {number} frame index to start at
+ * @param frameNumber {Number} frame index to start at
*/
PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber)
{
@@ -127,13 +144,13 @@ PIXI.MovieClip.prototype.gotoAndPlay = function(frameNumber)
PIXI.MovieClip.prototype.updateTransform = function()
{
PIXI.Sprite.prototype.updateTransform.call(this);
-
+
if(!this.playing)return;
-
+
this.currentFrame += this.animationSpeed;
-
+
var round = (this.currentFrame + 0.5) | 0;
-
+
if(this.loop || round < this.textures.length)
{
this.setTexture(this.textures[round % this.textures.length]);
diff --git a/src/pixi/display/Sprite.js b/src/pixi/display/Sprite.js
index 4041d43c..e567c795 100644
--- a/src/pixi/display/Sprite.js
+++ b/src/pixi/display/Sprite.js
@@ -152,7 +152,7 @@ PIXI.Sprite.prototype.setTexture = function(texture)
PIXI.Sprite.prototype.onTextureUpdate = function(event)
{
//this.texture.removeEventListener( 'update', this.onTextureUpdateBind );
-
+
// so if _width is 0 then width was not set..
if(this._width)this.scale.x = this._width / this.texture.frame.width;
if(this._height)this.scale.y = this._height / this.texture.frame.height;
@@ -194,4 +194,3 @@ PIXI.Sprite.fromImage = function(imageId)
var texture = PIXI.Texture.fromImage(imageId);
return new PIXI.Sprite(texture);
}
-
diff --git a/src/pixi/display/Stage.js b/src/pixi/display/Stage.js
index 02830cfe..513c0ad0 100644
--- a/src/pixi/display/Stage.js
+++ b/src/pixi/display/Stage.js
@@ -8,11 +8,10 @@
* @class Stage
* @extends DisplayObjectContainer
* @constructor
- * @param backgroundColor {number} the background color of the stage, easiest way to pass this in is in hex format
+ * @param backgroundColor {Number} the background color of the stage, easiest way to pass this in is in hex format
* like: 0xFFFFFF for white
- * @param interactive {Boolean} enable / disable interaction (default is false)
*/
-PIXI.Stage = function(backgroundColor, interactive)
+PIXI.Stage = function(backgroundColor)
{
PIXI.DisplayObjectContainer.call( this );
@@ -32,7 +31,7 @@ PIXI.Stage = function(backgroundColor, interactive)
* @property interactive
* @type Boolean
*/
- this.interactive = interactive;
+ this.interactive = true;
/**
* The interaction manage for this stage, manages all interactive activity on the stage
@@ -68,6 +67,18 @@ PIXI.Stage = function(backgroundColor, interactive)
PIXI.Stage.prototype = Object.create( PIXI.DisplayObjectContainer.prototype );
PIXI.Stage.prototype.constructor = PIXI.Stage;
+/**
+ * Sets another DOM element which can receive mouse/touch interactions instead of the default Canvas element.
+ * This is useful for when you have other DOM elements ontop of the Canvas element.
+ *
+ * @method setInteractionDelegate
+ * @param domElement {DOMElement} This new domElement which will receive mouse/touch events
+ */
+PIXI.Stage.prototype.setInteractionDelegate = function(domElement)
+{
+ this.interactionManager.setTargetDomElement( domElement );
+}
+
/*
* Updates the object transform for rendering
*
@@ -99,7 +110,7 @@ PIXI.Stage.prototype.updateTransform = function()
* Sets the background color for the stage
*
* @method setBackgroundColor
- * @param backgroundColor {number} the color of the background, easiest way to pass this in is in hex format
+ * @param backgroundColor {Number} the color of the background, easiest way to pass this in is in hex format
* like: 0xFFFFFF for white
*/
PIXI.Stage.prototype.setBackgroundColor = function(backgroundColor)
diff --git a/src/pixi/extras/CustomRenderable.js b/src/pixi/extras/CustomRenderable.js
index eb0dc5bf..24b2258b 100644
--- a/src/pixi/extras/CustomRenderable.js
+++ b/src/pixi/extras/CustomRenderable.js
@@ -6,7 +6,7 @@
/**
* This object is one that will allow you to specify custom rendering functions based on render type
*
- * @class CustomRenderable
+ * @class CustomRenderable
* @extends DisplayObject
* @constructor
*/
@@ -14,6 +14,7 @@ PIXI.CustomRenderable = function()
{
PIXI.DisplayObject.call( this );
+ this.renderable = true;
}
// constructor
diff --git a/src/pixi/extras/Rope.js b/src/pixi/extras/Rope.js
index 1c057c84..754306db 100644
--- a/src/pixi/extras/Rope.js
+++ b/src/pixi/extras/Rope.js
@@ -7,7 +7,7 @@ PIXI.Rope = function(texture, points)
{
PIXI.Strip.call( this, texture );
this.points = points;
-
+
try
{
this.verticies = new Float32Array( points.length * 4);
@@ -18,12 +18,12 @@ PIXI.Rope = function(texture, points)
catch(error)
{
this.verticies = verticies
-
+
this.uvs = uvs
this.colors = colors
this.indices = indices
}
-
+
this.refresh();
}
@@ -36,99 +36,99 @@ PIXI.Rope.prototype.refresh = function()
{
var points = this.points;
if(points.length < 1)return;
-
+
var uvs = this.uvs
var indices = this.indices;
var colors = this.colors;
-
+
var lastPoint = points[0];
var nextPoint;
var perp = {x:0, y:0};
var point = points[0];
-
+
this.count-=0.2;
-
-
+
+
uvs[0] = 0
uvs[1] = 1
uvs[2] = 0
uvs[3] = 1
-
+
colors[0] = 1;
colors[1] = 1;
-
+
indices[0] = 0;
indices[1] = 1;
-
+
var total = points.length;
-
- for (var i = 1; i < total; i++)
+
+ for (var i = 1; i < total; i++)
{
-
+
var point = points[i];
var index = i * 4;
// time to do some smart drawing!
var amount = i/(total-1)
-
+
if(i%2)
{
uvs[index] = amount;
uvs[index+1] = 0;
-
+
uvs[index+2] = amount
uvs[index+3] = 1
-
+
}
else
{
uvs[index] = amount
uvs[index+1] = 0
-
+
uvs[index+2] = amount
uvs[index+3] = 1
}
-
+
index = i * 2;
colors[index] = 1;
colors[index+1] = 1;
-
+
index = i * 2;
indices[index] = index;
indices[index + 1] = index + 1;
-
+
lastPoint = point;
}
}
PIXI.Rope.prototype.updateTransform = function()
{
-
+
var points = this.points;
if(points.length < 1)return;
-
- var verticies = this.verticies
-
+
+ var verticies = this.verticies
+
var lastPoint = points[0];
var nextPoint;
var perp = {x:0, y:0};
var point = points[0];
-
+
this.count-=0.2;
-
- verticies[0] = point.x + perp.x
+
+ verticies[0] = point.x + perp.x
verticies[1] = point.y + perp.y //+ 200
- verticies[2] = point.x - perp.x
+ verticies[2] = point.x - perp.x
verticies[3] = point.y - perp.y//+200
// time to do some smart drawing!
-
+
var total = points.length;
-
- for (var i = 1; i < total; i++)
+
+ for (var i = 1; i < total; i++)
{
-
+
var point = points[i];
var index = i * 4;
-
+
if(i < points.length-1)
{
nextPoint = points[i+1];
@@ -137,35 +137,35 @@ PIXI.Rope.prototype.updateTransform = function()
{
nextPoint = point
}
-
+
perp.y = -(nextPoint.x - lastPoint.x);
perp.x = nextPoint.y - lastPoint.y;
-
+
var ratio = (1 - (i / (total-1))) * 10;
if(ratio > 1)ratio = 1;
-
+
var perpLength = Math.sqrt(perp.x * perp.x + perp.y * perp.y);
var num = this.texture.height/2//(20 + Math.abs(Math.sin((i + this.count) * 0.3) * 50) )* ratio;
perp.x /= perpLength;
perp.y /= perpLength;
-
+
perp.x *= num;
perp.y *= num;
-
- verticies[index] = point.x + perp.x
+
+ verticies[index] = point.x + perp.x
verticies[index+1] = point.y + perp.y
- verticies[index+2] = point.x - perp.x
+ verticies[index+2] = point.x - perp.x
verticies[index+3] = point.y - perp.y
lastPoint = point;
}
-
+
PIXI.DisplayObjectContainer.prototype.updateTransform.call( this );
}
PIXI.Rope.prototype.setTexture = function(texture)
{
- // stop current texture
+ // stop current texture
this.texture = texture;
this.updateFrame = true;
}
diff --git a/src/pixi/extras/Spine.js b/src/pixi/extras/Spine.js
index 8dda8c1f..27995ae6 100644
--- a/src/pixi/extras/Spine.js
+++ b/src/pixi/extras/Spine.js
@@ -125,9 +125,9 @@ PIXI.Spine.prototype.createSprite = function (slot, descriptor) {
/*
* Awesome JS run time provided by EsotericSoftware
- *
+ *
* https://github.com/EsotericSoftware/spine-runtimes
- *
+ *
*/
var spine = {};
diff --git a/src/pixi/extras/Strip.js b/src/pixi/extras/Strip.js
index 1e5ba3bf..857e4129 100644
--- a/src/pixi/extras/Strip.js
+++ b/src/pixi/extras/Strip.js
@@ -7,20 +7,20 @@ PIXI.Strip = function(texture, width, height)
PIXI.DisplayObjectContainer.call( this );
this.texture = texture;
this.blendMode = PIXI.blendModes.NORMAL;
-
+
try
{
this.uvs = new Float32Array([0, 1,
1, 1,
1, 0, 0,1]);
-
+
this.verticies = new Float32Array([0, 0,
0,0,
0,0, 0,
0, 0]);
-
+
this.colors = new Float32Array([1, 1, 1, 1]);
-
+
this.indices = new Uint16Array([0, 1, 2, 3]);
}
catch(error)
@@ -28,18 +28,18 @@ PIXI.Strip = function(texture, width, height)
this.uvs = [0, 1,
1, 1,
1, 0, 0,1];
-
+
this.verticies = [0, 0,
0,0,
0,0, 0,
0, 0];
-
+
this.colors = [1, 1, 1, 1];
-
+
this.indices = [0, 1, 2, 3];
}
-
-
+
+
/*
this.uvs = new Float32Array()
this.verticies = new Float32Array()
@@ -48,7 +48,7 @@ PIXI.Strip = function(texture, width, height)
*/
this.width = width;
this.height = height;
-
+
// load the texture!
if(texture.baseTexture.hasLoaded)
{
@@ -61,7 +61,7 @@ PIXI.Strip = function(texture, width, height)
this.onTextureUpdateBind = this.onTextureUpdate.bind(this);
this.texture.addEventListener( 'update', this.onTextureUpdateBind );
}
-
+
this.renderable = true;
}
@@ -73,8 +73,8 @@ PIXI.Strip.prototype.setTexture = function(texture)
{
//TODO SET THE TEXTURES
//TODO VISIBILITY
-
- // stop current texture
+
+ // stop current texture
this.texture = texture;
this.width = texture.frame.width;
this.height = texture.frame.height;
diff --git a/src/pixi/extras/TilingSprite.js b/src/pixi/extras/TilingSprite.js
index f52465c7..be2e93fa 100644
--- a/src/pixi/extras/TilingSprite.js
+++ b/src/pixi/extras/TilingSprite.js
@@ -9,8 +9,8 @@
* @extends DisplayObjectContainer
* @constructor
* @param texture {Texture} the texture of the tiling sprite
- * @param width {number} the width of the tiling sprite
- * @param height {number} the height of the tiling sprite
+ * @param width {Number} the width of the tiling sprite
+ * @param height {Number} the height of the tiling sprite
*/
PIXI.TilingSprite = function(texture, width, height)
{
@@ -45,7 +45,7 @@ PIXI.TilingSprite = function(texture, width, height)
*
* @property tileScale
* @type Point
- */
+ */
this.tileScale = new PIXI.Point(1,1);
/**
@@ -53,11 +53,11 @@ PIXI.TilingSprite = function(texture, width, height)
*
* @property tilePosition
* @type Point
- */
+ */
this.tilePosition = new PIXI.Point(0,0);
this.renderable = true;
-
+
this.blendMode = PIXI.blendModes.NORMAL
}
@@ -75,8 +75,8 @@ PIXI.TilingSprite.prototype.setTexture = function(texture)
{
//TODO SET THE TEXTURES
//TODO VISIBILITY
-
- // stop current texture
+
+ // stop current texture
this.texture = texture;
this.updateFrame = true;
}
diff --git a/src/pixi/filters/AbstractFilter.js b/src/pixi/filters/AbstractFilter.js
new file mode 100644
index 00000000..c1e22b47
--- /dev/null
+++ b/src/pixi/filters/AbstractFilter.js
@@ -0,0 +1,37 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+/**
+ * This is the base class for creating a pixi.js filter. Currently only webGL supports filters.
+ * If you want to make a custom filter this should be your base class.
+ * @class AbstractFilter
+ * @constructor
+ * @param fragmentSrc
+ * @param unifroms
+ */
+PIXI.AbstractFilter = function(fragmentSrc, unifroms)
+{
+ /**
+ * An array of passes - some filters contain a few steps this array simply stores the steps in a liniear fashion.
+ * For example the blur filter has two passes blurX and blurY.
+ * @property passes
+ * @type Array an array of filter objects
+ * @private
+ */
+ this.passes = [this];
+
+
+ this.dirty = true;
+ this.padding = 0;
+
+ /**
+ @property uniforms
+ @private
+ */
+ this.uniforms = unifroms || {};
+
+ this.fragmentSrc = fragmentSrc || [];
+}
+
diff --git a/src/pixi/filters/BlurFilter.js b/src/pixi/filters/BlurFilter.js
new file mode 100644
index 00000000..43caa0c4
--- /dev/null
+++ b/src/pixi/filters/BlurFilter.js
@@ -0,0 +1,70 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+/**
+ *
+ * The BlurFilter applies a Gaussian blur to an object.
+ * The strength of the blur can be set for x- and y-axis separately (always relative to the stage).
+ *
+ * @class BlurFilter
+ * @contructor
+ */
+PIXI.BlurFilter = function()
+{
+
+ this.blurXFilter = new PIXI.BlurXFilter();
+ this.blurYFilter = new PIXI.BlurYFilter();
+
+ this.passes =[this.blurXFilter, this.blurYFilter];
+
+}
+
+/**
+ * Sets the strength of both the blurX and blurY properties simultaneously
+ *
+ * @property blur
+ * @type Number the strength of the blur
+ * @default 2
+ */
+Object.defineProperty(PIXI.BlurFilter.prototype, 'blur', {
+ get: function() {
+ return this.blurXFilter.blur;
+ },
+ set: function(value) {
+ this.blurXFilter.blur = this.blurYFilter.blur = value;
+ }
+});
+
+/**
+ * Sets the strength of the blurX property simultaneously
+ *
+ * @property blurX
+ * @type Number the strength of the blurX
+ * @default 2
+ */
+Object.defineProperty(PIXI.BlurFilter.prototype, 'blurX', {
+ get: function() {
+ return this.blurXFilter.blur;
+ },
+ set: function(value) {
+ this.blurXFilter.blur = value;
+ }
+});
+
+/**
+ * Sets the strength of the blurX property simultaneously
+ *
+ * @property blurY
+ * @type Number the strength of the blurY
+ * @default 2
+ */
+Object.defineProperty(PIXI.BlurFilter.prototype, 'blurY', {
+ get: function() {
+ return this.blurYFilter.blur;
+ },
+ set: function(value) {
+ this.blurYFilter.blur = value;
+ }
+});
diff --git a/src/pixi/filters/BlurXFilter.js b/src/pixi/filters/BlurXFilter.js
new file mode 100644
index 00000000..7fef33c3
--- /dev/null
+++ b/src/pixi/filters/BlurXFilter.js
@@ -0,0 +1,56 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+
+PIXI.BlurXFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ blur: {type: 'f', value: 1/512},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float blur;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "vec4 sum = vec4(0.0);",
+
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x - 4.0*blur, vTextureCoord.y)) * 0.05;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x - 3.0*blur, vTextureCoord.y)) * 0.09;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x - 2.0*blur, vTextureCoord.y)) * 0.12;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x - blur, vTextureCoord.y)) * 0.15;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x + blur, vTextureCoord.y)) * 0.15;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x + 2.0*blur, vTextureCoord.y)) * 0.12;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x + 3.0*blur, vTextureCoord.y)) * 0.09;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x + 4.0*blur, vTextureCoord.y)) * 0.05;",
+
+ "gl_FragColor = sum;",
+
+ "}"
+ ];
+}
+
+PIXI.BlurXFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.BlurXFilter.prototype.constructor = PIXI.BlurXFilter;
+
+
+Object.defineProperty(PIXI.BlurXFilter.prototype, 'blur', {
+ get: function() {
+ return this.uniforms.blur.value / (1/7000);
+ },
+ set: function(value) {
+
+ this.dirty = true;
+ this.uniforms.blur.value = (1/7000) * value;
+ }
+});
diff --git a/src/pixi/filters/BlurYFilter.js b/src/pixi/filters/BlurYFilter.js
new file mode 100644
index 00000000..4b9d352c
--- /dev/null
+++ b/src/pixi/filters/BlurYFilter.js
@@ -0,0 +1,54 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+
+PIXI.BlurYFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ blur: {type: 'f', value: 1/512},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float blur;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "vec4 sum = vec4(0.0);",
+
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 4.0*blur)) * 0.05;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 3.0*blur)) * 0.09;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - 2.0*blur)) * 0.12;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y - blur)) * 0.15;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y)) * 0.16;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + blur)) * 0.15;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 2.0*blur)) * 0.12;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 3.0*blur)) * 0.09;",
+ "sum += texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y + 4.0*blur)) * 0.05;",
+
+ "gl_FragColor = sum;",
+
+ "}"
+ ];
+}
+
+PIXI.BlurYFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.BlurYFilter.prototype.constructor = PIXI.BlurYFilter;
+
+Object.defineProperty(PIXI.BlurYFilter.prototype, 'blur', {
+ get: function() {
+ return this.uniforms.blur.value / (1/7000);
+ },
+ set: function(value) {
+ //this.padding = value;
+ this.uniforms.blur.value = (1/7000) * value;
+ }
+});
diff --git a/src/pixi/filters/ColorMatrixFilter.js b/src/pixi/filters/ColorMatrixFilter.js
new file mode 100644
index 00000000..1386f8b2
--- /dev/null
+++ b/src/pixi/filters/ColorMatrixFilter.js
@@ -0,0 +1,59 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+/**
+ *
+ * The ColorMatrixFilter class lets you apply a 4x4 matrix transformation on the RGBA
+ * color and alpha values of every pixel on your displayObject to produce a result
+ * with a new set of RGBA color and alpha values. Its pretty powerful!
+ * @class ColorMatrixFilter
+ * @contructor
+ */
+PIXI.ColorMatrixFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ matrix: {type: 'mat4', value: [1,0,0,0,
+ 0,1,0,0,
+ 0,0,1,0,
+ 0,0,0,1]},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float invert;",
+ "uniform mat4 matrix;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "gl_FragColor = texture2D(uSampler, vTextureCoord) * matrix;",
+ "gl_FragColor = gl_FragColor * vColor;",
+ "}"
+ ];
+
+}
+
+PIXI.ColorMatrixFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.ColorMatrixFilter.prototype.constructor = PIXI.ColorMatrixFilter;
+
+/**
+ * Sets the matrix of the color matrix filter
+ *
+ * @property matrix
+ * @type Array and array of 26 numbers
+ * @default [1,0,0,0,0,1,0,0,0,0,1,0,0,0,0,1]
+ */
+Object.defineProperty(PIXI.ColorMatrixFilter.prototype, 'matrix', {
+ get: function() {
+ return this.uniforms.matrix.value;
+ },
+ set: function(value) {
+ this.uniforms.matrix.value = value;
+ }
+});
\ No newline at end of file
diff --git a/src/pixi/filters/ColorStepFilter.js b/src/pixi/filters/ColorStepFilter.js
new file mode 100644
index 00000000..ebf040bd
--- /dev/null
+++ b/src/pixi/filters/ColorStepFilter.js
@@ -0,0 +1,51 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+/**
+ *
+ * This turns your displayObjects to black and white.
+ * @class GreyFilter
+ * @contructor
+ */
+PIXI.ColorStepFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ step: {type: 'f', value: 5},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform sampler2D uSampler;",
+ "uniform float step;",
+ "void main(void) {",
+ "vec4 color = texture2D(uSampler, vTextureCoord);",
+ "color = floor(color * step) / step;",
+ "gl_FragColor = color * vColor;",
+ "}"
+ ];
+}
+
+PIXI.ColorStepFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.ColorStepFilter.prototype.constructor = PIXI.ColorStepFilter;
+
+/**
+The number of steps.
+@property step
+*/
+Object.defineProperty(PIXI.ColorStepFilter.prototype, 'step', {
+ get: function() {
+ return this.uniforms.step.value;
+ },
+ set: function(value) {
+ this.uniforms.step.value = value;
+ }
+});
diff --git a/src/pixi/filters/CrossHatchFilter.js b/src/pixi/filters/CrossHatchFilter.js
new file mode 100644
index 00000000..cd050cb0
--- /dev/null
+++ b/src/pixi/filters/CrossHatchFilter.js
@@ -0,0 +1,69 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+
+PIXI.CrossHatchFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ blur: {type: 'f', value: 1/512},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float blur;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+
+
+ " float lum = length(texture2D(uSampler, vTextureCoord.xy).rgb);",
+ " ",
+ " gl_FragColor = vec4(1.0, 1.0, 1.0, 1.0);",
+ " ",
+ " if (lum < 1.00) {",
+ " if (mod(gl_FragCoord.x + gl_FragCoord.y, 10.0) == 0.0) {",
+ " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);",
+ " }",
+ " }",
+ " ",
+ " if (lum < 0.75) {",
+ " if (mod(gl_FragCoord.x - gl_FragCoord.y, 10.0) == 0.0) {",
+ " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);",
+ " }",
+ " }",
+ " ",
+ " if (lum < 0.50) {",
+ " if (mod(gl_FragCoord.x + gl_FragCoord.y - 5.0, 10.0) == 0.0) {",
+ " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);",
+ " }",
+ " }",
+ " ",
+ " if (lum < 0.3) {",
+ " if (mod(gl_FragCoord.x - gl_FragCoord.y - 5.0, 10.0) == 0.0) {",
+ " gl_FragColor = vec4(0.0, 0.0, 0.0, 1.0);",
+ " }",
+ " }",
+ "}"
+ ];
+}
+
+PIXI.CrossHatchFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.CrossHatchFilter.prototype.constructor = PIXI.BlurYFilter;
+
+Object.defineProperty(PIXI.CrossHatchFilter.prototype, 'blur', {
+ get: function() {
+ return this.uniforms.blur.value / (1/7000);
+ },
+ set: function(value) {
+ //this.padding = value;
+ this.uniforms.blur.value = (1/7000) * value;
+ }
+});
diff --git a/src/pixi/filters/DisplacementFilter.js b/src/pixi/filters/DisplacementFilter.js
new file mode 100644
index 00000000..6c05498d
--- /dev/null
+++ b/src/pixi/filters/DisplacementFilter.js
@@ -0,0 +1,135 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+/**
+ *
+ * The DisplacementFilter 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 DisplacementFilter
+ * @contructor
+ * @param texture {Texture} The texture used for the displacemtent map * must be power of 2 texture at the moment
+ */
+PIXI.DisplacementFilter = 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: 'f2', value:{x:30, y:30}},
+ offset: {type: 'f2', value:{x:0, y:0}},
+ mapDimensions: {type: 'f2', value:{x:1, y:5112}},
+ dimensions: {type: 'f4', value:[0,0,0,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 vec2 scale;",
+ "uniform vec2 offset;",
+ "uniform vec4 dimensions;",
+ "uniform vec2 mapDimensions;",// = vec2(256.0, 256.0);",
+ // "const vec2 textureDimensions = vec2(750.0, 750.0);",
+
+ "void main(void) {",
+ "vec2 mapCords = vTextureCoord.xy;",
+// "mapCords -= ;",
+ "mapCords += (dimensions.zw + offset)/ dimensions.xy ;",
+ "mapCords.y *= -1.0;",
+ "mapCords.y += 1.0;",
+ "vec2 matSample = texture2D(displacementMap, mapCords).xy;",
+ "matSample -= 0.5;",
+ "matSample *= scale;",
+ "matSample /= mapDimensions;",
+ "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x + matSample.x, vTextureCoord.y + matSample.y));",
+ "gl_FragColor.rgb = mix( gl_FragColor.rgb, gl_FragColor.rgb, 1.0);",
+ "vec2 cord = vTextureCoord;",
+
+ //"gl_FragColor = texture2D(displacementMap, cord);",
+ "gl_FragColor = gl_FragColor * vColor;",
+
+ "}"
+ ];
+
+}
+
+PIXI.DisplacementFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.DisplacementFilter.prototype.constructor = PIXI.DisplacementFilter;
+
+PIXI.DisplacementFilter.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.DisplacementFilter.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.DisplacementFilter.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.DisplacementFilter.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/DotScreenFilter.js b/src/pixi/filters/DotScreenFilter.js
new file mode 100644
index 00000000..f9f5452e
--- /dev/null
+++ b/src/pixi/filters/DotScreenFilter.js
@@ -0,0 +1,86 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ * original filter: https://github.com/evanw/glfx.js/blob/master/src/filters/fun/dotscreen.js
+ */
+
+/**
+ *
+ * This filter applies a pixlate effect making display objects appear "blocky"
+ * @class PixelateFilter
+ * @contructor
+ */
+PIXI.DotScreenFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ scale: {type: 'f', value:1},
+ angle: {type: 'f', value:5},
+ dimensions: {type: 'f4', value:[0,0,0,0]}
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform vec4 dimensions;",
+ "uniform sampler2D uSampler;",
+
+ "uniform float angle;",
+ "uniform float scale;",
+
+ "float pattern() {",
+ "float s = sin(angle), c = cos(angle);",
+ "vec2 tex = vTextureCoord * dimensions.xy;",
+ "vec2 point = vec2(",
+ "c * tex.x - s * tex.y,",
+ "s * tex.x + c * tex.y",
+ ") * scale;",
+ "return (sin(point.x) * sin(point.y)) * 4.0;",
+ "}",
+
+ "void main() {",
+ "vec4 color = texture2D(uSampler, vTextureCoord);",
+ "float average = (color.r + color.g + color.b) / 3.0;",
+ "gl_FragColor = vec4(vec3(average * 10.0 - 5.0 + pattern()), color.a);",
+ "}",
+ ];
+}
+
+PIXI.DotScreenFilter.prototype = Object.create( PIXI.DotScreenFilter.prototype );
+PIXI.DotScreenFilter.prototype.constructor = PIXI.DotScreenFilter;
+
+/**
+ *
+ * This describes the the scale
+ * @property scale
+ * @type Number
+ */
+Object.defineProperty(PIXI.DotScreenFilter.prototype, 'scale', {
+ get: function() {
+ return this.uniforms.scale.value;
+ },
+ set: function(value) {
+ this.dirty = true;
+ this.uniforms.scale.value = value;
+ }
+});
+
+/**
+ *
+ * This radius describes angle
+ * @property angle
+ * @type Number
+ */
+Object.defineProperty(PIXI.DotScreenFilter.prototype, 'angle', {
+ get: function() {
+ return this.uniforms.angle.value;
+ },
+ set: function(value) {
+ this.dirty = true;
+ this.uniforms.angle.value = value;
+ }
+});
\ No newline at end of file
diff --git a/src/pixi/filters/FilterBlock.js b/src/pixi/filters/FilterBlock.js
index c4732338..bfcfdb77 100644
--- a/src/pixi/filters/FilterBlock.js
+++ b/src/pixi/filters/FilterBlock.js
@@ -4,10 +4,8 @@
-PIXI.FilterBlock = function(mask)
+PIXI.FilterBlock = function()
{
- this.graphics = mask
this.visible = true;
this.renderable = true;
-}
-
+}
\ No newline at end of file
diff --git a/src/pixi/filters/GreyFilter.js b/src/pixi/filters/GreyFilter.js
new file mode 100644
index 00000000..d182975f
--- /dev/null
+++ b/src/pixi/filters/GreyFilter.js
@@ -0,0 +1,51 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+/**
+ *
+ * This turns your displayObjects to black and white.
+ * @class GreyFilter
+ * @contructor
+ */
+PIXI.GreyFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ grey: {type: 'f', value: 1},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform sampler2D uSampler;",
+ "uniform float grey;",
+ "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), grey);",
+ "gl_FragColor = gl_FragColor * vColor;",
+ "}"
+ ];
+}
+
+PIXI.GreyFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.GreyFilter.prototype.constructor = PIXI.GreyFilter;
+
+/**
+The strength of the grey. 1 will make the object black and white, 0 will make the object its normal color
+@property grey
+*/
+Object.defineProperty(PIXI.GreyFilter.prototype, 'grey', {
+ get: function() {
+ return this.uniforms.grey.value;
+ },
+ set: function(value) {
+ this.uniforms.grey.value = value;
+ }
+});
diff --git a/src/pixi/filters/InvertFilter.js b/src/pixi/filters/InvertFilter.js
new file mode 100644
index 00000000..3d6ee784
--- /dev/null
+++ b/src/pixi/filters/InvertFilter.js
@@ -0,0 +1,52 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+/**
+ *
+ * This inverts your displayObjects colors.
+ * @class InvertFilter
+ * @contructor
+ */
+PIXI.InvertFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ invert: {type: 'f', value: 1},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float invert;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "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;",
+ "}"
+ ];
+
+}
+
+PIXI.InvertFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.InvertFilter.prototype.constructor = PIXI.InvertFilter;
+
+/**
+The strength of the invert. 1 will fully invert the colors, 0 will make the object its normal color
+@property invert
+*/
+Object.defineProperty(PIXI.InvertFilter.prototype, 'invert', {
+ get: function() {
+ return this.uniforms.invert.value;
+ },
+ set: function(value) {
+ this.uniforms.invert.value = value;
+ }
+});
\ No newline at end of file
diff --git a/src/pixi/filters/PixelateFilter.js b/src/pixi/filters/PixelateFilter.js
new file mode 100644
index 00000000..bc6eb354
--- /dev/null
+++ b/src/pixi/filters/PixelateFilter.js
@@ -0,0 +1,62 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+/**
+ *
+ * This filter applies a pixlate effect making display objects appear "blocky"
+ * @class PixelateFilter
+ * @contructor
+ */
+PIXI.PixelateFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ invert: {type: 'f', value: 0},
+ dimensions: {type: 'f4', value:new Float32Array([10000, 100, 10, 10])},
+ pixelSize: {type: 'f2', value:{x:10, y:10}},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform vec2 testDim;",
+ "uniform vec4 dimensions;",
+ "uniform vec2 pixelSize;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "vec2 coord = vTextureCoord;",
+
+ "vec2 size = dimensions.xy/pixelSize;",
+
+ "vec2 color = floor( ( vTextureCoord * size ) ) / size + pixelSize/dimensions.xy * 0.5;",
+ "gl_FragColor = texture2D(uSampler, color);",
+ "}"
+ ];
+
+
+}
+
+PIXI.PixelateFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.PixelateFilter.prototype.constructor = PIXI.PixelateFilter;
+
+/**
+ *
+ * This a point that describes the size of the blocs. x is the width of the block and y is the the height
+ * @property size
+ * @type Point
+ */
+Object.defineProperty(PIXI.PixelateFilter.prototype, 'size', {
+ get: function() {
+ return this.uniforms.pixelSize.value;
+ },
+ set: function(value) {
+ this.dirty = true;
+ this.uniforms.pixelSize.value = value;
+ }
+});
\ No newline at end of file
diff --git a/src/pixi/filters/RGBSplitFilter.js b/src/pixi/filters/RGBSplitFilter.js
new file mode 100644
index 00000000..5303d646
--- /dev/null
+++ b/src/pixi/filters/RGBSplitFilter.js
@@ -0,0 +1,50 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+
+PIXI.RGBSplitFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ red: {type: 'f2', value: {x:20, y:20}},
+ green: {type: 'f2', value: {x:-20, y:20}},
+ blue: {type: 'f2', value: {x:20, y:-20}},
+ dimensions: {type: 'f4', value:[0,0,0,0]}
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform vec2 red;",
+ "uniform vec2 green;",
+ "uniform vec2 blue;",
+ "uniform vec4 dimensions;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "gl_FragColor.r = texture2D(uSampler, vTextureCoord + red/dimensions.xy).r;",
+ "gl_FragColor.g = texture2D(uSampler, vTextureCoord + green/dimensions.xy).g;",
+ "gl_FragColor.b = texture2D(uSampler, vTextureCoord + blue/dimensions.xy).b;",
+ "gl_FragColor.a = texture2D(uSampler, vTextureCoord).a;",
+ "}"
+ ];
+}
+
+PIXI.RGBSplitFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.RGBSplitFilter.prototype.constructor = PIXI.RGBSplitFilter;
+
+Object.defineProperty(PIXI.RGBSplitFilter.prototype, 'angle', {
+ get: function() {
+ return this.uniforms.blur.value / (1/7000);
+ },
+ set: function(value) {
+ //this.padding = value;
+ this.uniforms.blur.value = (1/7000) * value;
+ }
+});
diff --git a/src/pixi/filters/SepiaFilter.js b/src/pixi/filters/SepiaFilter.js
new file mode 100644
index 00000000..b3209337
--- /dev/null
+++ b/src/pixi/filters/SepiaFilter.js
@@ -0,0 +1,55 @@
+/**
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+/**
+ *
+ * This applies a sepia effect to your displayObjects.
+ * @class SepiaFilter
+ * @contructor
+ */
+PIXI.SepiaFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ sepia: {type: 'f', value: 1},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float sepia;",
+ "uniform sampler2D uSampler;",
+
+ "const mat3 sepiaMatrix = mat3(0.3588, 0.7044, 0.1368, 0.2990, 0.5870, 0.1140, 0.2392, 0.4696, 0.0912);",
+ "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;",
+ "}"
+ ];
+
+}
+
+PIXI.SepiaFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.SepiaFilter.prototype.constructor = PIXI.SepiaFilter;
+
+/**
+The strength of the sepia. 1 will apply the full sepia effect, 0 will make the object its normal color
+@property sepia
+*/
+Object.defineProperty(PIXI.SepiaFilter.prototype, 'sepia', {
+ get: function() {
+ return this.uniforms.sepia.value;
+ },
+ set: function(value) {
+ this.uniforms.sepia.value = value;
+ }
+});
diff --git a/src/pixi/filters/SmartBlurFilter.js b/src/pixi/filters/SmartBlurFilter.js
new file mode 100644
index 00000000..b0ddf87a
--- /dev/null
+++ b/src/pixi/filters/SmartBlurFilter.js
@@ -0,0 +1,64 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+
+PIXI.SmartBlurFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ blur: {type: 'f', value: 1/512},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "uniform sampler2D uSampler;",
+ // "uniform vec2 delta;",
+ "const vec2 delta = vec2(1.0/10.0, 0.0);",
+ // "uniform float darkness;",
+
+ "float random(vec3 scale, float seed) {",
+ "return fract(sin(dot(gl_FragCoord.xyz + seed, scale)) * 43758.5453 + seed);",
+ "}",
+
+
+ "void main(void) {",
+
+ "vec4 color = vec4(0.0);",
+ "float total = 0.0;",
+
+ "float offset = random(vec3(12.9898, 78.233, 151.7182), 0.0);",
+
+ "for (float t = -30.0; t <= 30.0; t++) {",
+ "float percent = (t + offset - 0.5) / 30.0;",
+ "float weight = 1.0 - abs(percent);",
+ "vec4 sample = texture2D(uSampler, vTextureCoord + delta * percent);",
+ "sample.rgb *= sample.a;",
+ "color += sample * weight;",
+ "total += weight;",
+ "}",
+
+ "gl_FragColor = color / total;",
+ "gl_FragColor.rgb /= gl_FragColor.a + 0.00001;",
+ // "gl_FragColor.rgb *= darkness;",
+ "}"
+ ];
+}
+
+PIXI.SmartBlurFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.SmartBlurFilter.prototype.constructor = PIXI.SmartBlurFilter;
+
+Object.defineProperty(PIXI.SmartBlurFilter.prototype, 'blur', {
+ get: function() {
+ return this.uniforms.blur.value;
+ },
+ set: function(value) {
+ this.uniforms.blur.value = value;
+ }
+});
diff --git a/src/pixi/filters/TwistFilter.js b/src/pixi/filters/TwistFilter.js
new file mode 100644
index 00000000..b477b0b3
--- /dev/null
+++ b/src/pixi/filters/TwistFilter.js
@@ -0,0 +1,103 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+/**
+ *
+ * This filter applies a pixlate effect making display objects appear "blocky"
+ * @class PixelateFilter
+ * @contructor
+ */
+PIXI.TwistFilter = function()
+{
+ PIXI.AbstractFilter.call( this );
+
+ this.passes = [this];
+
+ // set the uniforms
+ this.uniforms = {
+ radius: {type: 'f', value:0.5},
+ angle: {type: 'f', value:5},
+ offset: {type: 'f2', value:{x:0.5, y:0.5}},
+ };
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform vec4 dimensions;",
+ "uniform sampler2D uSampler;",
+
+ "uniform float radius;",
+ "uniform float angle;",
+ "uniform vec2 offset;",
+
+ "void main(void) {",
+ "vec2 coord = vTextureCoord - offset;",
+ "float distance = length(coord);",
+
+ "if (distance < radius){",
+
+ "float ratio = (radius - distance) / radius;",
+ "float angleMod = ratio * ratio * angle;",
+ "float s = sin(angleMod);",
+ "float c = cos(angleMod);",
+ "coord = vec2(coord.x * c - coord.y * s, coord.x * s + coord.y * c);",
+
+ "}",
+
+ "gl_FragColor = texture2D(uSampler, coord+offset);",
+ "}"
+ ];
+}
+
+PIXI.TwistFilter.prototype = Object.create( PIXI.AbstractFilter.prototype );
+PIXI.TwistFilter.prototype.constructor = PIXI.TwistFilter;
+
+/**
+ *
+ * This point describes the the offset of the twist
+ * @property size
+ * @type Point
+ */
+Object.defineProperty(PIXI.TwistFilter.prototype, 'offset', {
+ get: function() {
+ return this.uniforms.offset.value;
+ },
+ set: function(value) {
+ this.dirty = true;
+ this.uniforms.offset.value = value;
+ }
+});
+
+/**
+ *
+ * This radius describes size of the twist
+ * @property size
+ * @type Number
+ */
+Object.defineProperty(PIXI.TwistFilter.prototype, 'radius', {
+ get: function() {
+ return this.uniforms.radius.value;
+ },
+ set: function(value) {
+ this.dirty = true;
+ this.uniforms.radius.value = value;
+ }
+});
+
+/**
+ *
+ * This radius describes angle of the twist
+ * @property angle
+ * @type Number
+ */
+Object.defineProperty(PIXI.TwistFilter.prototype, 'angle', {
+ get: function() {
+ return this.uniforms.angle.value;
+ },
+ set: function(value) {
+ this.dirty = true;
+ this.uniforms.angle.value = value;
+ }
+});
\ No newline at end of file
diff --git a/src/pixi/loaders/AssetLoader.js b/src/pixi/loaders/AssetLoader.js
index 168a5f86..02e02a96 100644
--- a/src/pixi/loaders/AssetLoader.js
+++ b/src/pixi/loaders/AssetLoader.js
@@ -54,8 +54,8 @@ PIXI.AssetLoader = function(assetURLs, crossorigin)
"xml": PIXI.BitmapFontLoader,
"fnt": PIXI.BitmapFontLoader
};
-
-
+
+
};
/**
@@ -65,7 +65,7 @@ PIXI.AssetLoader = function(assetURLs, crossorigin)
/**
* Fired when all the assets have loaded
- * @event onComplete
+ * @event onComplete
*/
// constructor
@@ -112,7 +112,7 @@ PIXI.AssetLoader.prototype.onAssetLoaded = function()
this.loadCount--;
this.dispatchEvent({type: "onProgress", content: this});
if(this.onProgress) this.onProgress();
-
+
if(this.loadCount == 0)
{
this.dispatchEvent({type: "onComplete", content: this});
diff --git a/src/pixi/loaders/BitmapFontLoader.js b/src/pixi/loaders/BitmapFontLoader.js
index 4afd8aa2..ef050943 100644
--- a/src/pixi/loaders/BitmapFontLoader.js
+++ b/src/pixi/loaders/BitmapFontLoader.js
@@ -110,20 +110,19 @@ PIXI.BitmapFontLoader.prototype.onXMLLoaded = function()
{
var charCode = parseInt(letters[i].attributes.getNamedItem("id").nodeValue, 10);
- var textureRect = {
- x: parseInt(letters[i].attributes.getNamedItem("x").nodeValue, 10),
- y: parseInt(letters[i].attributes.getNamedItem("y").nodeValue, 10),
- width: parseInt(letters[i].attributes.getNamedItem("width").nodeValue, 10),
- height: parseInt(letters[i].attributes.getNamedItem("height").nodeValue, 10)
- };
- PIXI.TextureCache[charCode] = new PIXI.Texture(this.texture, textureRect);
+ 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)
+ );
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),
kerning: {},
- texture:new PIXI.Texture(this.texture, textureRect)
+ texture: PIXI.TextureCache[charCode] = new PIXI.Texture(this.texture, textureRect)
};
}
diff --git a/src/pixi/loaders/ImageLoader.js b/src/pixi/loaders/ImageLoader.js
index 971c0129..d8a41374 100644
--- a/src/pixi/loaders/ImageLoader.js
+++ b/src/pixi/loaders/ImageLoader.js
@@ -24,6 +24,13 @@ PIXI.ImageLoader = function(url, crossorigin)
* @type Texture
*/
this.texture = PIXI.Texture.fromImage(url, crossorigin);
+
+ /**
+ * if the image is loaded with loadFramedSpriteSheet
+ * frames will contain the sprite sheet frames
+ *
+ */
+ this.frames = [];
};
// constructor
@@ -60,3 +67,48 @@ PIXI.ImageLoader.prototype.onLoaded = function()
{
this.dispatchEvent({type: "loaded", content: this});
};
+
+/**
+ * Loads image and split it to uniform sized frames
+ *
+ *
+ * @method loadFramedSpriteSheet
+ * @param frameWidth {Number} with of each frame
+ * @param frameHeight {Number} height of each frame
+ * @param textureName {String} if given, the frames will be cached in - format
+ */
+PIXI.ImageLoader.prototype.loadFramedSpriteSheet = function(frameWidth, frameHeight, textureName)
+{
+ this.frames = [];
+ var cols = Math.floor(this.texture.width / frameWidth);
+ var rows = Math.floor(this.texture.height / frameHeight);
+
+ var i=0;
+ for (var y=0; y 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;
+ };
+ }
+
+ };
+
+ this.bounds = new PIXI.Rectangle(minX, minY, maxX - minX, maxY - minY);
+
+ }
+
+// console.log(this.bounds);
}
// SOME TYPES:
diff --git a/src/pixi/renderers/canvas/CanvasGraphics.js b/src/pixi/renderers/canvas/CanvasGraphics.js
index 7f1093b9..f5352b9b 100644
--- a/src/pixi/renderers/canvas/CanvasGraphics.js
+++ b/src/pixi/renderers/canvas/CanvasGraphics.js
@@ -10,7 +10,7 @@
*/
PIXI.CanvasGraphics = function()
{
-
+
}
@@ -26,33 +26,33 @@ PIXI.CanvasGraphics = function()
PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
{
var worldAlpha = graphics.worldAlpha;
-
- for (var i=0; i < graphics.graphicsData.length; i++)
+
+ for (var i=0; i < graphics.graphicsData.length; i++)
{
var data = graphics.graphicsData[i];
var points = data.points;
-
+
context.strokeStyle = color = '#' + ('00000' + ( data.lineColor | 0).toString(16)).substr(-6);
context.lineWidth = data.lineWidth;
-
+
if(data.type == PIXI.Graphics.POLY)
{
context.beginPath();
-
+
context.moveTo(points[0], points[1]);
-
+
for (var j=1; j < points.length/2; j++)
{
context.lineTo(points[j * 2], points[j * 2 + 1]);
- }
-
+ }
+
// if the first and last point are the same close the path - much neater :)
if(points[0] == points[points.length-2] && points[1] == points[points.length-1])
{
context.closePath();
}
-
+
if(data.fill)
{
context.globalAlpha = data.fillAlpha * worldAlpha;
@@ -67,21 +67,20 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
}
else if(data.type == PIXI.Graphics.RECT)
{
-
- // TODO - need to be Undefined!
- if(data.fillColor)
+
+ if(data.fillColor || data.fillColor === 0)
{
context.globalAlpha = data.fillAlpha * worldAlpha;
context.fillStyle = color = '#' + ('00000' + ( data.fillColor | 0).toString(16)).substr(-6);
context.fillRect(points[0], points[1], points[2], points[3]);
-
+
}
if(data.lineWidth)
{
context.globalAlpha = data.lineAlpha * worldAlpha;
context.strokeRect(points[0], points[1], points[2], points[3]);
}
-
+
}
else if(data.type == PIXI.Graphics.CIRC)
{
@@ -89,7 +88,7 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
context.beginPath();
context.arc(points[0], points[1], points[2],0,2*Math.PI);
context.closePath();
-
+
if(data.fill)
{
context.globalAlpha = data.fillAlpha * worldAlpha;
@@ -104,19 +103,19 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
}
else if(data.type == PIXI.Graphics.ELIP)
{
-
+
// elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
-
+
var elipseData = data.points;
-
+
var w = elipseData[2] * 2;
var h = elipseData[3] * 2;
-
+
var x = elipseData[0] - w/2;
var y = elipseData[1] - h/2;
-
+
context.beginPath();
-
+
var kappa = .5522848,
ox = (w / 2) * kappa, // control point offset horizontal
oy = (h / 2) * kappa, // control point offset vertical
@@ -124,15 +123,15 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
ye = y + h, // y-end
xm = x + w / 2, // x-middle
ym = y + h / 2; // y-middle
-
+
context.moveTo(x, ym);
context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
context.bezierCurveTo(xe, ym + oy, xm + ox, ye, xm, ye);
context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
-
+
context.closePath();
-
+
if(data.fill)
{
context.globalAlpha = data.fillAlpha * worldAlpha;
@@ -145,7 +144,7 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
context.stroke();
}
}
-
+
};
}
@@ -161,35 +160,37 @@ PIXI.CanvasGraphics.renderGraphics = function(graphics, context)
PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
{
var worldAlpha = graphics.worldAlpha;
-
+
var len = graphics.graphicsData.length;
+ if(len === 0)return;
+
if(len > 1)
{
len = 1;
console.log("Pixi.js warning: masks in canvas can only mask using the first path in the graphics object")
}
-
- for (var i=0; i < 1; i++)
+
+ for (var i=0; i < 1; i++)
{
var data = graphics.graphicsData[i];
var points = data.points;
-
+
if(data.type == PIXI.Graphics.POLY)
{
context.beginPath();
context.moveTo(points[0], points[1]);
-
+
for (var j=1; j < points.length/2; j++)
{
context.lineTo(points[j * 2], points[j * 2 + 1]);
- }
-
+ }
+
// if the first and last point are the same close the path - much neater :)
if(points[0] == points[points.length-2] && points[1] == points[points.length-1])
{
context.closePath();
}
-
+
}
else if(data.type == PIXI.Graphics.RECT)
{
@@ -206,18 +207,18 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
}
else if(data.type == PIXI.Graphics.ELIP)
{
-
+
// elipse code taken from: http://stackoverflow.com/questions/2172798/how-to-draw-an-oval-in-html5-canvas
var elipseData = data.points;
-
+
var w = elipseData[2] * 2;
var h = elipseData[3] * 2;
-
+
var x = elipseData[0] - w/2;
var y = elipseData[1] - h/2;
-
+
context.beginPath();
-
+
var kappa = .5522848,
ox = (w / 2) * kappa, // control point offset horizontal
oy = (h / 2) * kappa, // control point offset vertical
@@ -225,7 +226,7 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
ye = y + h, // y-end
xm = x + w / 2, // x-middle
ym = y + h / 2; // y-middle
-
+
context.moveTo(x, ym);
context.bezierCurveTo(x, ym - oy, xm - ox, y, xm, y);
context.bezierCurveTo(xm + ox, y, xe, ym - oy, xe, ym);
@@ -233,7 +234,7 @@ PIXI.CanvasGraphics.renderGraphicsMask = function(graphics, context)
context.bezierCurveTo(xm - ox, ye, x, ym + oy, x, ym);
context.closePath();
}
-
-
+
+
};
}
diff --git a/src/pixi/renderers/canvas/CanvasRenderer.js b/src/pixi/renderers/canvas/CanvasRenderer.js
index 8dbb6256..1e927d30 100644
--- a/src/pixi/renderers/canvas/CanvasRenderer.js
+++ b/src/pixi/renderers/canvas/CanvasRenderer.js
@@ -9,8 +9,8 @@
*
* @class CanvasRenderer
* @constructor
- * @param width=0 {number} the width of the canvas view
- * @param height=0 {number} the height of the canvas view
+ * @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
*/
@@ -114,8 +114,8 @@ PIXI.CanvasRenderer.prototype.render = function(stage)
* resizes the canvas view to the specified width and height
*
* @method resize
- * @param width {number} the new width of the canvas view
- * @param height {number} the new height of the canvas view
+ * @param width {Number} the new width of the canvas view
+ * @param height {Number} the new height of the canvas view
*/
PIXI.CanvasRenderer.prototype.resize = function(width, height)
{
@@ -163,9 +163,10 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject)
if(displayObject instanceof PIXI.Sprite)
{
+
var frame = displayObject.texture.frame;
- if(frame)
+ if(frame && frame.width && frame.height)
{
context.globalAlpha = displayObject.worldAlpha;
@@ -194,6 +195,7 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(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)
@@ -203,27 +205,36 @@ PIXI.CanvasRenderer.prototype.renderDisplayObject = function(displayObject)
}
else if(displayObject instanceof PIXI.FilterBlock)
{
- if(displayObject.open)
- {
- context.save();
-
- var cacheAlpha = displayObject.mask.alpha;
- var maskTransform = displayObject.mask.worldTransform;
-
- context.setTransform(maskTransform[0], maskTransform[3], maskTransform[1], maskTransform[4], maskTransform[2], maskTransform[5])
-
- displayObject.mask.worldAlpha = 0.5;
-
- context.worldAlpha = 0;
-
- PIXI.CanvasGraphics.renderGraphicsMask(displayObject.mask, context);
- context.clip();
-
- displayObject.mask.worldAlpha = cacheAlpha;
+ 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();
+ }
}
else
{
- context.restore();
+ // only masks supported right now!
}
}
// count++
diff --git a/src/pixi/renderers/webgl/PixiShader.js b/src/pixi/renderers/webgl/PixiShader.js
new file mode 100644
index 00000000..7b6a50f9
--- /dev/null
+++ b/src/pixi/renderers/webgl/PixiShader.js
@@ -0,0 +1,119 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+PIXI.PixiShader = function()
+{
+ // the webGL program..
+ this.program;
+
+ this.fragmentSrc = [
+ "precision lowp float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "gl_FragColor = texture2D(uSampler, vTextureCoord) * vColor;",
+ "}"
+ ];
+
+}
+
+PIXI.PixiShader.prototype.init = function()
+{
+ var program = PIXI.compileProgram(this.vertexSrc || PIXI.PixiShader.defaultVertexSrc, this.fragmentSrc)
+
+ var gl = PIXI.gl;
+
+ gl.useProgram(program);
+
+ // get and store the uniforms for the shader
+ this.uSampler = gl.getUniformLocation(program, "uSampler");
+ this.projectionVector = gl.getUniformLocation(program, "projectionVector");
+ this.offsetVector = gl.getUniformLocation(program, "offsetVector");
+ //this.dimensions = gl.getUniformLocation(this.program, "dimensions");
+
+ // get and store the attributes
+ this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
+ this.colorAttribute = gl.getAttribLocation(program, "aColor");
+ this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord");
+
+ // add those custom shaders!
+ for (var key in this.uniforms)
+ {
+
+ // get the uniform locations..
+ // program[key] =
+ this.uniforms[key].uniformLocation = gl.getUniformLocation(program, key);
+
+
+ }
+
+ this.program = program;
+}
+
+PIXI.PixiShader.prototype.syncUniforms = function()
+{
+ var gl = PIXI.gl;
+
+ for (var key in this.uniforms)
+ {
+ //var
+ var type = this.uniforms[key].type;
+
+ // need to grow this!
+ if(type == "f")
+ {
+ gl.uniform1f(this.uniforms[key].uniformLocation, this.uniforms[key].value);
+ }
+ if(type == "f2")
+ {
+ // console.log(this.program[key])
+ gl.uniform2f(this.uniforms[key].uniformLocation, this.uniforms[key].value.x, this.uniforms[key].value.y);
+ }
+ else if(type == "f4")
+ {
+ // console.log(this.uniforms[key].value)
+ gl.uniform4fv(this.uniforms[key].uniformLocation, this.uniforms[key].value);
+ }
+ else if(type == "mat4")
+ {
+ gl.uniformMatrix4fv(this.uniforms[key].uniformLocation, false, this.uniforms[key].value);
+ }
+ else if(type == "sampler2D")
+ {
+ // first texture...
+ var texture = this.uniforms[key].value;
+
+ gl.activeTexture(gl.TEXTURE1);
+ gl.bindTexture(gl.TEXTURE_2D, texture.baseTexture._glTexture);
+
+ gl.uniform1i(this.uniforms[key].uniformLocation, 1);
+
+ // activate texture..
+ // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
+ // gl.uniformMatrix4fv(this.program[key], false, this.uniforms[key].value);
+ }
+ }
+
+}
+
+PIXI.PixiShader.defaultVertexSrc = [
+ "attribute vec2 aVertexPosition;",
+ "attribute vec2 aTextureCoord;",
+ "attribute float aColor;",
+
+ "uniform vec2 projectionVector;",
+ "uniform vec2 offsetVector;",
+ "varying vec2 vTextureCoord;",
+
+ "varying float vColor;",
+
+ "const vec2 center = vec2(-1.0, 1.0);",
+ "void main(void) {",
+ "gl_Position = vec4( ((aVertexPosition + offsetVector) / projectionVector) + center , 0.0, 1.0);",
+ "vTextureCoord = aTextureCoord;",
+ "vColor = aColor;",
+ "}"
+];
diff --git a/src/pixi/renderers/webgl/PrimitiveShader.js b/src/pixi/renderers/webgl/PrimitiveShader.js
new file mode 100644
index 00000000..1089d84d
--- /dev/null
+++ b/src/pixi/renderers/webgl/PrimitiveShader.js
@@ -0,0 +1,57 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+PIXI.PrimitiveShader = function()
+{
+ // the webGL program..
+ this.program;
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec4 vColor;",
+ "void main(void) {",
+ "gl_FragColor = vColor;",
+ "}"
+ ];
+
+ this.vertexSrc = [
+ "attribute vec2 aVertexPosition;",
+ "attribute vec4 aColor;",
+ "uniform mat3 translationMatrix;",
+ "uniform vec2 projectionVector;",
+ "uniform vec2 offsetVector;",
+ "uniform float alpha;",
+ "varying vec4 vColor;",
+ "void main(void) {",
+ "vec3 v = translationMatrix * vec3(aVertexPosition , 1.0);",
+ "v -= offsetVector.xyx;",
+ "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
+ "vColor = aColor * alpha;",
+ "}"
+ ];
+
+}
+
+PIXI.PrimitiveShader.prototype.init = function()
+{
+ var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc);
+
+ var gl = PIXI.gl;
+
+ gl.useProgram(program);
+
+ // get and store the uniforms for the shader
+ this.projectionVector = gl.getUniformLocation(program, "projectionVector");
+ this.offsetVector = gl.getUniformLocation(program, "offsetVector");
+
+ // get and store the attributes
+ this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
+ this.colorAttribute = gl.getAttribLocation(program, "aColor");
+
+ this.translationMatrix = gl.getUniformLocation(program, "translationMatrix");
+ this.alpha = gl.getUniformLocation(program, "alpha");
+
+ this.program = program;
+}
diff --git a/src/pixi/renderers/webgl/StripShader.js b/src/pixi/renderers/webgl/StripShader.js
new file mode 100644
index 00000000..80d8394c
--- /dev/null
+++ b/src/pixi/renderers/webgl/StripShader.js
@@ -0,0 +1,65 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+PIXI.StripShader = function()
+{
+ // the webGL program..
+ this.program;
+
+ this.fragmentSrc = [
+ "precision mediump float;",
+ "varying vec2 vTextureCoord;",
+ "varying float vColor;",
+ "uniform float alpha;",
+ "uniform sampler2D uSampler;",
+ "void main(void) {",
+ "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));",
+ "gl_FragColor = gl_FragColor * alpha;",
+ "}"
+ ];
+
+ this.vertexSrc = [
+ "attribute vec2 aVertexPosition;",
+ "attribute vec2 aTextureCoord;",
+ "attribute float aColor;",
+ "uniform mat3 translationMatrix;",
+ "uniform vec2 projectionVector;",
+ "varying vec2 vTextureCoord;",
+ "varying vec2 offsetVector;",
+ "varying float vColor;",
+ "void main(void) {",
+ "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
+ "v -= offsetVector.xyx;",
+ "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / projectionVector.y + 1.0 , 0.0, 1.0);",
+ "vTextureCoord = aTextureCoord;",
+ "vColor = aColor;",
+ "}"
+ ];
+}
+
+PIXI.StripShader.prototype.init = function()
+{
+ var program = PIXI.compileProgram(this.vertexSrc, this.fragmentSrc)
+
+ var gl = PIXI.gl;
+
+ gl.useProgram(program);
+
+ // get and store the uniforms for the shader
+ this.uSampler = gl.getUniformLocation(program, "uSampler");
+ this.projectionVector = gl.getUniformLocation(program, "projectionVector");
+ this.offsetVector = gl.getUniformLocation(program, "offsetVector");
+ this.colorAttribute = gl.getAttribLocation(program, "aColor");
+ //this.dimensions = gl.getUniformLocation(this.program, "dimensions");
+
+ // get and store the attributes
+ this.aVertexPosition = gl.getAttribLocation(program, "aVertexPosition");
+ this.aTextureCoord = gl.getAttribLocation(program, "aTextureCoord");
+
+ this.translationMatrix = gl.getUniformLocation(program, "translationMatrix");
+ this.alpha = gl.getUniformLocation(program, "alpha");
+
+ this.program = program;
+}
diff --git a/src/pixi/renderers/webgl/WebGLBatch.js b/src/pixi/renderers/webgl/WebGLBatch.js
index 410884b8..fa09fc43 100644
--- a/src/pixi/renderers/webgl/WebGLBatch.js
+++ b/src/pixi/renderers/webgl/WebGLBatch.js
@@ -415,7 +415,10 @@ PIXI.WebGLBatch.prototype.update = function()
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)
@@ -443,17 +446,17 @@ PIXI.WebGLBatch.prototype.update = function()
tx = worldTransform[2];
ty = worldTransform[5];
- this.verticies[index + 0 ] = a * w1 + c * h1 + tx;
- this.verticies[index + 1 ] = d * h1 + b * w1 + ty;
+ verticies[index + 0 ] = a * w1 + c * h1 + tx;
+ verticies[index + 1 ] = d * h1 + b * w1 + ty;
- this.verticies[index + 2 ] = a * w0 + c * h1 + tx;
- this.verticies[index + 3 ] = d * h1 + b * w0 + ty;
+ verticies[index + 2 ] = a * w0 + c * h1 + tx;
+ verticies[index + 3 ] = d * h1 + b * w0 + ty;
- this.verticies[index + 4 ] = a * w0 + c * h0 + tx;
- this.verticies[index + 5 ] = d * h0 + b * w0 + ty;
+ verticies[index + 4 ] = a * w0 + c * h0 + tx;
+ verticies[index + 5 ] = d * h0 + b * w0 + ty;
- this.verticies[index + 6] = a * w1 + c * h0 + tx;
- this.verticies[index + 7] = d * h0 + b * w1 + ty;
+ verticies[index + 6] = a * w1 + c * h0 + tx;
+ verticies[index + 7] = d * h0 + b * w1 + ty;
if(displayObject.updateFrame || displayObject.texture.updateFrame)
{
@@ -465,17 +468,17 @@ PIXI.WebGLBatch.prototype.update = function()
var tw = texture.baseTexture.width;
var th = texture.baseTexture.height;
- this.uvs[index + 0] = frame.x / tw;
- this.uvs[index +1] = frame.y / th;
+ uvs[index + 0] = frame.x / tw;
+ uvs[index +1] = frame.y / th;
- this.uvs[index +2] = (frame.x + frame.width) / tw;
- this.uvs[index +3] = frame.y / th;
+ uvs[index +2] = (frame.x + frame.width) / tw;
+ uvs[index +3] = frame.y / th;
- this.uvs[index +4] = (frame.x + frame.width) / tw;
- this.uvs[index +5] = (frame.y + frame.height) / th;
+ uvs[index +4] = (frame.x + frame.width) / tw;
+ uvs[index +5] = (frame.y + frame.height) / th;
- this.uvs[index +6] = frame.x / tw;
- this.uvs[index +7] = (frame.y + frame.height) / th;
+ uvs[index +6] = frame.x / tw;
+ uvs[index +7] = (frame.y + frame.height) / th;
displayObject.updateFrame = false;
}
@@ -486,7 +489,7 @@ PIXI.WebGLBatch.prototype.update = function()
displayObject.cacheAlpha = displayObject.worldAlpha;
var colorIndex = indexRun * 4;
- this.colors[colorIndex] = this.colors[colorIndex + 1] = this.colors[colorIndex + 2] = this.colors[colorIndex + 3] = displayObject.worldAlpha;
+ colors[colorIndex] = colors[colorIndex + 1] = colors[colorIndex + 2] = colors[colorIndex + 3] = displayObject.worldAlpha;
this.dirtyColors = true;
}
}
@@ -494,17 +497,7 @@ PIXI.WebGLBatch.prototype.update = function()
{
index = indexRun * 8;
- this.verticies[index + 0 ] = 0;
- this.verticies[index + 1 ] = 0;
-
- this.verticies[index + 2 ] = 0;
- this.verticies[index + 3 ] = 0;
-
- this.verticies[index + 4 ] = 0;
- this.verticies[index + 5 ] = 0;
-
- this.verticies[index + 6] = 0;
- this.verticies[index + 7] = 0;
+ 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++;
@@ -536,15 +529,18 @@ PIXI.WebGLBatch.prototype.render = function(start, end)
//TODO optimize this!
- var shaderProgram = PIXI.shaderProgram;
- gl.useProgram(shaderProgram);
+ 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.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
+ 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)
@@ -553,7 +549,7 @@ PIXI.WebGLBatch.prototype.render = function(start, end)
gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvs);
}
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribPointer(shaderProgram.aTextureCoord, 2, gl.FLOAT, false, 0, 0);
gl.activeTexture(gl.TEXTURE0);
gl.bindTexture(gl.TEXTURE_2D, this.texture._glTexture);
@@ -568,7 +564,6 @@ PIXI.WebGLBatch.prototype.render = function(start, end)
}
gl.vertexAttribPointer(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
-
// dont need to upload!
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
diff --git a/src/pixi/renderers/webgl/WebGLFilterManager.js b/src/pixi/renderers/webgl/WebGLFilterManager.js
new file mode 100644
index 00000000..f3e9027c
--- /dev/null
+++ b/src/pixi/renderers/webgl/WebGLFilterManager.js
@@ -0,0 +1,519 @@
+/**
+ * @author Mat Groves http://matgroves.com/ @Doormat23
+ */
+
+
+PIXI.WebGLFilterManager = function(transparent)
+{
+ this.transparent = transparent;
+
+ this.filterStack = [];
+ this.texturePool = [];
+
+ this.offsetX = 0;
+ this.offsetY = 0;
+
+ this.initShaderBuffers();
+}
+
+// API
+
+PIXI.WebGLFilterManager.prototype.begin = function(projection, buffer)
+{
+ this.width = projection.x * 2;
+ this.height = -projection.y * 2;
+ this.buffer = buffer;
+}
+
+PIXI.WebGLFilterManager.prototype.pushFilter = function(filterBlock)
+{
+ var gl = PIXI.gl;
+
+ // filter program
+ // OPTIMISATION - the first filter is free if its a simple color change?
+ this.filterStack.push(filterBlock);
+
+ var filter = filterBlock.filterPasses[0];
+
+
+
+ this.offsetX += filterBlock.target.filterArea.x;
+ this.offsetY += filterBlock.target.filterArea.y;
+
+
+
+
+
+ var texture = this.texturePool.pop();
+ if(!texture)texture = new PIXI.FilterTexture(this.width, this.height);
+
+ gl.bindTexture(gl.TEXTURE_2D, texture.texture);
+
+ this.getBounds(filterBlock.target);
+
+ // addpadding?
+ //displayObject.filterArea.x
+
+ var filterArea = filterBlock.target.filterArea;
+
+ var padidng = filter.padding;
+ filterArea.x -= padidng;
+ filterArea.y -= padidng;
+ filterArea.width += padidng * 2;
+ filterArea.height += padidng * 2;
+
+ // cap filter to screen size..
+ if(filterArea.x < 0)filterArea.x = 0;
+ if(filterArea.width > this.width)filterArea.width = this.width;
+ if(filterArea.y < 0)filterArea.y = 0;
+ if(filterArea.height > this.height)filterArea.height = this.height;
+
+
+ //gl.texImage2D(gl.TEXTURE_2D, 0, gl.RGBA, filterArea.width, filterArea.height, 0, gl.RGBA, gl.UNSIGNED_BYTE, null);
+ gl.bindFramebuffer(gl.FRAMEBUFFER, texture.frameBuffer);
+
+ // console.log(filterArea)
+ // set view port
+ gl.viewport(0, 0, filterArea.width, filterArea.height);
+
+ PIXI.projection.x = filterArea.width/2;
+ PIXI.projection.y = -filterArea.height/2;
+
+ PIXI.offset.x = -filterArea.x;
+ PIXI.offset.y = -filterArea.y;
+
+ //console.log(PIXI.defaultShader.projectionVector)
+ // update projection
+ gl.uniform2f(PIXI.defaultShader.projectionVector, filterArea.width/2, -filterArea.height/2);
+ gl.uniform2f(PIXI.defaultShader.offsetVector, -filterArea.x, -filterArea.y);
+ //PIXI.primitiveProgram
+
+ gl.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")
+}
+
+
+PIXI.WebGLFilterManager.prototype.popFilter = function()
+{
+
+ var gl = PIXI.gl;
+
+ var filterBlock = this.filterStack.pop();
+
+
+
+ var filterArea = filterBlock.target.filterArea;
+
+ var texture = filterBlock._glFilterTexture;
+
+ if(filterBlock.filterPasses.length > 1)
+ {
+ gl.viewport(0, 0, filterArea.width, filterArea.height);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+
+ this.vertexArray[0] = 0;
+ this.vertexArray[1] = filterArea.height;
+
+ this.vertexArray[2] = filterArea.width;
+ this.vertexArray[3] = filterArea.height;
+
+ this.vertexArray[4] = 0;
+ this.vertexArray[5] = 0;
+
+ this.vertexArray[6] = filterArea.width;
+ this.vertexArray[7] = 0;
+
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray);
+
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
+ // nnow set the uvs..
+ this.uvArray[2] = filterArea.width/this.width;
+ this.uvArray[5] = filterArea.height/this.height;
+ this.uvArray[6] = filterArea.width/this.width;
+ this.uvArray[7] = filterArea.height/this.height;
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray);
+
+ var inputTexture = texture;
+ var outputTexture = this.texturePool.pop();
+ if(!outputTexture)outputTexture = new PIXI.FilterTexture(this.width, this.height);
+
+ // need to clear this FBO as it may have some left over elements from a prvious filter.
+ gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer );
+ gl.clear(gl.COLOR_BUFFER_BIT);
+
+ gl.disable(gl.BLEND);
+
+ for (var i = 0; i < filterBlock.filterPasses.length-1; i++)
+ {
+ var filterPass = filterBlock.filterPasses[i];
+
+ gl.bindFramebuffer(gl.FRAMEBUFFER, outputTexture.frameBuffer );
+
+ // set texture
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, inputTexture.texture);
+
+ // draw texture..
+ //filterPass.applyFilterPass(filterArea.width, filterArea.height);
+ this.applyFilterPass(filterPass, filterArea, filterArea.width, filterArea.height);
+
+ // swap the textures..
+ var temp = inputTexture;
+ inputTexture = outputTexture;
+ outputTexture = temp;
+
+ };
+
+ gl.enable(gl.BLEND);
+
+ texture = inputTexture;
+ this.texturePool.push(outputTexture);
+ }
+
+ var filter = filterBlock.filterPasses[filterBlock.filterPasses.length-1];
+
+ this.offsetX -= filterArea.x;
+ this.offsetY -= filterArea.y;
+
+
+ var sizeX = this.width;
+ var sizeY = this.height;
+
+ var offsetX = 0;
+ var offsetY = 0;
+
+ var buffer = this.buffer;
+
+ // time to render the filters texture to the previous scene
+ if(this.filterStack.length === 0)
+ {
+ gl.colorMask(true, true, true, this.transparent);
+ }
+ else
+ {
+ var currentFilter = this.filterStack[this.filterStack.length-1];
+ var filterArea = currentFilter.target.filterArea;
+
+ sizeX = filterArea.width;
+ sizeY = filterArea.height;
+
+ offsetX = filterArea.x;
+ offsetY = filterArea.y;
+
+ buffer = currentFilter._glFilterTexture.frameBuffer;
+ }
+
+
+
+ // TODO need toremove thease global elements..
+ PIXI.projection.x = sizeX/2;
+ PIXI.projection.y = -sizeY/2;
+
+ PIXI.offset.x = offsetX;
+ PIXI.offset.y = offsetY;
+
+
+ var filterArea = filterBlock.target.filterArea;
+ var x = filterArea.x-offsetX;
+ var y = filterArea.y-offsetY;
+
+ // update the buffers..
+ // make sure to flip the y!
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+
+ this.vertexArray[0] = x;
+ this.vertexArray[1] = y + filterArea.height;
+
+ this.vertexArray[2] = x + filterArea.width;
+ this.vertexArray[3] = y + filterArea.height;
+
+ this.vertexArray[4] = x;
+ this.vertexArray[5] = y;
+
+ this.vertexArray[6] = x + filterArea.width;
+ this.vertexArray[7] = y;
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.vertexArray);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
+
+ this.uvArray[2] = filterArea.width/this.width;
+ this.uvArray[5] = filterArea.height/this.height;
+ this.uvArray[6] = filterArea.width/this.width;
+ this.uvArray[7] = filterArea.height/this.height;
+
+ gl.bufferSubData(gl.ARRAY_BUFFER, 0, this.uvArray);
+
+ gl.viewport(0, 0, sizeX, sizeY);
+ // bind the buffer
+ gl.bindFramebuffer(gl.FRAMEBUFFER, buffer );
+
+ // set texture
+ gl.activeTexture(gl.TEXTURE0);
+ gl.bindTexture(gl.TEXTURE_2D, texture.texture);
+
+ // apply!
+ //filter.applyFilterPass(sizeX, sizeY);
+ this.applyFilterPass(filter, filterArea, sizeX, sizeY);
+
+ // now restore the regular shader..
+ gl.useProgram(PIXI.defaultShader.program);
+ gl.uniform2f(PIXI.defaultShader.projectionVector, sizeX/2, -sizeY/2);
+ gl.uniform2f(PIXI.defaultShader.offsetVector, -offsetX, -offsetY);
+
+ // return the texture to the pool
+ this.texturePool.push(texture);
+ filterBlock._glFilterTexture = null;
+}
+
+PIXI.WebGLFilterManager.prototype.applyFilterPass = function(filter, filterArea, width, height)
+{
+ // use program
+ var gl = PIXI.gl;
+
+ if(!filter.shader)
+ {
+ var shader = new PIXI.PixiShader();
+
+ shader.fragmentSrc = filter.fragmentSrc;
+ shader.uniforms = filter.uniforms;
+ shader.init();
+
+ filter.shader = shader;
+ }
+
+ var shader = filter.shader;
+
+ // set the shader
+ gl.useProgram(shader.program);
+
+ gl.uniform2f(shader.projectionVector, width/2, -height/2);
+ gl.uniform2f(shader.offsetVector, 0,0)
+
+ 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();
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
+ gl.vertexAttribPointer(shader.aTextureCoord, 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 );
+}
+
+PIXI.WebGLFilterManager.prototype.initShaderBuffers = function()
+{
+ var gl = PIXI.gl;
+
+ // create some buffers
+ this.vertexBuffer = gl.createBuffer();
+ this.uvBuffer = gl.createBuffer();
+ this.indexBuffer = gl.createBuffer();
+
+ // bind and upload the vertexs..
+ // keep a refferance to the vertexFloatData..
+ this.vertexArray = new Float32Array([0.0, 0.0,
+ 1.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 1.0]);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.vertexBuffer);
+ gl.bufferData(
+ gl.ARRAY_BUFFER,
+ this.vertexArray,
+ gl.STATIC_DRAW);
+
+
+ // bind and upload the uv buffer
+ this.uvArray = new Float32Array([0.0, 0.0,
+ 1.0, 0.0,
+ 0.0, 1.0,
+ 1.0, 1.0]);
+
+ gl.bindBuffer(gl.ARRAY_BUFFER, this.uvBuffer);
+ gl.bufferData(
+ gl.ARRAY_BUFFER,
+ this.uvArray,
+ gl.STATIC_DRAW);
+
+ // bind and upload the index
+ gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, this.indexBuffer);
+ gl.bufferData(
+ gl.ELEMENT_ARRAY_BUFFER,
+ new Uint16Array([0, 1, 2, 1, 3, 2]),
+ gl.STATIC_DRAW);
+}
+
+PIXI.WebGLFilterManager.prototype.getBounds = function(displayObject)
+{
+ // time to get the width and height of the object!
+ var worldTransform, width, height, aX, aY, w0, w1, h0, h1, index, doTest;
+ var a, b, c, d, tx, ty, x1, x2, x3, x4, y1, y2, y3, y4;
+
+ 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;
+
+ }
+ while(tempObject != testObject)
+
+ // maximum bounds is the size of the screen..
+ //minX = minX > 0 ? minX : 0;
+ //minY = minY > 0 ? minY : 0;
+
+ displayObject.filterArea.x = minX;
+ displayObject.filterArea.y = minY;
+
+// console.log(maxX+ " : " + minX)
+ 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)
+{
+ 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);
+
+}
\ No newline at end of file
diff --git a/src/pixi/renderers/webgl/WebGLGraphics.js b/src/pixi/renderers/webgl/WebGLGraphics.js
index bcddb142..1d949853 100644
--- a/src/pixi/renderers/webgl/WebGLGraphics.js
+++ b/src/pixi/renderers/webgl/WebGLGraphics.js
@@ -46,7 +46,6 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
PIXI.WebGLGraphics.updateGraphics(graphics);
}
-
PIXI.activatePrimitiveShader();
// This could be speeded up fo sure!
@@ -56,30 +55,29 @@ PIXI.WebGLGraphics.renderGraphics = function(graphics, projection)
// set the matrix transform for the
gl.blendFunc(gl.ONE, gl.ONE_MINUS_SRC_ALPHA);
-
- gl.uniformMatrix3fv(PIXI.primitiveProgram.translationMatrix, false, m);
-
- gl.uniform2f(PIXI.primitiveProgram.projectionVector, projection.x, projection.y);
-
- gl.uniform1f(PIXI.primitiveProgram.alpha, graphics.worldAlpha);
+ gl.uniformMatrix3fv(PIXI.primitiveShader.translationMatrix, false, m);
+
+ gl.uniform2f(PIXI.primitiveShader.projectionVector, projection.x, -projection.y);
+ gl.uniform2f(PIXI.primitiveShader.offsetVector, -PIXI.offset.x, -PIXI.offset.y);
+
+ gl.uniform1f(PIXI.primitiveShader.alpha, graphics.worldAlpha);
gl.bindBuffer(gl.ARRAY_BUFFER, graphics._webGL.buffer);
- // WHY DOES THIS LINE NEED TO BE THERE???
- gl.vertexAttribPointer(PIXI.shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
- // its not even used.. but need to be set or it breaks?
- // only on pc though..
-
- gl.vertexAttribPointer(PIXI.primitiveProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 4 * 6, 0);
- gl.vertexAttribPointer(PIXI.primitiveProgram.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4);
+ gl.vertexAttribPointer(PIXI.primitiveShader.aVertexPosition, 2, gl.FLOAT, false, 4 * 6, 0);
+ gl.vertexAttribPointer(PIXI.primitiveShader.colorAttribute, 4, gl.FLOAT, false,4 * 6, 2 * 4);
// set the index buffer!
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, graphics._webGL.indexBuffer);
+
gl.drawElements(gl.TRIANGLE_STRIP, graphics._webGL.indices.length, gl.UNSIGNED_SHORT, 0 );
+ PIXI.deactivatePrimitiveShader();
+
+
// return to default shader...
- PIXI.activateDefaultShader();
+// PIXI.activateShader(PIXI.defaultShader);
}
/**
@@ -284,6 +282,14 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
var points = graphicsData.points;
if(points.length == 0)return;
+ // if the line width is an odd number add 0.5 to align to a whole pixel
+ if(graphicsData.lineWidth%2)
+ {
+ for (var i = 0; i < points.length; i++) {
+ points[i] += 0.5;
+ };
+ }
+
// get first and last point.. figure out the middle!
var firstPoint = new PIXI.Point( points[0], points[1] );
var lastPoint = new PIXI.Point( points[points.length - 2], points[points.length - 1] );
@@ -385,16 +391,27 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
c2 = (-perp2x + p3x) * (-perp2y + p2y) - (-perp2x + p2x) * (-perp2y + p3y);
denom = a1*b2 - a2*b1;
-
- if (denom == 0) {
- denom+=1;
- }
+
+ if(Math.abs(denom) < 0.1 )
+ {
+
+ denom+=10.1;
+ verts.push(p2x - perpx , p2y - perpy,
+ r, g, b, alpha);
+
+ verts.push(p2x + perpx , p2y + perpy,
+ r, g, b, alpha);
+
+ continue;
+ }
px = (b1*c2 - b2*c1)/denom;
py = (a2*c1 - a1*c2)/denom;
+
pdist = (px -p2x) * (px -p2x) + (py -p2y) + (py -p2y);
+
if(pdist > 140 * 140)
{
perp3x = perpx - perp2x;
@@ -419,6 +436,7 @@ PIXI.WebGLGraphics.buildLine = function(graphicsData, webGLData)
}
else
{
+
verts.push(px , py);
verts.push(r, g, b, alpha);
diff --git a/src/pixi/renderers/webgl/WebGLRenderGroup.js b/src/pixi/renderers/webgl/WebGLRenderGroup.js
index a66ce6b6..7a52a9f2 100644
--- a/src/pixi/renderers/webgl/WebGLRenderGroup.js
+++ b/src/pixi/renderers/webgl/WebGLRenderGroup.js
@@ -15,14 +15,18 @@
* @contructor
* @param gl {WebGLContext} An instance of the webGL context
*/
-PIXI.WebGLRenderGroup = function(gl)
+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
@@ -56,19 +60,20 @@ PIXI.WebGLRenderGroup.prototype.setRenderable = function(displayObject)
* @method render
* @param projection {Object}
*/
-PIXI.WebGLRenderGroup.prototype.render = function(projection)
+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.uniform2f(PIXI.shaderProgram.projectionVector, projection.x, projection.y);
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++)
{
@@ -79,61 +84,12 @@ PIXI.WebGLRenderGroup.prototype.render = function(projection)
continue;
}
- // non sprite batch..
- 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.Graphics)
- {
- if(worldVisible && renderable.renderable) PIXI.WebGLGraphics.renderGraphics(renderable, projection);//, projectionMatrix);
- }
- else if(renderable instanceof PIXI.FilterBlock)
- {
- /*
- * for now only masks are supported..
- */
- if(renderable.open)
- {
- gl.enable(gl.STENCIL_TEST);
-
- gl.colorMask(false, false, false, false);
- gl.stencilFunc(gl.ALWAYS,1,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
-
- PIXI.WebGLGraphics.renderGraphics(renderable.mask, projection);
-
- gl.colorMask(true, true, true, false);
- gl.stencilFunc(gl.NOTEQUAL,0,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.KEEP);
- }
- else
- {
- gl.disable(gl.STENCIL_TEST);
- }
- }
+ // render special
+ this.renderSpecial(renderable, projection);
}
}
-/**
- * Renders the stage to its webgl view
- *
- * @method handleFilter
- * @param filter {FilterBlock}
- * @private
- */
-PIXI.WebGLRenderGroup.prototype.handleFilter = function(filter, projection)
-{
-
-}
-
/**
* Renders a specific displayObject
*
@@ -142,13 +98,14 @@ PIXI.WebGLRenderGroup.prototype.handleFilter = function(filter, projection)
* @param projection {Object}
* @private
*/
-PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection)
+PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, projection, buffer)
{
PIXI.WebGLRenderer.updateTextures();
-
var gl = this.gl;
- gl.uniform2f(PIXI.shaderProgram.projectionVector, projection.x, projection.y);
+ gl.uniform2f(PIXI.defaultShader.projectionVector, projection.x, projection.y);
+
+ this.filterManager.begin(projection, buffer);
// to do!
// render part of the scene...
@@ -168,11 +125,13 @@ PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, project
var nextRenderable = displayObject.first;
while(nextRenderable._iNext)
{
- nextRenderable = 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;
@@ -202,13 +161,11 @@ PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, project
}
// Get the LAST renderable object
- var lastRenderable = displayObject;
- var endBatch;
- var lastItem = displayObject;
- while(lastItem.children.length > 0)
+ var lastRenderable = displayObject.last;
+ while(lastRenderable._iPrev)
{
- lastItem = lastItem.children[lastItem.children.length-1];
- if(lastItem.renderable)lastRenderable = lastItem;
+ if(lastRenderable.renderable && lastRenderable.__renderGroup)break;
+ lastRenderable = lastRenderable._iNext;
}
if(lastRenderable instanceof PIXI.Sprite)
@@ -237,6 +194,7 @@ PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, project
endBatch = lastRenderable;
}
+ //console.log(endBatch);
// TODO - need to fold this up a bit!
if(startBatch == endBatch)
@@ -302,8 +260,10 @@ PIXI.WebGLRenderGroup.prototype.renderSpecific = function(displayObject, project
*/
PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
{
+
var worldVisible = renderable.vcount === PIXI.visibleCount
+
if(renderable instanceof PIXI.TilingSprite)
{
if(worldVisible)this.renderTilingSprite(renderable, projection);
@@ -322,29 +282,76 @@ PIXI.WebGLRenderGroup.prototype.renderSpecial = function(renderable, projection)
}
else if(renderable instanceof PIXI.FilterBlock)
{
- /*
- * for now only masks are supported..
- */
+ this.handleFilterBlock(renderable, projection);
+ }
+}
- var gl = PIXI.gl;
+flip = false;
+var maskStack = [];
+var maskPosition = 0;
- if(renderable.open)
+//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)
{
- gl.enable(gl.STENCIL_TEST);
-
- gl.colorMask(false, false, false, false);
- gl.stencilFunc(gl.ALWAYS,1,0xff);
- gl.stencilOp(gl.KEEP,gl.KEEP,gl.REPLACE);
-
- PIXI.WebGLGraphics.renderGraphics(renderable.mask, projection);
+ 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);
- // we know this is a render texture so enable alpha too..
gl.colorMask(true, true, true, true);
- gl.stencilFunc(gl.NOTEQUAL,0,0xff);
+ 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);
}
}
@@ -410,7 +417,7 @@ PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end)
* It keeps going back until it finds a sprite or the stage
*/
var previousRenderable = start;
- while(previousRenderable != this.root)
+ while(previousRenderable != this.root.first)
{
previousRenderable = previousRenderable._iPrev;
if(previousRenderable.renderable && previousRenderable.__renderGroup)break;
@@ -424,7 +431,7 @@ PIXI.WebGLRenderGroup.prototype.addFilterBlocks = function(start, end)
* scene graph
*/
var previousRenderable2 = end;
- while(previousRenderable2 != this.root)
+ while(previousRenderable2 != this.root.first)
{
previousRenderable2 = previousRenderable2._iPrev;
if(previousRenderable2.renderable && previousRenderable2.__renderGroup)break;
@@ -796,6 +803,7 @@ PIXI.WebGLRenderGroup.prototype.removeObject = function(displayObject)
}
}
+
/**
* Initializes a tiling sprite
*
@@ -866,25 +874,26 @@ PIXI.WebGLRenderGroup.prototype.initTilingSprite = function(sprite)
PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
{
var gl = this.gl;
- var shaderProgram = PIXI.shaderProgram;
-// mat
- //var mat4Real = PIXI.mat3.toMat4(strip.worldTransform);
- //PIXI.mat4.transpose(mat4Real);
- //PIXI.mat4.multiply(projectionMatrix, mat4Real, mat4Real )
+ PIXI.activateStripShader();
+
+ var shader = PIXI.stripShader;
+
+ var program = shader.program;
- gl.useProgram(PIXI.stripShaderProgram);
-
var m = PIXI.mat3.clone(strip.worldTransform);
PIXI.mat3.transpose(m);
+// console.log(projection)
// set the matrix transform for the
- gl.uniformMatrix3fv(PIXI.stripShaderProgram.translationMatrix, false, m);
- gl.uniform2f(PIXI.stripShaderProgram.projectionVector, projection.x, projection.y);
- gl.uniform1f(PIXI.stripShaderProgram.alpha, strip.worldAlpha);
+ 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);
@@ -895,23 +904,22 @@ PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
}
*/
-
+ //console.log("!!")
if(!strip.dirty)
- {
-
+ {
gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
gl.bufferSubData(gl.ARRAY_BUFFER, 0, strip.verticies)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribPointer(shader.aVertexPosition, 2, gl.FLOAT, false, 0, 0);
// update the uvs
gl.bindBuffer(gl.ARRAY_BUFFER, strip._uvBuffer);
- gl.vertexAttribPointer(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
+ 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(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
+ gl.vertexAttribPointer(shader.colorAttribute, 1, gl.FLOAT, false, 0, 0);
// dont need to upload!
gl.bindBuffer(gl.ELEMENT_ARRAY_BUFFER, strip._indexBuffer);
@@ -921,30 +929,30 @@ PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
strip.dirty = false;
gl.bindBuffer(gl.ARRAY_BUFFER, strip._vertexBuffer);
gl.bufferData(gl.ARRAY_BUFFER, strip.verticies, gl.STATIC_DRAW)
- gl.vertexAttribPointer(shaderProgram.vertexPositionAttribute, 2, gl.FLOAT, false, 0, 0);
+ 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(shaderProgram.textureCoordAttribute, 2, gl.FLOAT, false, 0, 0);
+ 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(shaderProgram.colorAttribute, 1, gl.FLOAT, false, 0, 0);
+ 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);
}
- //console.log(gl.TRIANGLE_STRIP);
gl.drawElements(gl.TRIANGLE_STRIP, strip.indices.length, gl.UNSIGNED_SHORT, 0);
- gl.useProgram(PIXI.shaderProgram);
+ PIXI.deactivateStripShader();
+ //gl.useProgram(PIXI.currentProgram);
}
/**
@@ -958,6 +966,8 @@ PIXI.WebGLRenderGroup.prototype.renderStrip = function(strip, projection)
PIXI.WebGLRenderGroup.prototype.renderTilingSprite = function(sprite, projectionMatrix)
{
var gl = this.gl;
+
+
var shaderProgram = PIXI.shaderProgram;
var tilePosition = sprite.tilePosition;
@@ -1018,3 +1028,4 @@ PIXI.WebGLRenderGroup.prototype.initStrip = function(strip)
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 e192cfb7..e11cd44f 100644
--- a/src/pixi/renderers/webgl/WebGLRenderer.js
+++ b/src/pixi/renderers/webgl/WebGLRenderer.js
@@ -16,8 +16,8 @@ PIXI.gl;
*
* @class WebGLRenderer
* @constructor
- * @param width=0 {number} the width of the canvas view
- * @param height=0 {number} the height of the canvas view
+ * @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 antialias=false {Boolean} sets antialias (only applicable in chrome at the moment)
@@ -43,27 +43,38 @@ PIXI.WebGLRenderer = function(width, height, view, transparent, antialias)
this.batchs = [];
- try
- {
- PIXI.gl = this.gl = this.view.getContext("experimental-webgl", {
- alpha: this.transparent,
- antialias:!!antialias, // SPEED UP??
- premultipliedAlpha:false,
- stencil:true
- });
- }
- catch (e)
- {
- throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this);
- }
+ var options = {
+ alpha: this.transparent,
+ antialias:!!antialias, // SPEED UP??
+ premultipliedAlpha:false,
+ stencil:true
+ }
- PIXI.initPrimitiveShader();
- PIXI.initDefaultShader();
- PIXI.initDefaultStripShader();
+ //try 'experimental-webgl'
+ try {
+ PIXI.gl = this.gl = this.view.getContext("experimental-webgl", options);
+ } catch (e) {
+ //try 'webgl'
+ try {
+ PIXI.gl = this.gl = this.view.getContext("webgl", options);
+ } catch (e) {
+ // fail, not able to get a context
+ throw new Error(" This browser does not support webGL. Try using the canvas renderer" + this);
+ }
+ }
- PIXI.activateDefaultShader();
+ PIXI.initDefaultShaders();
+
+
+
+
+ // PIXI.activateDefaultShader();
var gl = this.gl;
+
+ gl.useProgram(PIXI.defaultShader.program);
+
+
PIXI.WebGLRenderer.gl = gl;
this.batch = new PIXI.WebGLBatch(gl);
@@ -74,11 +85,17 @@ PIXI.WebGLRenderer = function(width, height, view, transparent, antialias)
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;
- this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl);
+ //PIXI.pushShader(PIXI.defaultShader);
+
+ this.stageRenderGroup = new PIXI.WebGLRenderGroup(this.gl, this.transparent);
+ // this.stageRenderGroup. = this.transparent
}
// constructor
@@ -137,15 +154,6 @@ PIXI.WebGLRenderer.prototype.render = function(stage)
this.__stage = stage;
this.stageRenderGroup.setRenderable(stage);
}
-
- // TODO not needed now...
- // update children if need be
- // best to remove first!
- /*for (var i=0; i < stage.__childrenRemoved.length; i++)
- {
- var group = stage.__childrenRemoved[i].__renderGroup
- if(group)group.removeDisplayObject(stage.__childrenRemoved[i]);
- }*/
// update any textures
PIXI.WebGLRenderer.updateTextures();
@@ -168,6 +176,10 @@ PIXI.WebGLRenderer.prototype.render = function(stage)
// HACK TO TEST
this.stageRenderGroup.backgroundColor = stage.backgroundColorSplit;
+
+ PIXI.projection.x = this.width/2;
+ PIXI.projection.y = -this.height/2;
+
this.stageRenderGroup.render(PIXI.projection);
// interaction
@@ -277,8 +289,8 @@ PIXI.WebGLRenderer.destroyTexture = function(texture)
* resizes the webGL view to the specified width and height
*
* @method resize
- * @param width {number} the new width of the webGL view
- * @param height {number} the new height of the webGL view
+ * @param width {Number} the new width of the webGL view
+ * @param height {Number} the new height of the webGL view
*/
PIXI.WebGLRenderer.prototype.resize = function(width, height)
{
@@ -293,7 +305,10 @@ PIXI.WebGLRenderer.prototype.resize = function(width, height)
//var projectionMatrix = this.projectionMatrix;
PIXI.projection.x = this.width/2;
- PIXI.projection.y = this.height/2;
+ PIXI.projection.y = -this.height/2;
+
+ //PIXI.size.x = this.width/2;
+ //PIXI.size.y = -this.height/2;
// projectionMatrix[0] = 2/this.width;
// projectionMatrix[5] = -2/this.height;
diff --git a/src/pixi/renderers/webgl/WebGLShaders.js b/src/pixi/renderers/webgl/WebGLShaders.js
index 68e5b0b1..44123d27 100644
--- a/src/pixi/renderers/webgl/WebGLShaders.js
+++ b/src/pixi/renderers/webgl/WebGLShaders.js
@@ -1,159 +1,79 @@
-
/**
* @author Mat Groves http://matgroves.com/ @Doormat23
*/
-/*
- * the default suoer fast shader!
- */
+PIXI.initDefaultShaders = function()
+{
+ PIXI.primitiveShader = new PIXI.PrimitiveShader();
+ PIXI.primitiveShader.init();
-PIXI.shaderFragmentSrc = [
- "precision mediump float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));",
- "gl_FragColor = gl_FragColor * vColor;",
- "}"
-];
+ PIXI.stripShader = new PIXI.StripShader();
+ PIXI.stripShader.init();
-PIXI.shaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
- //"uniform mat4 uMVMatrix;",
+ PIXI.defaultShader = new PIXI.PixiShader();
+ PIXI.defaultShader.init();
+
+ var gl = PIXI.gl;
+ var shaderProgram = PIXI.defaultShader.program;
+
+
+ gl.useProgram(shaderProgram);
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- // "gl_Position = uMVMatrix * vec4(aVertexPosition, 1.0, 1.0);",
- "gl_Position = vec4( aVertexPosition.x / projectionVector.x -1.0, aVertexPosition.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
+ 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);
+}
/*
- * the triangle strip shader..
- */
-PIXI.stripShaderFragmentSrc = [
- "precision mediump float;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "uniform float alpha;",
- "uniform sampler2D uSampler;",
- "void main(void) {",
- "gl_FragColor = texture2D(uSampler, vec2(vTextureCoord.x, vTextureCoord.y));",
- "gl_FragColor = gl_FragColor * alpha;",
- "}"
-];
-
-
-PIXI.stripShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec2 aTextureCoord;",
- "attribute float aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "varying vec2 vTextureCoord;",
- "varying float vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vTextureCoord = aTextureCoord;",
- "vColor = aColor;",
- "}"
-];
-
-
-/*
- * primitive shader..
- */
-
-PIXI.primitiveShaderFragmentSrc = [
- "precision mediump float;",
- "varying vec4 vColor;",
- "void main(void) {",
- "gl_FragColor = vColor;",
- "}"
-];
-
-PIXI.primitiveShaderVertexSrc = [
- "attribute vec2 aVertexPosition;",
- "attribute vec4 aColor;",
- "uniform mat3 translationMatrix;",
- "uniform vec2 projectionVector;",
- "uniform float alpha;",
- "varying vec4 vColor;",
- "void main(void) {",
- "vec3 v = translationMatrix * vec3(aVertexPosition, 1.0);",
- "gl_Position = vec4( v.x / projectionVector.x -1.0, v.y / -projectionVector.y + 1.0 , 0.0, 1.0);",
- "vColor = aColor * alpha;",
- "}"
-];
-
-PIXI.initPrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- var shaderProgram = PIXI.compileProgram(PIXI.primitiveShaderVertexSrc, PIXI.primitiveShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
-
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
-
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- PIXI.primitiveProgram = shaderProgram;
-}
-
-PIXI.initDefaultShader = function()
-{
- var gl = this.gl;
- var shaderProgram = PIXI.compileProgram(PIXI.shaderVertexSrc, PIXI.shaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
-
- // shaderProgram.mvMatrixUniform = gl.getUniformLocation(shaderProgram, "uMVMatrix");
- shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
-
- PIXI.shaderProgram = shaderProgram;
-}
-
-PIXI.initDefaultStripShader = function()
-{
- var gl = this.gl;
- var shaderProgram = PIXI.compileProgram(PIXI.stripShaderVertexSrc, PIXI.stripShaderFragmentSrc)
-
- gl.useProgram(shaderProgram);
-
- shaderProgram.vertexPositionAttribute = gl.getAttribLocation(shaderProgram, "aVertexPosition");
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
- shaderProgram.textureCoordAttribute = gl.getAttribLocation(shaderProgram, "aTextureCoord");
- shaderProgram.translationMatrix = gl.getUniformLocation(shaderProgram, "translationMatrix");
- shaderProgram.alpha = gl.getUniformLocation(shaderProgram, "alpha");
-
- shaderProgram.colorAttribute = gl.getAttribLocation(shaderProgram, "aColor");
-
- shaderProgram.projectionVector = gl.getUniformLocation(shaderProgram, "projectionVector");
-
- shaderProgram.samplerUniform = gl.getUniformLocation(shaderProgram, "uSampler");
-
- PIXI.stripShaderProgram = shaderProgram;
-}
+SHADER COMPILER HELPERS
+*/
PIXI.CompileVertexShader = function(gl, shaderSrc)
{
@@ -173,7 +93,7 @@ PIXI._CompileShader = function(gl, shaderSrc, shaderType)
gl.compileShader(shader);
if (!gl.getShaderParameter(shader, gl.COMPILE_STATUS)) {
- alert(gl.getShaderInfoLog(shader));
+ console.log(gl.getShaderInfoLog(shader));
return null;
}
@@ -194,38 +114,8 @@ PIXI.compileProgram = function(vertexSrc, fragmentSrc)
gl.linkProgram(shaderProgram);
if (!gl.getProgramParameter(shaderProgram, gl.LINK_STATUS)) {
- alert("Could not initialise shaders");
+ console.log("Could not initialise shaders");
}
return shaderProgram;
}
-
-
-PIXI.activateDefaultShader = function()
-{
- var gl = PIXI.gl;
- var shaderProgram = PIXI.shaderProgram;
-
- gl.useProgram(shaderProgram);
-
-
- gl.enableVertexAttribArray(shaderProgram.vertexPositionAttribute);
- gl.enableVertexAttribArray(shaderProgram.textureCoordAttribute);
- gl.enableVertexAttribArray(shaderProgram.colorAttribute);
-}
-
-
-
-PIXI.activatePrimitiveShader = function()
-{
- var gl = PIXI.gl;
-
- gl.disableVertexAttribArray(PIXI.shaderProgram.textureCoordAttribute);
- gl.disableVertexAttribArray(PIXI.shaderProgram.colorAttribute);
-
- gl.useProgram(PIXI.primitiveProgram);
-
- gl.enableVertexAttribArray(PIXI.primitiveProgram.vertexPositionAttribute);
- gl.enableVertexAttribArray(PIXI.primitiveProgram.colorAttribute);
-}
-
diff --git a/src/pixi/text/BitmapText.js b/src/pixi/text/BitmapText.js
index d2890c78..db4ec3b5 100644
--- a/src/pixi/text/BitmapText.js
+++ b/src/pixi/text/BitmapText.js
@@ -4,7 +4,7 @@
/**
* A Text Object will create a line(s) of text using bitmap font. To split a line you can use "\n", "\r" or "\r\n"
- * You can generate the fnt files using
+ * You can generate the fnt files using
* http://www.angelcode.com/products/bmfont/ for windows or
* http://www.bmglyph.com/ for mac.
*
@@ -94,7 +94,7 @@ PIXI.BitmapText.prototype.updateText = function()
prevCharCode = null;
continue;
}
-
+
var charData = data.chars[charCode];
if(!charData) continue;
@@ -135,7 +135,7 @@ PIXI.BitmapText.prototype.updateText = function()
this.addChild(c);
}
- this.width = maxLineWidth * scale;
+ this.width = pos.x * scale;
this.height = (pos.y + data.lineHeight) * scale;
};
@@ -157,7 +157,7 @@ PIXI.BitmapText.prototype.updateTransform = function()
this.dirty = false;
}
-
+
PIXI.DisplayObjectContainer.prototype.updateTransform.call(this);
};
diff --git a/src/pixi/text/Text.js b/src/pixi/text/Text.js
index aaf6a431..df1d12d9 100644
--- a/src/pixi/text/Text.js
+++ b/src/pixi/text/Text.js
@@ -14,9 +14,9 @@
* @param [style.fill="black"] {Object} A canvas fillstyle that will be used on the text eg "red", "#00FF00"
* @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right")
* @param [style.stroke] {String} A canvas fillstyle that will be used on the text stroke eg "blue", "#FCFF00"
- * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke)
+ * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke)
* @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used
- * @param [style.wordWrapWidth=100] {number} The width at which text will wrap
+ * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap
*/
PIXI.Text = function(text, style)
{
@@ -26,7 +26,7 @@ PIXI.Text = function(text, style)
this.setText(text);
this.setStyle(style);
-
+
this.updateText();
this.dirty = false;
};
@@ -44,9 +44,9 @@ PIXI.Text.prototype.constructor = PIXI.Text;
* @param [style.fill="black"] {Object} A canvas fillstyle that will be used on the text eg "red", "#00FF00"
* @param [style.align="left"] {String} An alignment of the multiline text ("left", "center" or "right")
* @param [style.stroke="black"] {String} A canvas fillstyle that will be used on the text stroke eg "blue", "#FCFF00"
- * @param [style.strokeThickness=0] {number} A number that represents the thickness of the stroke. Default is 0 (no stroke)
+ * @param [style.strokeThickness=0] {Number} A number that represents the thickness of the stroke. Default is 0 (no stroke)
* @param [style.wordWrap=false] {Boolean} Indicates if word wrap should be used
- * @param [style.wordWrapWidth=100] {number} The width at which text will wrap
+ * @param [style.wordWrapWidth=100] {Number} The width at which text will wrap
*/
PIXI.Text.prototype.setStyle = function(style)
{
@@ -68,7 +68,7 @@ PIXI.Text.prototype.setStyle = function(style)
* @methos setText
* @param {String} text The copy that you would like the text to display
*/
-PIXI.Sprite.prototype.setText = function(text)
+PIXI.Text.prototype.setText = function(text)
{
this.text = text.toString() || " ";
this.dirty = true;
@@ -83,9 +83,9 @@ PIXI.Sprite.prototype.setText = function(text)
PIXI.Text.prototype.updateText = function()
{
this.context.font = this.style.font;
-
+
var outputText = this.text;
-
+
// word wrap
// preserve original text
if(this.style.wordWrap)outputText = this.wordWrap(this.text);
@@ -103,7 +103,7 @@ PIXI.Text.prototype.updateText = function()
maxLineWidth = Math.max(maxLineWidth, lineWidth);
}
this.canvas.width = maxLineWidth + this.style.strokeThickness;
-
+
//calculate text height
var lineHeight = this.determineFontHeight("font: " + this.style.font + ";") + this.style.strokeThickness;
this.canvas.height = lineHeight * lines.length;
@@ -111,7 +111,7 @@ PIXI.Text.prototype.updateText = function()
//set canvas text styles
this.context.fillStyle = this.style.fill;
this.context.font = this.style.font;
-
+
this.context.strokeStyle = this.style.stroke;
this.context.lineWidth = this.style.strokeThickness;
@@ -121,7 +121,7 @@ PIXI.Text.prototype.updateText = function()
for (i = 0; i < lines.length; i++)
{
var linePosition = new PIXI.Point(this.style.strokeThickness / 2, this.style.strokeThickness / 2 + i * lineHeight);
-
+
if(this.style.align == "right")
{
linePosition.x += maxLineWidth - lineWidths[i];
@@ -141,7 +141,7 @@ PIXI.Text.prototype.updateText = function()
this.context.fillText(lines[i], linePosition.x, linePosition.y);
}
}
-
+
this.updateTexture();
};
@@ -157,10 +157,10 @@ PIXI.Text.prototype.updateTexture = function()
this.texture.baseTexture.height = this.canvas.height;
this.texture.frame.width = this.canvas.width;
this.texture.frame.height = this.canvas.height;
-
+
this._width = this.canvas.width;
this._height = this.canvas.height;
-
+
PIXI.texturesToUpdate.push(this.texture.baseTexture);
};
@@ -174,10 +174,10 @@ PIXI.Text.prototype.updateTransform = function()
{
if(this.dirty)
{
- this.updateText();
+ this.updateText();
this.dirty = false;
}
-
+
PIXI.Sprite.prototype.updateTransform.call(this);
};
@@ -189,12 +189,12 @@ PIXI.Text.prototype.updateTransform = function()
* @param fontStyle {Object}
* @private
*/
-PIXI.Text.prototype.determineFontHeight = function(fontStyle)
+PIXI.Text.prototype.determineFontHeight = function(fontStyle)
{
// build a little reference dictionary so if the font style has been used return a
// cached version...
var result = PIXI.Text.heightCache[fontStyle];
-
+
if(!result)
{
var body = document.getElementsByTagName("body")[0];
@@ -203,18 +203,19 @@ PIXI.Text.prototype.determineFontHeight = function(fontStyle)
dummy.appendChild(dummyText);
dummy.setAttribute("style", fontStyle + ';position:absolute;top:0;left:0');
body.appendChild(dummy);
-
+
result = dummy.offsetHeight;
PIXI.Text.heightCache[fontStyle] = result;
-
+
body.removeChild(dummy);
}
-
+
return result;
};
/**
- * A Text Object will apply wordwrap
+ * Applies newlines to a string to have it optimally fit into the horizontal
+ * bounds set by the Text object's wordWrapWidth property.
*
* @method wordWrap
* @param text {String}
@@ -222,48 +223,37 @@ PIXI.Text.prototype.determineFontHeight = function(fontStyle)
*/
PIXI.Text.prototype.wordWrap = function(text)
{
- // search good wrap position
- var searchWrapPos = function(ctx, text, start, end, wrapWidth)
- {
- var p = Math.floor((end-start) / 2) + start;
- if(p == start) {
- return 1;
- }
-
- if(ctx.measureText(text.substring(0,p)).width <= wrapWidth)
- {
- if(ctx.measureText(text.substring(0,p+1)).width > wrapWidth)
- {
- return p;
- }
- else
- {
- return arguments.callee(ctx, text, p, end, wrapWidth);
- }
- }
- else
- {
- return arguments.callee(ctx, text, start, p, wrapWidth);
- }
- };
-
- var lineWrap = function(ctx, text, wrapWidth)
- {
- if(ctx.measureText(text).width <= wrapWidth || text.length < 1)
- {
- return text;
- }
- var pos = searchWrapPos(ctx, text, 0, text.length, wrapWidth);
- return text.substring(0, pos) + "\n" + arguments.callee(ctx, text.substring(pos), wrapWidth);
- };
-
+ // Greedy wrapping algorithm that will wrap words as the line grows longer
+ // than its horizontal bounds.
var result = "";
var lines = text.split("\n");
for (var i = 0; i < lines.length; i++)
{
- result += lineWrap(this.context, lines[i], this.style.wordWrapWidth) + "\n";
+ var spaceLeft = this.style.wordWrapWidth;
+ var words = lines[i].split(" ");
+ for (var j = 0; j < words.length; j++)
+ {
+ var wordWidth = this.context.measureText(words[j]).width;
+ var wordWidthWithSpace = wordWidth + this.context.measureText(" ").width;
+ if(wordWidthWithSpace > spaceLeft)
+ {
+ // Skip printing the newline if it's the first word of the line that is
+ // greater than the word wrap width.
+ if(j > 0)
+ {
+ result += "\n";
+ }
+ result += words[j] + " ";
+ spaceLeft = this.style.wordWrapWidth - wordWidth;
+ }
+ else
+ {
+ spaceLeft -= wordWidthWithSpace;
+ result += words[j] + " ";
+ }
+ }
+ result += "\n";
}
-
return result;
};
@@ -279,7 +269,7 @@ PIXI.Text.prototype.destroy = function(destroyTexture)
{
this.texture.destroy();
}
-
+
};
PIXI.Text.heightCache = {};
diff --git a/src/pixi/textures/BaseTexture.js b/src/pixi/textures/BaseTexture.js
index 4b7e7acb..22ac5a03 100644
--- a/src/pixi/textures/BaseTexture.js
+++ b/src/pixi/textures/BaseTexture.js
@@ -62,19 +62,19 @@ PIXI.BaseTexture = function(source)
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 } );
@@ -87,7 +87,7 @@ PIXI.BaseTexture = function(source)
this.hasLoaded = true;
this.width = this.source.width;
this.height = this.source.height;
-
+
PIXI.texturesToUpdate.push(this);
}
@@ -127,7 +127,7 @@ PIXI.BaseTexture.fromImage = function(imageUrl, crossorigin)
{
// new Image() breaks tex loading in some versions of Chrome.
// See https://code.google.com/p/chromium/issues/detail?id=238071
- var image = new Image();//document.createElement('img');
+ var image = new Image();//document.createElement('img');
if (crossorigin)
{
image.crossOrigin = '';
diff --git a/src/pixi/textures/RenderTexture.js b/src/pixi/textures/RenderTexture.js
index 788fc8ef..ec35c189 100644
--- a/src/pixi/textures/RenderTexture.js
+++ b/src/pixi/textures/RenderTexture.js
@@ -27,8 +27,8 @@
@class RenderTexture
@extends Texture
@constructor
- @param width {number} The width of the render texture
- @param height {number} The height of the render texture
+ @param width {Number} The width of the render texture
+ @param height {Number} The height of the render texture
*/
PIXI.RenderTexture = function(width, height)
{
@@ -91,12 +91,10 @@ PIXI.RenderTexture.prototype.initWebGL = function()
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);
+ this.projection = new PIXI.Point(this.width/2 , -this.height/2);
// set the correct render function..
this.render = this.renderWebGL;
-
-
}
@@ -109,7 +107,7 @@ PIXI.RenderTexture.prototype.resize = function(width, height)
if(PIXI.gl)
{
this.projection.x = this.width/2
- this.projection.y = this.height/2;
+ this.projection.y = -this.height/2;
var gl = PIXI.gl;
gl.bindTexture(gl.TEXTURE_2D, this.baseTexture._glTexture);
@@ -173,9 +171,8 @@ PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, cle
displayObject.worldTransform = PIXI.mat3.create();//sthis.indetityMatrix;
// modify to flip...
displayObject.worldTransform[4] = -1;
- displayObject.worldTransform[5] = this.projection.y * 2;
+ displayObject.worldTransform[5] = this.projection.y * -2;
-
if(position)
{
displayObject.worldTransform[2] = position.x;
@@ -196,20 +193,20 @@ PIXI.RenderTexture.prototype.renderWebGL = function(displayObject, position, cle
{
if(displayObject == renderGroup.root)
{
- renderGroup.render(this.projection);
+ renderGroup.render(this.projection, this.glFramebuffer);
}
else
{
- renderGroup.renderSpecific(displayObject, this.projection);
+ 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.renderGroup.render(this.projection, this.glFramebuffer);
}
-
+
displayObject.worldTransform = originalWorldTransform;
}
@@ -249,4 +246,3 @@ PIXI.RenderTexture.prototype.renderCanvas = function(displayObject, position, cl
// PIXI.texturesToUpdate.push(this.baseTexture);
}
-
diff --git a/src/pixi/textures/Texture.js b/src/pixi/textures/Texture.js
index 419c7b2f..11d82a0b 100644
--- a/src/pixi/textures/Texture.js
+++ b/src/pixi/textures/Texture.js
@@ -13,7 +13,7 @@ PIXI.FrameCache = {};
* @uses EventTarget
* @constructor
* @param baseTexture {BaseTexture} The base texture source to create the texture from
- * @param frmae {Rectangle} The rectangle frame of the texture to show
+ * @param frame {Rectangle} The rectangle frame of the texture to show
*/
PIXI.Texture = function(baseTexture, frame)
{
@@ -58,7 +58,7 @@ PIXI.Texture = function(baseTexture, frame)
{
if(this.noFrame)frame = new PIXI.Rectangle(0,0, baseTexture.width, baseTexture.height);
//console.log(frame)
-
+
this.setFrame(frame);
}
else
@@ -137,13 +137,13 @@ PIXI.Texture.prototype.setFrame = function(frame)
PIXI.Texture.fromImage = function(imageUrl, crossorigin)
{
var texture = PIXI.TextureCache[imageUrl];
-
+
if(!texture)
{
texture = new PIXI.Texture(PIXI.BaseTexture.fromImage(imageUrl, crossorigin));
PIXI.TextureCache[imageUrl] = texture;
}
-
+
return texture;
}
@@ -193,7 +193,7 @@ PIXI.Texture.addTextureToCache = function(texture, id)
}
/**
- * Remove a texture from the textureCache.
+ * Remove a texture from the textureCache.
*
* @static
* @method removeTextureFromCache
diff --git a/src/pixi/utils/Detector.js b/src/pixi/utils/Detector.js
index f3256256..e955e497 100644
--- a/src/pixi/utils/Detector.js
+++ b/src/pixi/utils/Detector.js
@@ -9,12 +9,12 @@
*
* @method autoDetectRenderer
* @static
- * @param width {number} the width of the renderers view
- * @param height {number} the height of the renderers view
+ * @param width {Number} the width of the renderers view
+ * @param height {Number} the height of the renderers 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 antialias=false {Boolean} sets antialias (only applicable in webGL chrome at the moment)
- *
+ *
* antialias
*/
PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias)
@@ -23,8 +23,14 @@ PIXI.autoDetectRenderer = function(width, height, view, transparent, antialias)
if(!height)height = 600;
// BORROWED from Mr Doob (mrdoob.com)
- var webgl = ( function () { try { return !! window.WebGLRenderingContext && !! document.createElement( 'canvas' ).getContext( 'experimental-webgl' ); } catch( e ) { return false; } } )();
+ var webgl = ( function () { try { var canvas = document.createElement( 'canvas' ); return !! window.WebGLRenderingContext && ( canvas.getContext( 'webgl' ) || canvas.getContext( 'experimental-webgl' ) ); } catch( e ) { return false; } } )();
+ if(webgl)
+ {
+ var ie = (navigator.userAgent.toLowerCase().indexOf('msie') != -1);
+ webgl = !ie;
+ }
+
//console.log(webgl);
if( webgl )
{
diff --git a/src/pixi/utils/EventTarget.js b/src/pixi/utils/EventTarget.js
index 8dc54a5f..73da516d 100644
--- a/src/pixi/utils/EventTarget.js
+++ b/src/pixi/utils/EventTarget.js
@@ -18,14 +18,14 @@
PIXI.EventTarget = function () {
var listeners = {};
-
+
this.addEventListener = this.on = function ( type, listener ) {
-
-
+
+
if ( listeners[ type ] === undefined ) {
listeners[ type ] = [];
-
+
}
if ( listeners[ type ].indexOf( listener ) === - 1 ) {
@@ -36,11 +36,17 @@ PIXI.EventTarget = function () {
};
this.dispatchEvent = this.emit = function ( event ) {
-
- for ( var listener in listeners[ event.type ] ) {
- listeners[ event.type ][ listener ]( event );
-
+ if ( !listeners[ event.type ] || !listeners[ event.type ].length ) {
+
+ return;
+
+ }
+
+ for(var i = 0, l = listeners[ event.type ].length; i < l; i++) {
+
+ listeners[ event.type ][ i ]( event );
+
}
};
diff --git a/src/pixi/utils/Polyk.js b/src/pixi/utils/Polyk.js
index 84d290f1..e29d77da 100644
--- a/src/pixi/utils/Polyk.js
+++ b/src/pixi/utils/Polyk.js
@@ -2,7 +2,7 @@
PolyK library
url: http://polyk.ivank.net
Released under MIT licence.
-
+
Copyright (c) 2012 Ivan Kuckir
Permission is hereby granted, free of charge, to any person
@@ -26,8 +26,8 @@
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
OTHER DEALINGS IN THE SOFTWARE.
- This is an amazing lib!
-
+ This is an amazing lib!
+
slightly modified by mat groves (matgroves.com);
*/
@@ -43,13 +43,13 @@ PIXI.PolyK = {};
PIXI.PolyK.Triangulate = function(p)
{
var sign = true;
-
+
var n = p.length>>1;
if(n<3) return [];
var tgs = [];
var avl = [];
for(var i=0; i 3)
@@ -57,11 +57,11 @@ PIXI.PolyK.Triangulate = function(p)
var i0 = avl[(i+0)%al];
var i1 = avl[(i+1)%al];
var i2 = avl[(i+2)%al];
-
+
var ax = p[2*i0], ay = p[2*i0+1];
var bx = p[2*i1], by = p[2*i1+1];
var cx = p[2*i2], cy = p[2*i2+1];
-
+
var earFound = false;
if(PIXI.PolyK._convex(ax, ay, bx, by, cx, cy, sign))
{
@@ -80,7 +80,7 @@ PIXI.PolyK.Triangulate = function(p)
al--;
i = 0;
}
- else if(i++ > 3*al)
+ else if(i++ > 3*al)
{
// need to flip flip reverse it!
// reset!
@@ -89,17 +89,17 @@ PIXI.PolyK.Triangulate = function(p)
var tgs = [];
avl = [];
for(var i=0; i> 16 & 0xFF) / 255, ( hex >> 8 & 0xFF) / 255, (hex & 0xFF)/ 255];
@@ -60,19 +60,19 @@ if (typeof Function.prototype.bind != 'function') {
var slice = Array.prototype.slice;
return function (thisArg) {
var target = this, boundArgs = slice.call(arguments, 1);
-
+
if (typeof target != 'function') throw new TypeError();
-
+
function bound() {
var args = boundArgs.concat(slice.call(arguments));
target.apply(this instanceof bound ? this : thisArg, args);
}
-
+
bound.prototype = (function F(proto) {
proto && (F.prototype = proto);
- if (!(this instanceof F)) return new F;
+ if (!(this instanceof F)) return new F;
})(target.prototype);
-
+
return bound;
};
})();
@@ -86,8 +86,8 @@ if (typeof Function.prototype.bind != 'function') {
*/
var AjaxRequest = PIXI.AjaxRequest = function()
{
- var activexmodes = ["Msxml2.XMLHTTP", "Microsoft.XMLHTTP"] //activeX versions to check for in IE
-
+ var activexmodes = ["Msxml2.XMLHTTP.6.0", "Msxml2.XMLHTTP.3.0", "Microsoft.XMLHTTP"] //activeX versions to check for in IE
+
if (window.ActiveXObject)
{ //Test for support for ActiveXObject in IE first (as XMLHttpRequest in IE7 is broken)
for (var i=0; i 100)
{
console.log("BREAK")
break
}
- }
+ }
}
diff --git a/src/system/RequestAnimationFrame.js b/src/system/RequestAnimationFrame.js
index 6fe2ae74..8d3ca09f 100644
--- a/src/system/RequestAnimationFrame.js
+++ b/src/system/RequestAnimationFrame.js
@@ -50,6 +50,13 @@ Phaser.RequestAnimationFrame = function(game) {
*/
this._onLoop = null;
+ /**
+ * The callback ID used when calling cancel
+ * @property _timeOutID
+ * @private
+ */
+ this._timeOutID = null;
+
};
Phaser.RequestAnimationFrame.prototype = {
@@ -83,7 +90,7 @@ Phaser.RequestAnimationFrame.prototype = {
return _this.updateRAF(time);
};
- window.requestAnimationFrame(this._onLoop);
+ this._timeOutID = window.requestAnimationFrame(this._onLoop);
}
},
@@ -97,7 +104,7 @@ Phaser.RequestAnimationFrame.prototype = {
this.game.update(time);
- window.requestAnimationFrame(this._onLoop);
+ this._timeOutID = window.requestAnimationFrame(this._onLoop);
},
@@ -125,7 +132,7 @@ Phaser.RequestAnimationFrame.prototype = {
}
else
{
- window.cancelAnimationFrame;
+ window.cancelAnimationFrame(this._timeOutID);
}
this.isRunning = false;
diff --git a/src/system/StageScaleMode.js b/src/system/StageScaleMode.js
index 142e4610..c9318806 100644
--- a/src/system/StageScaleMode.js
+++ b/src/system/StageScaleMode.js
@@ -17,45 +17,19 @@
Phaser.StageScaleMode = function (game, width, height) {
/**
- * @property {number} _startHeight - Stage height when starting the game.
- * @default
- * @private
+ * @property {Phaser.Game} game - A reference to the currently running game.
*/
- this._startHeight = 0;
+ this.game = game;
/**
- * @property {boolean} forceLandscape - If the game should be forced to use Landscape mode, this is set to true by Game.Stage
- * @default
+ * @property {number} width - Width of the stage after calculation.
*/
- this.forceLandscape = false;
+ this.width = width;
/**
- * @property {boolean} forcePortrait - If the game should be forced to use Portrait mode, this is set to true by Game.Stage
- * @default
+ * @property {number} height - Height of the stage after calculation.
*/
- this.forcePortrait = false;
-
- /**
- * @property {boolean} incorrectOrientation - If the game should be forced to use a specific orientation and the device currently isn't in that orientation this is set to true.
- * @default
- */
- this.incorrectOrientation = false;
-
- /**
- * @property {boolean} pageAlignHorizontally - If you wish to align your game in the middle of the page then you can set this value to true.
-
It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.
-
It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.
- * @default
- */
- this.pageAlignHorizontally = false;
-
- /**
- * @property {boolean} pageAlignVertically - If you wish to align your game in the middle of the page then you can set this value to true.
-
It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.
-
It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.
- * @default
- */
- this.pageAlignVertically = false;
+ this.height = height;
/**
* @property {number} minWidth - Minimum width the canvas should be scaled to (in pixels).
@@ -84,14 +58,45 @@ Phaser.StageScaleMode = function (game, width, height) {
this.maxHeight = null;
/**
- * @property {number} width - Width of the stage after calculation.
+ * @property {number} _startHeight - Stage height when starting the game.
+ * @default
+ * @private
*/
- this.width = width;
+ this._startHeight = 0;
/**
- * @property {number} height - Height of the stage after calculation.
+ * @property {boolean} forceLandscape - If the game should be forced to use Landscape mode, this is set to true by Game.Stage
+ * @default
*/
- this.height = height;
+ this.forceLandscape = false;
+
+ /**
+ * @property {boolean} forcePortrait - If the game should be forced to use Portrait mode, this is set to true by Game.Stage
+ * @default
+ */
+ this.forcePortrait = false;
+
+ /**
+ * @property {boolean} incorrectOrientation - If the game should be forced to use a specific orientation and the device currently isn't in that orientation this is set to true.
+ * @default
+ */
+ this.incorrectOrientation = false;
+
+ /**
+ * @property {boolean} pageAlignHorizontally - If you wish to align your game in the middle of the page then you can set this value to true.
+ * It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.
+ * It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.
+ * @default
+ */
+ this.pageAlignHorizontally = false;
+
+ /**
+ * @property {boolean} pageAlignVertically - If you wish to align your game in the middle of the page then you can set this value to true.
+ * It will place a re-calculated margin-left pixel value onto the canvas element which is updated on orientation/resizing.
+ * It doesn't care about any other DOM element that may be on the page, it literally just sets the margin.
+ * @default
+ */
+ this.pageAlignVertically = false;
/**
* @property {number} _width - Cached stage width for full screen mode.
@@ -113,18 +118,20 @@ Phaser.StageScaleMode = function (game, width, height) {
*/
this.maxIterations = 5;
- /**
- * @property {Phaser.Game} game - A reference to the currently running game.
- */
- this.game = game;
/**
- * @property {Description} enterLandscape - Description.
+ * @property {PIXI.Sprite} orientationSprite - The Sprite that is optionally displayed if the browser enters an unsupported orientation.
+ * @default
+ */
+ this.orientationSprite = null;
+
+ /**
+ * @property {Phaser.Signal} enterLandscape - The event that is dispatched when the browser enters landscape orientation.
*/
this.enterLandscape = new Phaser.Signal();
/**
- * @property {Description} enterPortrait - Description.
+ * @property {Phaser.Signal} enterPortrait - The event that is dispatched when the browser enters horizontal orientation.
*/
this.enterPortrait = new Phaser.Signal();
@@ -145,7 +152,7 @@ Phaser.StageScaleMode = function (game, width, height) {
}
/**
- * @property {Description} scaleFactor - Description.
+ * @property {Phaser.Point} scaleFactor - The scale factor based on the game dimensions vs. the scaled dimensions.
*/
this.scaleFactor = new Phaser.Point(1, 1);
@@ -298,6 +305,54 @@ Phaser.StageScaleMode.prototype = {
},
+ /**
+ * If you need your game to run in only one orientation you can force that to happen.
+ * The optional orientationImage is displayed when the game is in the incorrect orientation.
+ * @method Phaser.StageScaleMode#forceOrientation
+ * @param {boolean} forceLandscape - true if the game should run in landscape mode only.
+ * @param {boolean} forcePortrait - true if the game should run in portrait mode only.
+ * @param {string} [forcePortrait=''] - The string of an image in the Phaser.Cache to display when this game is in the incorrect orientation.
+ */
+ forceOrientation: function (forceLandscape, forcePortrait, orientationImage) {
+
+ this.forceLandscape = forceLandscape;
+
+ if (typeof forcePortrait === 'undefined')
+ {
+ this.forcePortrait = false;
+ }
+
+ if (typeof orientationImage !== 'undefined')
+ {
+ if (orientationImage == null || this.game.cache.checkImageKey(orientationImage) == false)
+ {
+ orientationImage = '__default';
+ }
+
+ this.orientationSprite = new PIXI.Sprite(PIXI.TextureCache[orientationImage]);
+ this.orientationSprite.anchor.x = 0.5;
+ this.orientationSprite.anchor.y = 0.5;
+ this.orientationSprite.position.x = this.game.width / 2;
+ this.orientationSprite.position.y = this.game.height / 2;
+
+ this.checkOrientationState();
+
+ if (this.incorrectOrientation)
+ {
+ this.orientationSprite.visible = true;
+ this.game.world.visible = false;
+ }
+ else
+ {
+ this.orientationSprite.visible = false;
+ this.game.world.visible = true;
+ }
+
+ this.game.stage._stage.addChild(this.orientationSprite);
+ }
+
+ },
+
/**
* Checks if the browser is in the correct orientation for your game (if forceLandscape or forcePortrait have been set)
* @method Phaser.StageScaleMode#checkOrientationState
@@ -312,6 +367,13 @@ Phaser.StageScaleMode.prototype = {
// Back to normal
this.game.paused = false;
this.incorrectOrientation = false;
+
+ if (this.orientationSprite)
+ {
+ this.orientationSprite.visible = false;
+ this.game.world.visible = true;
+ }
+
this.refresh();
}
}
@@ -322,6 +384,13 @@ Phaser.StageScaleMode.prototype = {
// Show orientation screen
this.game.paused = true;
this.incorrectOrientation = true;
+
+ if (this.orientationSprite && this.orientationSprite.visible == false)
+ {
+ this.orientationSprite.visible = true;
+ this.game.world.visible = false;
+ }
+
this.refresh();
}
}
@@ -381,6 +450,9 @@ Phaser.StageScaleMode.prototype = {
{
this.refresh();
}
+
+ this.checkOrientationState();
+
},
/**
@@ -420,7 +492,7 @@ Phaser.StageScaleMode.prototype = {
/**
* Set screen size automatically based on the scaleMode.
- * @param {Description} force - If force is true it will try to resize the game regardless of the document dimensions.
+ * @param {boolean} force - If force is true it will try to resize the game regardless of the document dimensions.
*/
setScreenSize: function (force) {
@@ -533,6 +605,8 @@ Phaser.StageScaleMode.prototype = {
this.scaleFactor.x = this.game.width / this.width;
this.scaleFactor.y = this.game.height / this.height;
+ this.checkOrientationState();
+
},
/**
diff --git a/src/utils/Utils.js b/src/utils/Utils.js
index 05634dc6..6be67fe6 100644
--- a/src/utils/Utils.js
+++ b/src/utils/Utils.js
@@ -10,6 +10,12 @@
*/
Phaser.Utils = {
+ /**
+ * A standard Fisher-Yates Array shuffle implementation.
+ * @method Phaser.Utils.shuffle
+ * @param {array} array - The array to shuffle.
+ * @return {array} The shuffled array.
+ */
shuffle: function (array) {
for (var i = array.length - 1; i > 0; i--)
@@ -26,14 +32,14 @@ Phaser.Utils = {
/**
* Javascript string pad http://www.webtoolkit.info/.
- * pad = the string to pad it out with (defaults to a space)
+ * pad = the string to pad it out with (defaults to a space)
* dir = 1 (left), 2 (right), 3 (both)
* @method Phaser.Utils.pad
* @param {string} str - The target string.
* @param {number} len - Description.
* @param {number} pad - the string to pad it out with (defaults to a space).
* @param {number} [dir=3] the direction dir = 1 (left), 2 (right), 3 (both).
- * @return {string}
+ * @return {string} The padded string
*/
pad: function (str, len, pad, dir) {
diff --git a/tutorials/01 Getting Started/index.html b/tutorials/01 Getting Started/index.html
new file mode 100644
index 00000000..f4bb3802
--- /dev/null
+++ b/tutorials/01 Getting Started/index.html
@@ -0,0 +1,80 @@
+
+
+
+
+ Phaser Tutorial 01 - Getting Started
+
+
+
+
+
+
Getting started with Phaser
+
+
Part 1 - Setting up your development environment
+
+
In this tutorial we're going to cover setting-up a development enviornment with which you can build your Phaser games. This will include running a local web server, picking an IDE, getting the latest version of Phaser and checking it all works together properly.
+
+
"But why do I need a local web server anyway? Can't I just drag the html files onto my browser?"
+
+
Not these days, no. I appreciate that it's a bit confusing, even contradictory at times, but it all boils down to browser security in the end. If you're making a static html web site, with a few images in it, then you can happily drag this into your browser and see the end results. You can also "Save As" entire web pages locally and re-open them, with all the contents mostly intact. So why can't you drag an HTML5 game into a browser and have it work?
+
+
It's to do with the protocol used to access the files. When you request anything over the web you're using http - and the server level security is enough to ensure you can only access files you're meant to. But when you drag a file in it's loaded via the local file system (technically file://) and that is a massively restricted one, for obvious reasons. Under file:// there's no concept of domains, no server level security - just a raw file system. Ask yourself this: do you really want JavaScript to have the ability to load files from your local file system? The immediate answer should of course be "no way!". If JavaScript had free reign while operating under file:// there would be nothing stopping it loading up any system file it fancied and sending it off over the net to anywhere it liked.
+
+
Because this is so dangerous browsers lock themselves down tighter than Alcatraz when running under file://. Every single page becomes treated as a unique local domain. That is why "Save Web page" work, to a degree. They still are under the same cross-site restrictions as if they were on a live server. (to a degree, they still can't save anything or send data out or load data like a game), but also why "Save Web page" cannot make a cross site request, i.e. it can't load or send local data elsewhere. There's a quite detailed post here about it: http://blog.chromium.org/2008/12/security-in-depth-local-web-pages.html
+
+
+
+ Due to the way that web browser sandbox security works you will need a local web server running. This is so that your games can load in external assets like images and music. By default web browsers are unable to load local files, as if you think about it for a moment you should be grateful for that fact! Although there are ways to modify your browsers start-up settings to bypass the sandbox security we really don't recommend it, and as you're building games for the web it's only sensible that you run a local environment that as closely emulates the web on which your game will be running anyway.
+
+
+
Download the latest version of Phaser
+
+
+
In this tutorial we're going to build a game that will introduce some of the core features of Phaser to you. Before we begin there are a few things you'll need to have set-up if you haven't already:
+
+
Download the latest version of Phaser
+
+
The latest version of Phaser is available to download from github. At the time of writing that is version 1.1.2. If you aren't familiar with using git then github offer a handy "Download as zip" option which will download the whole repository in a single zip file. You can then unzip this locally and get to all the files. If you are happy using git then pull down the latest version of the repositiory before starting.
+
+
Set-up your development environment
+
+
Method 1: Run a local web server
+
+http://cesanta.com/downloads.html
+
+
On Windows there are lots of "single install" bundles available. These are easy-to-install files that package together popular web technologies like Apache, PHP and MySQL and install them all for you at once, often with a handy system-tray icon to manage them too. We would recommend either WAMP Server or XAMPP. Instead of an 'all in one' bundle you could also download just the web server on its own. Microsoft provide IIS and Apache can be downloaded for Windows as well.
+
+
Note: Skype likes to steal port 80 by default. This is the traditional port for a web server to run over and it might interfer with WAMP or similar being able to start. To disable this within Skype go to "Tools - Options - Connection" and uncheck the "Use port 80 and 443 as alternatives for incoming connections" checkbox.
+
+
On OS X you could download MAMP which comes in two versions (one free, one paid for). Or there are guides for setting up a local web server manually, such as this guide written for Mountain Lion.
+
+
Method 2: grunt connect
+
+
Grunt is an extremely powerful tool to have installed, regardless if you use it as a web server or not. At its essence it's a JavaScript based task runner and allows you to automate tedious time consuming tasks. But it can also be configured with Connect for serving local files and here's a guide on doing just that.
+
+
Method 3: Simple HTTP Server with Python
+
+
If you need a quick web server running and you don't want to mess around with setting up apache or something similar, then Python can help. Python comes with a simple built in HTTP server. With the help of this little HTTP server you can turn any directory in your system into your web server directory. The only thing you need to have installed is Python. Read the full guide here.
+
+
Method 4: http-server for node.js
+
+
http-server is a simple, zero-configuration command-line http server for node.js. It is powerful enough for production usage, but it's simple and hackable enough to be used for testing, local development, and learning. Or as the web site says "Serving up static files like they were turtles strapped to rockets". Get the npm and instructions from the http-server web site.
+
+
Method 5: php 5 built-in web server
+
+
As of PHP 5.4.0, the CLI SAPI provides a built-in web server. It's only really suitable for development purposes and servers all files sequentially, but it's easily powerful enough for testing HTML5 games. It's invoked from a single command-line call and you can find details on how to do this in the PHP Manual