diff --git a/examples/a_template.php b/examples/a_template.php
index 9b4ec4c31..69811ff73 100644
--- a/examples/a_template.php
+++ b/examples/a_template.php
@@ -22,10 +22,13 @@
function create() {
- // var tempSprite = game.add.sprite(game.world.randomX, game.world.randomY, game.rnd.pick(images));
+ // var tempSprite = game.add.sprite(game.world.randomX, game.world.randomY, 'atari1');
}
+ function update() {
+ }
+
function render() {
}
diff --git a/examples/camerafollow.php b/examples/camerafollow.php
new file mode 100644
index 000000000..97e4dcc5c
--- /dev/null
+++ b/examples/camerafollow.php
@@ -0,0 +1,79 @@
+
+
+
+ phaser.js - a new beginning
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/pixelpick.php b/examples/pixelpick.php
new file mode 100644
index 000000000..4d37e8f26
--- /dev/null
+++ b/examples/pixelpick.php
@@ -0,0 +1,66 @@
+
+
+
+ phaser.js - a new beginning
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/pixelpick2.php b/examples/pixelpick2.php
new file mode 100644
index 000000000..697b5c50b
--- /dev/null
+++ b/examples/pixelpick2.php
@@ -0,0 +1,69 @@
+
+
+
+ phaser.js - a new beginning
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/pixelpick3.php b/examples/pixelpick3.php
new file mode 100644
index 000000000..000acd7ce
--- /dev/null
+++ b/examples/pixelpick3.php
@@ -0,0 +1,118 @@
+
+
+
+ phaser.js - a new beginning
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/examples/world.php b/examples/world.php
new file mode 100644
index 000000000..1061a3a89
--- /dev/null
+++ b/examples/world.php
@@ -0,0 +1,106 @@
+
+
+
+ phaser.js - a new beginning
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/src/core/Camera.js b/src/core/Camera.js
index 584c5bc31..4d0cf1c19 100644
--- a/src/core/Camera.js
+++ b/src/core/Camera.js
@@ -21,6 +21,10 @@ Phaser.Camera = function (game, id, x, y, width, height) {
*/
this.view = new Phaser.Rectangle(x, y, width, height);
+ /**
+ * Used by Sprites to work out Camera culling.
+ * @type {Rectangle}
+ */
this.screenView = new Phaser.Rectangle(x, y, width, height);
/**
@@ -35,11 +39,19 @@ Phaser.Camera = function (game, id, x, y, width, height) {
*/
this.visible = true;
+ /**
+ * Whether this camera is flush with the World Bounds or not.
+ * @type {bool}
+ */
+ this.atLimit = { x: false, y: false };
+
/**
* If the camera is tracking a Sprite, this is a reference to it, otherwise null
* @type {Sprite}
*/
this.target = null;
+
+ this._edge = 0;
};
@@ -66,23 +78,23 @@ Phaser.Camera.prototype = {
switch (style) {
- case Phaser.Types.CAMERA_FOLLOW_PLATFORMER:
+ case Phaser.Camera.FOLLOW_PLATFORMER:
var w = this.width / 8;
var h = this.height / 3;
this.deadzone = new Phaser.Rectangle((this.width - w) / 2, (this.height - h) / 2 - h * 0.25, w, h);
break;
- case Phaser.Types.CAMERA_FOLLOW_TOPDOWN:
+ case Phaser.Camera.FOLLOW_TOPDOWN:
helper = Math.max(this.width, this.height) / 4;
this.deadzone = new Phaser.Rectangle((this.width - helper) / 2, (this.height - helper) / 2, helper, helper);
break;
- case Phaser.Types.CAMERA_FOLLOW_TOPDOWN_TIGHT:
+ case Phaser.Camera.FOLLOW_TOPDOWN_TIGHT:
helper = Math.max(this.width, this.height) / 8;
this.deadzone = new Phaser.Rectangle((this.width - helper) / 2, (this.height - helper) / 2, helper, helper);
break;
- case Phaser.Types.CAMERA_FOLLOW_LOCKON:
+ case Phaser.Camera.FOLLOW_LOCKON:
default:
this.deadzone = null;
break;
@@ -97,9 +109,6 @@ Phaser.Camera.prototype = {
*/
focusOnXY: function (x, y) {
- x += (x > 0) ? 0.0000001 : -0.0000001;
- y += (y > 0) ? 0.0000001 : -0.0000001;
-
this.view.x = Math.round(x - this.view.halfWidth);
this.view.y = Math.round(y - this.view.halfHeight);
@@ -110,83 +119,89 @@ Phaser.Camera.prototype = {
*/
update: function () {
- // this.plugins.preUpdate();
-
// Add dirty flag
if (this.target !== null)
{
- if (this.deadzone == null)
+ if (this.deadzone)
{
- this.focusOnXY(this.target.x, this.target.y);
+ this._edge = this.target.x - this.deadzone.x;
+
+ if (this.view.x > this._edge)
+ {
+ this.view.x = this._edge;
+ }
+
+ this._edge = this.target.x + this.target.width - this.deadzone.x - this.deadzone.width;
+
+ if (this.view.x < this._edge)
+ {
+ this.view.x = this._edge;
+ }
+
+ this._edge = this.target.y - this.deadzone.y;
+
+ if (this.view.y > this._edge)
+ {
+ this.view.y = this._edge;
+ }
+
+ this._edge = this.target.y + this.target.height - this.deadzone.y - this.deadzone.height;
+
+ if (this.view.y < this._edge)
+ {
+ this.view.y = this._edge;
+ }
}
else
{
- var edge;
- var targetX = this.target.x + ((this.target.x > 0) ? 0.0000001 : -0.0000001);
- var targetY = this.target.y + ((this.target.y > 0) ? 0.0000001 : -0.0000001);
-
- edge = targetX - this.deadzone.x;
-
- if (this.view.x > edge)
- {
- this.view.x = edge;
- }
-
- edge = targetX + this.target.width - this.deadzone.x - this.deadzone.width;
-
- if (this.view.x < edge)
- {
- this.view.x = edge;
- }
-
- edge = targetY - this.deadzone.y;
-
- if (this.view.y > edge)
- {
- this.view.y = edge;
- }
-
- edge = targetY + this.target.height - this.deadzone.y - this.deadzone.height;
-
- if (this.view.y < edge)
- {
- this.view.y = edge;
- }
+ this.focusOnXY(this.target.x, this.target.y);
}
}
+ this.checkWorldBounds();
+
+ },
+
+ checkWorldBounds: function () {
+
+ this.atLimit.x = false;
+ this.atLimit.y = false;
+
// Make sure we didn't go outside the cameras worldBounds
if (this.view.x < this.world.bounds.left)
{
+ this.atLimit.x = true;
this.view.x = this.world.bounds.left;
}
if (this.view.x > this.world.bounds.right - this.width)
{
+ this.atLimit.x = true;
this.view.x = (this.world.bounds.right - this.width) + 1;
}
if (this.view.y < this.world.bounds.top)
{
+ this.atLimit.y = true;
this.view.y = this.world.bounds.top;
}
if (this.view.y > this.world.bounds.bottom - this.height)
{
+ this.atLimit.y = true;
this.view.y = (this.world.bounds.bottom - this.height) + 1;
}
this.view.floor();
- // this.plugins.update();
-
},
setPosition: function (x, y) {
this.view.x = x;
this.view.y = y;
+ this.checkWorldBounds();
},
@@ -207,6 +222,7 @@ Object.defineProperty(Phaser.Camera.prototype, "x", {
set: function (value) {
this.view.x = value;
+ this.checkWorldBounds();
}
});
@@ -219,6 +235,7 @@ Object.defineProperty(Phaser.Camera.prototype, "y", {
set: function (value) {
this.view.y = value;
+ this.checkWorldBounds();
}
});
diff --git a/src/gameobjects/Sprite.js b/src/gameobjects/Sprite.js
index 0d1dce61e..07c5383fe 100644
--- a/src/gameobjects/Sprite.js
+++ b/src/gameobjects/Sprite.js
@@ -23,6 +23,24 @@ Phaser.Sprite = function (game, x, y, key, frame) {
// The lifespan is decremented by game.time.elapsed each update, once it reaches zero the kill() function is called.
this.lifespan = 0;
+ /**
+ * The Signals you can subscribe to that are dispatched when certain things happen on this Sprite or its components
+ * @type Events
+ */
+ this.events = new Phaser.Events(this);
+
+ /**
+ * This manages animations of the sprite. You can modify animations through it. (see AnimationManager)
+ * @type AnimationManager
+ */
+ this.animations = new Phaser.AnimationManager(this);
+
+ /**
+ * The Input Handler Component
+ * @type InputHandler
+ */
+ this.input = new Phaser.InputHandler(this);
+
this.key = key;
if (key instanceof Phaser.RenderTexture)
@@ -62,24 +80,6 @@ Phaser.Sprite = function (game, x, y, key, frame) {
}
}
- /**
- * The Signals you can subscribe to that are dispatched when certain things happen on this Sprite or its components
- * @type Events
- */
- this.events = new Phaser.Events(this);
-
- /**
- * This manages animations of the sprite. You can modify animations through it. (see AnimationManager)
- * @type AnimationManager
- */
- this.animations = new Phaser.AnimationManager(this);
-
- /**
- * The Input Handler Component
- * @type InputHandler
- */
- this.input = new Phaser.InputHandler(this);
-
/**
* The anchor sets the origin point of the texture.
* The default is 0,0 this means the textures origin is the top left
diff --git a/src/input/Input.js b/src/input/Input.js
index caa26f461..14bc5c5e2 100644
--- a/src/input/Input.js
+++ b/src/input/Input.js
@@ -7,6 +7,9 @@
Phaser.Input = function (game) {
this.game = game;
+
+ this.hitCanvas = null;
+ this.hitContext = null;
};
@@ -283,10 +286,18 @@ Phaser.Input.prototype = {
this.activePointer = this.mousePointer;
this.currentPointers = 0;
- // this.hitCanvas = document.createElement('canvas');
- // this.hitCanvas.width = 1;
- // this.hitCanvas.height = 1;
- // this.hitContext = this.hitCanvas.getContext('2d');
+ this.hitCanvas = document.createElement('canvas');
+ this.hitCanvas.width = 1;
+ this.hitCanvas.height = 1;
+ this.hitContext = this.hitCanvas.getContext('2d');
+
+ // Debugging
+ // this.hitCanvas.style['width'] = '200px';
+ // this.hitCanvas.style['height'] = '200px';
+ // this.hitCanvas.style['position'] = 'absolute';
+ // this.hitCanvas.style['left'] = '810px';
+ // this.hitCanvas.style['backgroundColor'] = '#ef0000';
+ // Phaser.Canvas.addToDOM(this.hitCanvas);
this.mouse.start();
this.keyboard.start();
diff --git a/src/input/InputHandler.js b/src/input/InputHandler.js
index fecde368e..35173284d 100644
--- a/src/input/InputHandler.js
+++ b/src/input/InputHandler.js
@@ -16,17 +16,31 @@ Phaser.InputHandler = function (sprite) {
* The PriorityID controls which Sprite receives an Input event first if they should overlap.
*/
this.priorityID = 0;
+ this.useHandCursor = false;
this.isDragged = false;
- this.dragPixelPerfect = false;
this.allowHorizontalDrag = true;
this.allowVerticalDrag = true;
this.bringToTop = false;
+
+ this.snapOffset = null;
this.snapOnDrag = false;
this.snapOnRelease = false;
this.snapX = 0;
this.snapY = 0;
+ /**
+ * Should we use pixel perfect hit detection? Warning: expensive. Only enable if you really need it!
+ * @default false
+ */
+ this.pixelPerfect = false;
+
+ /**
+ * The alpha tolerance threshold. If the alpha value of the pixel matches or is above this value, it's considered a hit.
+ * @default 255
+ */
+ this.pixelPerfectAlpha = 255;
+
/**
* Is this sprite allowed to be dragged by the mouse? true = yes, false = no
* @default false
@@ -58,10 +72,9 @@ Phaser.InputHandler = function (sprite) {
Phaser.InputHandler.prototype = {
- start: function (priority, checkBody, useHandCursor) {
+ start: function (priority, useHandCursor) {
priority = priority || 0;
- checkBody = checkBody || false;
useHandCursor = useHandCursor || false;
// Turning on
@@ -69,7 +82,6 @@ Phaser.InputHandler.prototype = {
{
// Register, etc
this.game.input.interactiveItems.add(this);
- this.checkBody = checkBody;
this.useHandCursor = useHandCursor;
this.priorityID = priority;
this._pointerData = [];
@@ -317,19 +329,24 @@ Phaser.InputHandler.prototype = {
{
this.sprite.getLocalUnmodifiedPosition(this._tempPoint, pointer.x, pointer.y);
- // Check against bounds
- var width = this.sprite.texture.frame.width,
- height = this.sprite.texture.frame.height,
- x1 = -width * this.sprite.anchor.x,
- y1;
+ // Check against bounds first (move these to private vars)
+ var x1 = -(this.sprite.texture.frame.width) * this.sprite.anchor.x;
+ var y1;
- if (this._tempPoint.x > x1 && this._tempPoint.x < x1 + width)
+ if (this._tempPoint.x > x1 && this._tempPoint.x < x1 + this.sprite.texture.frame.width)
{
- y1 = -height * this.sprite.anchor.y;
+ y1 = -(this.sprite.texture.frame.height) * this.sprite.anchor.y;
- if (this._tempPoint.y > y1 && this._tempPoint.y < y1 + height)
+ if (this._tempPoint.y > y1 && this._tempPoint.y < y1 + this.sprite.texture.frame.height)
{
- return true;
+ if (this.pixelPerfect)
+ {
+ return this.checkPixel(this._tempPoint.x, this._tempPoint.y);
+ }
+ else
+ {
+ return true;
+ }
}
}
}
@@ -338,6 +355,30 @@ Phaser.InputHandler.prototype = {
return false;
}
+ },
+
+ checkPixel: function (x, y) {
+
+ x += (this.sprite.texture.frame.width * this.sprite.anchor.x);
+ y += (this.sprite.texture.frame.height * this.sprite.anchor.y);
+
+ // Grab a pixel from our image into the hitCanvas and then test it
+
+ if (this.sprite.texture.baseTexture.source)
+ {
+ this.game.input.hitContext.clearRect(0, 0, 1, 1);
+ this.game.input.hitContext.drawImage(this.sprite.texture.baseTexture.source, x, y, 1, 1, 0, 0, 1, 1);
+
+ var rgb = this.game.input.hitContext.getImageData(0, 0, 1, 1);
+
+ if (rgb.data[3] >= this.pixelPerfectAlpha)
+ {
+ return true;
+ }
+ }
+
+ return false;
+
},
/**
@@ -620,8 +661,9 @@ Phaser.InputHandler.prototype = {
this.bringToTop = bringToTop;
this.dragOffset = new Phaser.Point();
this.dragFromCenter = lockCenter;
- this.dragPixelPerfect = pixelPerfect;
- this.dragPixelPerfectAlpha = alphaThreshold;
+
+ this.pixelPerfect = pixelPerfect;
+ this.pixelPerfectAlpha = alphaThreshold;
if (boundsRect)
{
diff --git a/src/physics/arcade/Body.js b/src/physics/arcade/Body.js
index 6f5f0fb87..5385e6b39 100644
--- a/src/physics/arcade/Body.js
+++ b/src/physics/arcade/Body.js
@@ -124,8 +124,11 @@ Phaser.Physics.Arcade.Body.prototype = {
postUpdate: function () {
- this.sprite.x = this.x - this.offset.x + (this.sprite.anchor.x * this.width);
- this.sprite.y = this.y - this.offset.y + (this.sprite.anchor.y * this.height);
+ // this.sprite.x = this.x - this.offset.x + (this.sprite.anchor.x * this.width);
+ // this.sprite.y = this.y - this.offset.y + (this.sprite.anchor.y * this.height);
+
+ this.sprite.x = (this.x - this.offset.x + (this.sprite.anchor.x * this.width)) - (this.game.world.camera.x * this.sprite.scrollFactor.x);
+ this.sprite.y = (this.y - this.offset.y + (this.sprite.anchor.y * this.height)) - (this.game.world.camera.y * this.sprite.scrollFactor.y);
if (this.allowRotation)
{
diff --git a/src/utils/Debug.js b/src/utils/Debug.js
index 5444606fe..917971937 100644
--- a/src/utils/Debug.js
+++ b/src/utils/Debug.js
@@ -15,17 +15,17 @@ Phaser.Utils.Debug = function (game) {
this.game = game;
this.context = game.context;
+ this.font = '14px Courier';
+ this.lineHeight = 16;
+ this.renderShadow = true;
+ this.currentX = 0;
+ this.currentY = 0;
+ this.currentAlpha = 1;
+
};
Phaser.Utils.Debug.prototype = {
- font: '14px Courier',
- lineHeight: 16,
- renderShadow: true,
- currentX: 0,
- currentY: 0,
- currentAlpha: 1,
- context: null,
/**
* Internal method that resets the debug output values.