diff --git a/examples/js.php b/examples/js.php
index 7a6cc3849..faf156c24 100644
--- a/examples/js.php
+++ b/examples/js.php
@@ -62,6 +62,7 @@
+
diff --git a/examples/linkedlist1.php b/examples/linkedlist1.php
index a54b5da17..c877264f8 100644
--- a/examples/linkedlist1.php
+++ b/examples/linkedlist1.php
@@ -46,11 +46,11 @@
list = new Phaser.LinkedList();
list.add(a.input);
- // list.add(b.input);
- // list.add(c.input);
- // list.add(d.input);
- // list.add(e.input);
- // list.add(f.input);
+ list.add(b.input);
+ list.add(c.input);
+ list.add(d.input);
+ list.add(e.input);
+ list.add(f.input);
list.dump();
diff --git a/examples/touch1.php b/examples/touch1.php
new file mode 100644
index 000000000..120b6e4d4
--- /dev/null
+++ b/examples/touch1.php
@@ -0,0 +1,62 @@
+
+
+
+ phaser.js - a new beginning
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/core/LinkedList.js b/src/core/LinkedList.js
index 675099a37..84e3d0a35 100644
--- a/src/core/LinkedList.js
+++ b/src/core/LinkedList.js
@@ -7,17 +7,19 @@ Phaser.LinkedList.prototype = {
prev: null,
first: null,
last: null,
+ total: 0,
sprite: { name: 'HD' },
add: function (child) {
// If the list is empty
- if (this.first == null && this.last == null)
+ if (this.total == 0 && this.first == null && this.last == null)
{
this.first = child;
this.last = child;
this.next = child;
child.prev = this;
+ this.total++;
return;
}
@@ -28,6 +30,10 @@ Phaser.LinkedList.prototype = {
this.last = child;
+ this.total++;
+
+ return child;
+
},
remove: function (child) {
@@ -38,6 +44,8 @@ Phaser.LinkedList.prototype = {
return;
}
+ this.total--;
+
// The only node?
if (this.first == child && this.last == child)
{
diff --git a/src/gameobjects/Events.js b/src/gameobjects/Events.js
new file mode 100644
index 000000000..e92e3bbb6
--- /dev/null
+++ b/src/gameobjects/Events.js
@@ -0,0 +1,21 @@
+/**
+* The Events component is a collection of events fired by the parent game object and its components.
+* @param parent The game object using this Input component
+*/
+Phaser.Events = function (sprite) {
+
+ this.parent = sprite;
+ this.onAddedToGroup = new Phaser.Signal;
+ this.onRemovedFromGroup = new Phaser.Signal;
+ this.onKilled = new Phaser.Signal;
+ this.onRevived = new Phaser.Signal;
+ this.onOutOfBounds = new Phaser.Signal;
+
+ this.onInputOver = null;
+ this.onInputOut = null;
+ this.onInputDown = null;
+ this.onInputUp = null;
+ this.onDragStart = null;
+ this.onDragStop = null;
+
+};
\ No newline at end of file
diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js
index 2be8a5d24..863abd856 100644
--- a/src/gameobjects/Sprite.js
+++ b/src/gameobjects/Sprite.js
@@ -29,7 +29,7 @@ Phaser.Sprite = function (game, x, y, key, frame) {
PIXI.Sprite.call(this);
}
- // this.events = new Phaser.Components.Events(this);
+ this.events = new Phaser.Events(this);
/**
* This manages animations of the sprite. You can modify animations through it. (see AnimationManager)
@@ -102,6 +102,9 @@ Phaser.Sprite = function (game, x, y, key, frame) {
// Transform cache
a00: 1, a01: 0, a02: x, a10: 0, a11: 1, a12: y, id: 1,
+ // Input specific transform cache
+ i01: 0, i10: 0, idi: 1,
+
// Bounds check
left: null, right: null, top: null, bottom: null,
@@ -188,6 +191,7 @@ Phaser.Sprite.prototype.update = function() {
{
this._cache.a00 = this.worldTransform[0]; // scaleX a
this._cache.a01 = this.worldTransform[1]; // skewY c
+ this._cache.i01 = this.worldTransform[1]; // skewY c
this._cache.scaleX = Math.sqrt((this._cache.a00 * this._cache.a00) + (this._cache.a01 * this._cache.a01)); // round this off a bit?
this._cache.a01 *= -1;
this._cache.dirty = true;
@@ -197,6 +201,7 @@ Phaser.Sprite.prototype.update = function() {
if (this.worldTransform[3] != this._cache.a10 || this.worldTransform[4] != this._cache.a11)
{
this._cache.a10 = this.worldTransform[3]; // skewX b
+ this._cache.i10 = this.worldTransform[3]; // skewX b
this._cache.a11 = this.worldTransform[4]; // scaleY d
this._cache.scaleY = Math.sqrt((this._cache.a10 * this._cache.a10) + (this._cache.a11 * this._cache.a11)); // round this off a bit?
this._cache.a10 *= -1;
@@ -227,6 +232,7 @@ Phaser.Sprite.prototype.update = function() {
this._cache.halfHeight = Math.floor(this._cache.height / 2);
this._cache.id = 1 / (this._cache.a00 * this._cache.a11 + this._cache.a01 * -this._cache.a10);
+ this._cache.idi = 1 / (this._cache.a00 * this._cache.a11 + this._cache.i01 * -this._cache.i10);
this.updateBounds();
}
@@ -262,11 +268,6 @@ Phaser.Sprite.prototype.update = function() {
this.body.update();
- if (this.input.enabled)
- {
- this.input.update();
- }
-
}
Phaser.Sprite.prototype.postUpdate = function() {
@@ -309,6 +310,15 @@ Phaser.Sprite.prototype.getLocalPosition = function(p, x, y) {
}
+Phaser.Sprite.prototype.getLocalUnmodifiedPosition = function(p, x, y) {
+
+ p.x = this._cache.a11 * this._cache.idi * x + -this._cache.i01 * this._cache.idi * y + (this._cache.a12 * this._cache.i01 - this._cache.a02 * this._cache.a11) * this._cache.idi;
+ p.y = this._cache.a00 * this._cache.idi * y + -this._cache.i10 * this._cache.idi * x + (-this._cache.a12 * this._cache.a00 + this._cache.a02 * this._cache.i10) * this._cache.idi;
+
+ return p;
+
+}
+
Phaser.Sprite.prototype.getBounds = function(rect) {
rect = rect || new Phaser.Rectangle;
diff --git a/src/input/Input.js b/src/input/Input.js
index c3c16386d..3d9f2cff2 100644
--- a/src/input/Input.js
+++ b/src/input/Input.js
@@ -370,7 +370,7 @@ Phaser.Input.prototype = {
**/
reset: function (hard) {
- if (typeof hard === "undefined") { hard = false; }
+ hard = hard || false;
this.keyboard.reset();
this.mousePointer.reset();
@@ -428,7 +428,8 @@ Phaser.Input.prototype = {
**/
startPointer: function (event) {
- if (this.maxPointers < 10 && this.totalActivePointers == this.maxPointers) {
+ if (this.maxPointers < 10 && this.totalActivePointers == this.maxPointers)
+ {
return null;
}
@@ -525,7 +526,7 @@ Phaser.Input.prototype = {
**/
getPointer: function (state) {
- if (typeof state === "undefined") { state = false; }
+ state = state || false;
if (this.pointer1.active == state)
{
@@ -599,10 +600,7 @@ Phaser.Input.prototype = {
**/
getAngle: function (pointer1, pointer2) {
// return Phaser.Vec2Utils.angle(pointer1.position, pointer2.position);
- },
-
- addGameObject: function() {},
- removeGameObject: function() {},
+ }
};
diff --git a/src/input/InputHandler.js b/src/input/InputHandler.js
index b562e7a63..c6a31d3fb 100644
--- a/src/input/InputHandler.js
+++ b/src/input/InputHandler.js
@@ -104,7 +104,7 @@ Phaser.InputHandler.prototype = {
this.enabled = true;
// Create the signals the Input component will emit
- if (this.sprites.events && this.sprite.events.onInputOver == null)
+ if (this.sprite.events && this.sprite.events.onInputOver == null)
{
this.sprite.events.onInputOver = new Phaser.Signal;
this.sprite.events.onInputOut = new Phaser.Signal;
@@ -316,13 +316,13 @@ Phaser.InputHandler.prototype = {
},
/**
- * Checks if the given pointer is over this Sprite. All checks are done in world coordinates.
+ * Checks if the given pointer is over this Sprite.
*/
checkPointerOver: function (pointer) {
if (this.enabled && this.sprite.visible)
{
- this.sprite.getLocalPosition(this._tempPoint, pointer.x, pointer.y);
+ this.sprite.getLocalUnmodifiedPosition(this._tempPoint, pointer.x, pointer.y);
// Check against bounds
var width = this.sprite.texture.frame.width,
@@ -330,11 +330,11 @@ Phaser.InputHandler.prototype = {
x1 = -width * this.sprite.anchor.x,
y1;
- if(x > x1 && x < x1 + width)
+ if (this._tempPoint.x > x1 && this._tempPoint.x < x1 + width)
{
y1 = -height * this.sprite.anchor.y;
- if(y > y1 && y < y1 + height)
+ if (this._tempPoint.y > y1 && this._tempPoint.y < y1 + height)
{
return true;
}
@@ -364,7 +364,7 @@ Phaser.InputHandler.prototype = {
}
else if (this._pointerData[pointer.id].isOver == true)
{
- if (Phaser.SpriteUtils.overlapsPointer(this.sprite, pointer))
+ if (this.checkPointerOver(pointer))
{
this._pointerData[pointer.id].x = pointer.x - this.sprite.x;
this._pointerData[pointer.id].y = pointer.y - this.sprite.y;
@@ -449,7 +449,7 @@ Phaser.InputHandler.prototype = {
this._pointerData[pointer.id].downDuration = this._pointerData[pointer.id].timeUp - this._pointerData[pointer.id].timeDown;
// Only release the InputUp signal if the pointer is still over this sprite
- if (Phaser.SpriteUtils.overlapsPointer(this.sprite, pointer))
+ if (this.checkPointerOver(pointer))
{
//console.log('releasedHandler: ' + Date.now());
this.sprite.events.onInputUp.dispatch(this.sprite, pointer);
diff --git a/src/input/Pointer.js b/src/input/Pointer.js
index 895e88f0a..a388d486b 100644
--- a/src/input/Pointer.js
+++ b/src/input/Pointer.js
@@ -259,7 +259,7 @@ Phaser.Pointer.prototype = {
if (this.targetObject !== null)
{
- this.targetObject.input._touchedHandler(this);
+ this.targetObject._touchedHandler(this);
}
return this;
@@ -349,9 +349,9 @@ Phaser.Pointer.prototype = {
}
// Easy out if we're dragging something and it still exists
- if (this.targetObject !== null && this.targetObject.input && this.targetObject.input.isDragged == true)
+ if (this.targetObject !== null && this.targetObject.isDragged == true)
{
- if (this.targetObject.input.update(this) == false)
+ if (this.targetObject.update(this) == false)
{
this.targetObject = null;
}
@@ -366,47 +366,36 @@ Phaser.Pointer.prototype = {
this._highestInputPriorityID = -1;
// Just run through the linked list
- if (this.game.input.interactiveItems.next)
+ if (this.game.input.interactiveItems.total > 0)
{
var currentNode = this.game.input.interactiveItems.next;
-
+
do
{
// If the object has a higher InputManager.PriorityID OR if the priority ID is the same as the current highest AND it has a higher renderOrderID, then set it to the top
- if (currentNode.priorityID > this._highestInputPriorityID || (currentNode.priorityID == this._highestInputPriorityID && currentNode.sprite.renderOrderID > this._highestRenderOrderID) && currentNode.checkPointerOver(this))
+ if (currentNode.priorityID > this._highestInputPriorityID || (currentNode.priorityID == this._highestInputPriorityID && currentNode.sprite.renderOrderID > this._highestRenderOrderID))
{
- this._highestRenderOrderID = currentNode.sprite.renderOrderID;
- this._highestInputPriorityID = currentNode.priorityID;
- this._highestRenderObject = currentNode;
+ if (currentNode.checkPointerOver(this))
+ {
+ // console.log('HRO set', currentNode.sprite.name);
+ this._highestRenderOrderID = currentNode.sprite.renderOrderID;
+ this._highestInputPriorityID = currentNode.priorityID;
+ this._highestRenderObject = currentNode;
+ }
}
-
currentNode = currentNode.next;
}
- while (currentNode != this.game.input.interactiveItems.next)
+ while (currentNode != null)
}
-
-/*
- for (var i = 0; i < this.game.input.totalTrackedObjects; i++)
- {
- if (this.game.input.inputObjects[i] && this.game.input.inputObjects[i].input && this.game.input.inputObjects[i].input.checkPointerOver(this))
- {
- // If the object has a higher InputManager.PriorityID OR if the priority ID is the same as the current highest AND it has a higher renderOrderID, then set it to the top
- if (this.game.input.inputObjects[i].input.priorityID > this._highestInputPriorityID || (this.game.input.inputObjects[i].input.priorityID == this._highestInputPriorityID && this.game.input.inputObjects[i].renderOrderID > this._highestRenderOrderID))
- {
- this._highestRenderOrderID = this.game.input.inputObjects[i].renderOrderID;
- this._highestRenderObject = i;
- this._highestInputPriorityID = this.game.input.inputObjects[i].input.priorityID;
- }
- }
- }
-*/
-
if (this._highestRenderObject == null)
{
+ // console.log("HRO null");
+
// The pointer isn't currently over anything, check if we've got a lingering previous target
if (this.targetObject)
{
+ // console.log("The pointer isn't currently over anything, check if we've got a lingering previous target");
this.targetObject._pointerOutHandler(this);
this.targetObject = null;
}
@@ -416,15 +405,18 @@ Phaser.Pointer.prototype = {
if (this.targetObject == null)
{
// And now set the new one
+ // console.log('And now set the new one');
this.targetObject = this._highestRenderObject;
this._highestRenderObject._pointerOverHandler(this);
}
else
{
// We've got a target from the last update
+ // console.log("We've got a target from the last update");
if (this.targetObject == this._highestRenderObject)
{
// Same target as before, so update it
+ // console.log("Same target as before, so update it");
if (this._highestRenderObject.update(this) == false)
{
this.targetObject = null;
@@ -433,6 +425,7 @@ Phaser.Pointer.prototype = {
else
{
// The target has changed, so tell the old one we've left it
+ // console.log("The target has changed, so tell the old one we've left it");
this.targetObject._pointerOutHandler(this);
// And now set the new one
@@ -511,17 +504,20 @@ Phaser.Pointer.prototype = {
this.game.input.currentPointers--;
}
- if (this.game.input.interactiveItems.next)
+ if (this.game.input.interactiveItems.total > 0)
{
var currentNode = this.game.input.interactiveItems.next;
do
{
- currentNode._releasedHandler(this);
+ if (currentNode)
+ {
+ currentNode._releasedHandler(this);
+ }
currentNode = currentNode.next;
}
- while (currentNode != this.game.input.interactiveItems.next)
+ while (currentNode != null)
}
if (this.targetObject)
@@ -631,7 +627,7 @@ Object.defineProperty(Phaser.Pointer.prototype, "worldX", {
*/
get: function () {
- return this.game.world.camera.worldView.x + this.x;
+ return this.game.world.camera.x + this.x;
},
@@ -647,7 +643,7 @@ Object.defineProperty(Phaser.Pointer.prototype, "worldY", {
*/
get: function () {
- return this.game.world.camera.worldView.y + this.y;
+ return this.game.world.camera.y + this.y;
},
diff --git a/src/utils/Debug.js b/src/utils/Debug.js
index f571c9e6e..600e4298d 100644
--- a/src/utils/Debug.js
+++ b/src/utils/Debug.js
@@ -246,21 +246,22 @@ Phaser.Utils.Debug.prototype = {
*/
renderPointer: function (pointer, hideIfUp, downColor, upColor, color) {
- if (this.context == null)
+ if (this.context == null || pointer == null)
{
return;
}
- if (typeof hideIfUp === "undefined") { hideIfUp = false; }
- if (typeof downColor === "undefined") { downColor = 'rgba(0,255,0,0.5)'; }
- if (typeof upColor === "undefined") { upColor = 'rgba(255,0,0,0.5)'; }
- if (typeof color === "undefined") { color = 'rgb(255,255,255)'; }
+ hideIfUp = hideIfUp || false;
+ downColor = downColor || 'rgba(0,255,0,0.5)';
+ upColor = upColor || 'rgba(255,0,0,0.5)';
+ color = color || 'rgb(255,255,255)';
if (hideIfUp == true && pointer.isUp == true)
{
return;
}
+ this.start(pointer.x, pointer.y - 100, color);
this.context.beginPath();
this.context.arc(pointer.x, pointer.y, pointer.circle.radius, 0, Math.PI * 2);
@@ -285,11 +286,32 @@ Phaser.Utils.Debug.prototype = {
this.context.closePath();
// Render the text
- this.start(pointer.x, pointer.y - 100, color);
+ // this.start(pointer.x, pointer.y - 100, color);
this.line('ID: ' + pointer.id + " Active: " + pointer.active);
this.line('World X: ' + pointer.worldX + " World Y: " + pointer.worldY);
this.line('Screen X: ' + pointer.x + " Screen Y: " + pointer.y);
this.line('Duration: ' + pointer.duration + " ms");
+ this.stop();
+
+ },
+
+ /**
+ * Render Sprite Input Debug information
+ * @param x {number} X position of the debug info to be rendered.
+ * @param y {number} Y position of the debug info to be rendered.
+ * @param [color] {number} color of the debug info to be rendered. (format is css color string)
+ */
+ renderSpriteInputInfo: function (sprite, x, y, color) {
+
+ color = color || 'rgb(255,255,255)';
+
+ this.start(x, y, color);
+ this.line('Sprite Input: (' + sprite.width + ' x ' + sprite.height + ')');
+ this.line('x: ' + sprite.input.pointerX().toFixed(1) + ' y: ' + sprite.input.pointerY().toFixed(1));
+ this.line('over: ' + sprite.input.pointerOver() + ' duration: ' + sprite.input.overDuration().toFixed(0));
+ this.line('down: ' + sprite.input.pointerDown() + ' duration: ' + sprite.input.downDuration().toFixed(0));
+ this.line('just over: ' + sprite.input.justOver() + ' just out: ' + sprite.input.justOut());
+ this.stop();
},