mirror of
https://github.com/wassname/phaser.git
synced 2026-06-27 16:10:15 +08:00
You can now use the hitArea property on Sprites and Image objects. hitArea can be a geometry object (Rectangle, Circle, Polygon, Ellipse) and is used in pointerOver checks.
This commit is contained in:
@@ -75,6 +75,8 @@ Significant API changes:
|
||||
New features:
|
||||
|
||||
* Phaser.Image is a brand new display object perfect for logos, backgrounds, etc. You can scale, rotate, tint and blend and Image, but it has no animation, physics body or input events.
|
||||
* You can now use the hitArea property on Sprites and Image objects. hitArea can be a geometry object (Rectangle, Circle, Polygon, Ellipse) and is used in pointerOver checks.
|
||||
|
||||
|
||||
New Examples:
|
||||
|
||||
@@ -85,6 +87,7 @@ Updates:
|
||||
* Phaser.AnimationParser now sets the trimmed data directly for Pixi Texture frames. Tested across JSON Hash, JSON Data, Sprite Sheet and XML.
|
||||
* Game.add.renderTexture now has the addToCache parameter. If set the texture will be stored in Game.Cache and can be retrieved with Cache.getTexture(key).
|
||||
* Game.add.bitmapData now has the addToCache parameter. If set the texture will be stored in Game.Cache and can be retrieved with Cache.getBitmapData(key).
|
||||
* The InputManager now sets the canvas style cursor to 'inherit' instead of 'default'.
|
||||
|
||||
|
||||
Bug Fixes:
|
||||
|
||||
@@ -0,0 +1,86 @@
|
||||
|
||||
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
|
||||
|
||||
function preload() {
|
||||
|
||||
game.load.image('block', 'assets/sprites/block.png');
|
||||
|
||||
}
|
||||
|
||||
var grid = [];
|
||||
var currentTile = new Phaser.Point();
|
||||
|
||||
function create() {
|
||||
|
||||
// The block.png is 95x95, so for this we'll create a little grid or it won't fit:
|
||||
|
||||
for (var y = 0; y < 5; y++)
|
||||
{
|
||||
grid[y] = [];
|
||||
|
||||
for (var x = 0; x < 5; x++)
|
||||
{
|
||||
// grid[y][x] = game.add.sprite(x * 95, y * 95, 'block');
|
||||
// coz the grid is empty like
|
||||
grid[y][x] = null;
|
||||
}
|
||||
}
|
||||
|
||||
var block1 = game.add.sprite(600, 100, 'block');
|
||||
block1.name = 'block1';
|
||||
block1.inputEnabled = true;
|
||||
block1.input.enableDrag(true);
|
||||
block1.events.onDragStop.add(dropBlock, this);
|
||||
|
||||
var block2 = game.add.sprite(600, 300, 'block');
|
||||
block2.name = 'block2';
|
||||
block2.inputEnabled = true;
|
||||
block2.input.enableDrag(true);
|
||||
block2.events.onDragStop.add(dropBlock, this);
|
||||
|
||||
}
|
||||
|
||||
function dropBlock(sprite, pointer) {
|
||||
|
||||
// Convert the pointer into a grid location
|
||||
var x = this.game.math.snapToFloor(pointer.x, 95) / 95;
|
||||
var y = this.game.math.snapToFloor(pointer.y, 95) / 95;
|
||||
|
||||
// Bounds check it
|
||||
if (x >= 0 && x <= 4 && y >= 0 && y <= 4)
|
||||
{
|
||||
// something in there already?
|
||||
if (grid[y][x] !== null)
|
||||
{
|
||||
// This is very hacky - what you SHOULD do is have a Pipe object which has properties startX and startY or something, and snap back to those.
|
||||
if (sprite.name === 'block1')
|
||||
{
|
||||
game.add.tween(sprite).to( { x: 600, y: 100 }, 1000, Phaser.Easing.Linear.None, true);
|
||||
}
|
||||
else
|
||||
{
|
||||
game.add.tween(sprite).to( { x: 600, y: 300 }, 1000, Phaser.Easing.Linear.None, true);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
grid[y][x] = sprite;
|
||||
sprite.inputEnabled = false;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
// 95 = width and height of the block.png
|
||||
currentTile.x = this.game.math.snapToFloor(game.input.x, 95) / 95;
|
||||
currentTile.y = this.game.math.snapToFloor(game.input.y, 95) / 95;
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
game.debug.renderText('Tile X: ' + currentTile.x + ' Y: ' + currentTile.y, 32, 32);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
|
||||
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
|
||||
|
||||
function preload() {
|
||||
|
||||
game.load.image('block', 'assets/sprites/block.png');
|
||||
|
||||
}
|
||||
|
||||
var grid = [];
|
||||
var currentTile = new Phaser.Point();
|
||||
|
||||
function create() {
|
||||
|
||||
// The block.png is 95x95, so for this we'll create a little grid or it won't fit:
|
||||
|
||||
for (var y = 0; y < 5; y++)
|
||||
{
|
||||
grid[y] = [];
|
||||
|
||||
for (var x = 0; x < 5; x++)
|
||||
{
|
||||
grid[y][x] = game.add.sprite(x * 95, y * 95, 'block');
|
||||
}
|
||||
}
|
||||
|
||||
game.input.onDown.add(clickedBlock, this);
|
||||
|
||||
}
|
||||
|
||||
function clickedBlock() {
|
||||
|
||||
// Bounds check
|
||||
if (currentTile.x >= 0 && currentTile.x <= 4 && currentTile.y >= 0 && currentTile.y <= 4)
|
||||
{
|
||||
block = grid[currentTile.y][currentTile.x];
|
||||
block.alpha = 0.5;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
// 95 = width and height of the block.png
|
||||
currentTile.x = this.game.math.snapToFloor(game.input.x, 95) / 95;
|
||||
currentTile.y = this.game.math.snapToFloor(game.input.y, 95) / 95;
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
game.debug.renderText('Tile X: ' + currentTile.x + ' Y: ' + currentTile.y, 32, 32);
|
||||
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
|
||||
var game = new Phaser.Game(800, 600, Phaser.CANVAS, 'phaser-example', { preload: preload, create: create, update: update, render: render });
|
||||
|
||||
function preload() {
|
||||
|
||||
game.load.image('mushroom', 'assets/sprites/mushroom2.png');
|
||||
game.load.image('ball', 'assets/sprites/wizball.png');
|
||||
|
||||
}
|
||||
|
||||
var image;
|
||||
var image2;
|
||||
|
||||
var down;
|
||||
var p;
|
||||
var c;
|
||||
|
||||
function create() {
|
||||
|
||||
image = game.add.image(200, 200, 'mushroom');
|
||||
|
||||
image2 = game.add.image(400, 200, 'ball');
|
||||
|
||||
// image.rotation = 0.8;
|
||||
|
||||
image.inputEnabled = true;
|
||||
|
||||
image.events.onInputDown.add(clicked, this);
|
||||
image.events.onInputOver.add(over, this);
|
||||
image.events.onInputOut.add(out, this);
|
||||
|
||||
|
||||
|
||||
image2.hitArea = new Phaser.Circle(image2.width / 2, image2.height / 2, 90);
|
||||
image2.inputEnabled = true;
|
||||
|
||||
image2.events.onInputDown.add(clicked, this);
|
||||
image2.events.onInputOver.add(over, this);
|
||||
image2.events.onInputOut.add(out, this);
|
||||
|
||||
|
||||
// game.input.mouse.mouseDownCallback = onMouseDown;
|
||||
// game.input.mouse.mouseUpCallback = onMouseUp;
|
||||
// game.input.mouse.mouseMoveCallback = onMouseMove;
|
||||
|
||||
}
|
||||
|
||||
function over(object, pointer) {
|
||||
|
||||
object.alpha = 0.5;
|
||||
|
||||
}
|
||||
|
||||
function out(object, pointer) {
|
||||
|
||||
object.alpha = 1;
|
||||
|
||||
}
|
||||
|
||||
function clicked(object, pointer) {
|
||||
|
||||
console.log('boom');
|
||||
|
||||
}
|
||||
|
||||
function update() {
|
||||
|
||||
|
||||
}
|
||||
|
||||
function render() {
|
||||
|
||||
// var p = game.input.getLocalPosition(image);
|
||||
var p = game.input.getLocalPosition(image2);
|
||||
|
||||
|
||||
game.debug.renderPointInfo(p, 32, 32);
|
||||
game.debug.renderPoint(p);
|
||||
game.debug.renderCircle(image2.hitArea);
|
||||
|
||||
}
|
||||
+1
-2
@@ -457,6 +457,7 @@ Phaser.Game.prototype = {
|
||||
this.world.boot();
|
||||
this.input.boot();
|
||||
this.sound.boot();
|
||||
this.state.boot();
|
||||
|
||||
this.load.onLoadComplete.add(this.loadComplete, this);
|
||||
|
||||
@@ -467,8 +468,6 @@ Phaser.Game.prototype = {
|
||||
|
||||
this.raf = new Phaser.RequestAnimationFrame(this);
|
||||
this.raf.start();
|
||||
|
||||
this.state.boot();
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
@@ -70,6 +70,8 @@ Phaser.World.prototype.boot = function () {
|
||||
*/
|
||||
Phaser.World.prototype.preUpdate = function () {
|
||||
|
||||
this.currentRenderOrderID = 0;
|
||||
|
||||
for (var i = 0, len = this.children.length; i < len; i++)
|
||||
{
|
||||
if (this.children[i]['preUpdate'])
|
||||
|
||||
@@ -40,7 +40,8 @@ Phaser.GameObjectFactory.prototype = {
|
||||
},
|
||||
|
||||
/**
|
||||
* Create a new Image at the given coordinates, using the cache key and frame if set.
|
||||
* Create a new `Image` object. An Image is a light-weight object you can use to display anything that doesn't need physics or animation.
|
||||
* It can still rotate, scale, crop and receive input events. This makes it perfect for logos, backgrounds, simple buttons and other non-Sprite graphics.
|
||||
*
|
||||
* @method Phaser.GameObjectFactory#image
|
||||
* @param {number} x - X position of the image.
|
||||
|
||||
@@ -7,8 +7,8 @@
|
||||
/**
|
||||
* @class Phaser.Image
|
||||
*
|
||||
* @classdesc Create a new `Image` object. An Image is a light-weight object you can use to display anything that doesn't need physics, animation or input events.
|
||||
* It can still rotate, scale and crop. This makes it perfect for logos, backgrounds and other non-Sprite graphics.
|
||||
* @classdesc Create a new `Image` object. An Image is a light-weight object you can use to display anything that doesn't need physics or animation.
|
||||
* It can still rotate, scale, crop and receive input events. This makes it perfect for logos, backgrounds, simple buttons and other non-Sprite graphics.
|
||||
*
|
||||
* @constructor
|
||||
* @param {Phaser.Game} game - A reference to the currently running game.
|
||||
@@ -90,10 +90,15 @@ Phaser.Image = function (game, x, y, key, frame) {
|
||||
this.fixedToCamera = false;
|
||||
|
||||
/**
|
||||
* @property {array} _cache - A small cache for previous step values.
|
||||
* @property {Phaser.InputHandler|null} input - The Input Handler for this object. Needs to be enabled with image.inputEnabled = true before you can use it.
|
||||
*/
|
||||
this.input = null;
|
||||
|
||||
/**
|
||||
* @property {array} _cache - A small cache for previous step values. 0 = x, 1 = y, 2 = rotation, 3 = renderID
|
||||
* @private
|
||||
*/
|
||||
this._cache = [0, 0, 0];
|
||||
this._cache = [0, 0, 0, 0];
|
||||
|
||||
};
|
||||
|
||||
@@ -125,6 +130,11 @@ Phaser.Image.prototype.preUpdate = function() {
|
||||
|
||||
this.world.setTo(this.game.camera.x + this.worldTransform[2], this.game.camera.y + this.worldTransform[5]);
|
||||
|
||||
if (this.visible)
|
||||
{
|
||||
this._cache[3] = this.game.world.currentRenderOrderID++;
|
||||
}
|
||||
|
||||
return true;
|
||||
|
||||
};
|
||||
@@ -339,6 +349,11 @@ Phaser.Image.prototype.destroy = function() {
|
||||
this.events.destroy();
|
||||
}
|
||||
|
||||
if (this.input)
|
||||
{
|
||||
this.input.destroy();
|
||||
}
|
||||
|
||||
this.alive = false;
|
||||
this.exists = false;
|
||||
this.visible = false;
|
||||
@@ -566,3 +581,53 @@ Object.defineProperty(Phaser.Image.prototype, "frameName", {
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* @name Phaser.Image#renderOrderID
|
||||
* @property {number} renderOrderID - The render order ID, reset every frame.
|
||||
* @readonly
|
||||
*/
|
||||
Object.defineProperty(Phaser.Image.prototype, "renderOrderID", {
|
||||
|
||||
get: function() {
|
||||
|
||||
return this._cache[3];
|
||||
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
/**
|
||||
* By default an Image won't process any input events at all. By setting inputEnabled to true the Phaser.InputHandler is
|
||||
* activated for this object and it will then start to process click/touch events and more.
|
||||
*
|
||||
* @name Phaser.Image#inputEnabled
|
||||
* @property {boolean} inputEnabled - Set to true to allow this object to receive input events.
|
||||
*/
|
||||
Object.defineProperty(Phaser.Image.prototype, "inputEnabled", {
|
||||
|
||||
get: function () {
|
||||
|
||||
return (this.input && this.input.enabled);
|
||||
|
||||
},
|
||||
|
||||
set: function (value) {
|
||||
|
||||
if (value)
|
||||
{
|
||||
if (this.input === null)
|
||||
{
|
||||
this.input = new Phaser.InputHandler(this);
|
||||
this.input.start();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (this.input && this.input.enabled)
|
||||
{
|
||||
this.input.stop();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
+5
-8
@@ -384,21 +384,18 @@ Object.defineProperty(Phaser.Circle.prototype, "empty", {
|
||||
*/
|
||||
Phaser.Circle.contains = function (a, x, y) {
|
||||
|
||||
if (a.radius <= 0)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Check if x/y are within the bounds first
|
||||
if (x >= a.left && x <= a.right && y >= a.top && y <= a.bottom)
|
||||
if (a.radius > 0 && x >= a.left && x <= a.right && y >= a.top && y <= a.bottom)
|
||||
{
|
||||
var dx = (a.x - x) * (a.x - x);
|
||||
var dy = (a.y - y) * (a.y - y);
|
||||
|
||||
return (dx + dy) <= (a.radius * a.radius);
|
||||
}
|
||||
|
||||
return false;
|
||||
else
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
|
||||
+102
-1
@@ -530,7 +530,7 @@ Phaser.Input.prototype = {
|
||||
|
||||
if (this.game.canvas.style.cursor !== 'none')
|
||||
{
|
||||
this.game.canvas.style.cursor = 'default';
|
||||
this.game.canvas.style.cursor = 'inherit';
|
||||
}
|
||||
|
||||
if (hard === true)
|
||||
@@ -724,6 +724,107 @@ Phaser.Input.prototype = {
|
||||
|
||||
return null;
|
||||
|
||||
},
|
||||
|
||||
/**
|
||||
* This will return the local coordinates of the specified displayObject for this InteractionData
|
||||
*
|
||||
* @method getLocalPosition
|
||||
* @param displayObject {DisplayObject} The DisplayObject that you would like the local coords off
|
||||
* @return {Point} A point containing the coordinates of the InteractionData position relative to the DisplayObject
|
||||
*/
|
||||
getLocalPosition: function (displayObject) {
|
||||
|
||||
var worldTransform = displayObject.worldTransform;
|
||||
var global = new Phaser.Point(this.x, this.y);
|
||||
|
||||
// do a cheeky transform to get the mouse coords;
|
||||
var a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx,
|
||||
a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty,
|
||||
id = 1 / (a00 * a11 + a01 * -a10);
|
||||
// set the mouse coords...
|
||||
return new Phaser.Point(a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
|
||||
a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id);
|
||||
},
|
||||
|
||||
/**
|
||||
* Tests if the current mouse coordinates hit a sprite
|
||||
*
|
||||
* @method hitTest
|
||||
* @param item {DisplayObject} The displayObject to test for a hit
|
||||
* @param interactionData {InteractionData} The interactionData object to update in the case there is a hit
|
||||
* @private
|
||||
*/
|
||||
// hitTest: function (item, interactionData) {
|
||||
hitTest: function (item, pointer) {
|
||||
|
||||
// var global = interactionData.global;
|
||||
var global = new Phaser.Point(pointer.x, pointer.y);
|
||||
|
||||
if( !item.worldVisible )return false;
|
||||
|
||||
// temp fix for if the element is in a non visible
|
||||
|
||||
var isSprite = (item instanceof PIXI.Sprite),
|
||||
worldTransform = item.worldTransform,
|
||||
a00 = worldTransform.a, a01 = worldTransform.b, a02 = worldTransform.tx,
|
||||
a10 = worldTransform.c, a11 = worldTransform.d, a12 = worldTransform.ty,
|
||||
id = 1 / (a00 * a11 + a01 * -a10),
|
||||
x = a11 * id * global.x + -a01 * id * global.y + (a12 * a01 - a02 * a11) * id,
|
||||
y = a00 * id * global.y + -a10 * id * global.x + (-a12 * a00 + a02 * a10) * id;
|
||||
|
||||
// interactionData.target = item;
|
||||
|
||||
//a sprite or display object with a hit area defined
|
||||
if(item.hitArea && item.hitArea.contains) {
|
||||
if(item.hitArea.contains(x, y)) {
|
||||
console.log('AREA HIT!', x, y);
|
||||
//if(isSprite)
|
||||
// interactionData.target = item;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
// a sprite with no hitarea defined
|
||||
else if(isSprite)
|
||||
{
|
||||
var width = item.texture.frame.width,
|
||||
height = item.texture.frame.height,
|
||||
x1 = -width * item.anchor.x,
|
||||
y1;
|
||||
|
||||
if(x > x1 && x < x1 + width)
|
||||
{
|
||||
y1 = -height * item.anchor.y;
|
||||
|
||||
if(y > y1 && y < y1 + height)
|
||||
{
|
||||
// set the target property if a hit is true!
|
||||
// interactionData.target = item;
|
||||
console.log('HIT!', x, y, x1, y1);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
var length = item.children.length;
|
||||
|
||||
for (var i = 0; i < length; i++)
|
||||
{
|
||||
var tempItem = item.children[i];
|
||||
// var hit = this.hitTest(tempItem, interactionData);
|
||||
var hit = this.hitTest(tempItem);
|
||||
if(hit)
|
||||
{
|
||||
// hmm.. TODO SET CORRECT TARGET?
|
||||
// interactionData.target = item;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
};
|
||||
|
||||
@@ -215,7 +215,7 @@ Phaser.InputHandler.prototype = {
|
||||
this.enabled = true;
|
||||
|
||||
// Create the signals the Input component will emit
|
||||
if (this.sprite.events && this.sprite.events.onInputOver == null)
|
||||
if (this.sprite.events && this.sprite.events.onInputOver === null)
|
||||
{
|
||||
this.sprite.events.onInputOver = new Phaser.Signal();
|
||||
this.sprite.events.onInputOut = new Phaser.Signal();
|
||||
@@ -492,11 +492,18 @@ Phaser.InputHandler.prototype = {
|
||||
*/
|
||||
checkPointerOver: function (pointer) {
|
||||
|
||||
if (this.enabled === false || this.sprite.visible === false || (this.sprite.group && this.sprite.group.visible === false))
|
||||
if (this.enabled === false || this.sprite.visible === false || this.sprite.parent.visible === false)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
// Need to pass it a temp point, in case we need it again for the pixel check
|
||||
if (this.game.input.hitTest(this.sprite, pointer))
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
/*
|
||||
this.sprite.getLocalUnmodifiedPosition(this._tempPoint, pointer.x, pointer.y);
|
||||
|
||||
if (this._tempPoint.x >= 0 && this._tempPoint.x <= this.sprite.currentFrame.width && this._tempPoint.y >= 0 && this._tempPoint.y <= this.sprite.currentFrame.height)
|
||||
@@ -510,6 +517,9 @@ Phaser.InputHandler.prototype = {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
return false;
|
||||
|
||||
},
|
||||
|
||||
|
||||
Reference in New Issue
Block a user