Skip to content

Commit 4304811

Browse files
committed
Added new Pixel Perfect input handler and makePixelPerfect method.
1 parent a49e770 commit 4304811

3 files changed

Lines changed: 84 additions & 0 deletions

File tree

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ TODO - Out of Canvas events
2828
* Setting `enabled` to false on either the TouchManager, MouseManager or KeyboardManager will prevent it from handling any native DOM events until you set it back again.
2929
* InputPlugin has the following new read-only properties: `mousePointer`, `pointer1`, `pointer2`, `pointer3`, `pointer4`, `pointer5`, `pointer6`, `pointer7`, `pointer8`, `pointer9` and `pointer10`. Most of these will be undefined unless you call `addPointer` first, or set the active pointers quantity in your Game Config.
3030
* InputManager has a new method `transformPointer` which will set the transformed x and y properties of a Pointer in one call, rather than the 2 calls it took before. This is now used by all Pointer event handlers.
31+
* InputPlugin has a new method `makePixelPerfect` which allows you to specify a texture-based Game Object as being pixel perfect when performing all input checks against it. You use it like this: `this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect())` - you can also pass in an optional alpha tolerance level. See the method docs for full details and the new examples to see it in action. Note that as a pointer interacts with the Game Object it will constantly poll the texture, extracting a single pixel from the given coordinates and checking its color values. This is an expensive process, so should only be enabled on Game Objects that really need it.
3132

3233
### Input - Keyboard Manager Updates
3334

@@ -102,6 +103,7 @@ TODO - Out of Canvas events
102103
* Camera has a new method `setVisible` which toggles its visible property.
103104
* `CameraManager.fromJSON` will now set the visible property is defined in the config.
104105
* `ScenePlugin.run` is a new method that will run the given Scene and not change the state of the current Scene at all. If the scene is asleep, it will be woken. If it's paused, it will be resumed. If not running at all, it will be started.
106+
* `TextureManager.getPixelAlpha` is a new method that will return the alpha value of a pixel from the given texture and frame. It will return `null` if the coordinates were out of bounds, otherwise a value between 0 and 255.
105107

106108
### Updates
107109

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/**
2+
* @author Richard Davey <rich@photonstorm.com>
3+
* @copyright 2018 Photon Storm Ltd.
4+
* @license {@link https://github.com/photonstorm/phaser/blob/master/license.txt|MIT License}
5+
*/
6+
7+
/**
8+
* Creates a new Interactive Object.
9+
*
10+
* This is called automatically by the Input Manager when you enable a Game Object for input.
11+
*
12+
* The resulting Interactive Object is mapped to the Game Object's `input` property.
13+
*
14+
* @function Phaser.Input.CreatePixelPerfectHandler
15+
* @since 3.10.0
16+
*
17+
* @param {Phaser.GameObjects.GameObject} gameObject - The Game Object to which this Interactive Object is bound.
18+
* @param {any} hitArea - The hit area for this Interactive Object. Typically a geometry shape, like a Rectangle or Circle.
19+
* @param {HitAreaCallback} hitAreaCallback - The 'contains' check callback that the hit area shape will use for all hit tests.
20+
*
21+
* @return {Phaser.Input.InteractiveObject} The new Interactive Object.
22+
*/
23+
var CreatePixelPerfectHandler = function (textureManager, alphaTolerance)
24+
{
25+
return function (hitArea, x, y, gameObject)
26+
{
27+
var alpha = textureManager.getPixelAlpha(x, y, gameObject.texture.key, gameObject.frame.key);
28+
29+
return (alpha && alpha >= alphaTolerance)
30+
};
31+
};
32+
33+
module.exports = CreatePixelPerfectHandler;

src/input/InputPlugin.js

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ var Circle = require('../geom/circle/Circle');
88
var CircleContains = require('../geom/circle/Contains');
99
var Class = require('../utils/Class');
1010
var CreateInteractiveObject = require('./CreateInteractiveObject');
11+
var CreatePixelPerfectHandler = require('./CreatePixelPerfectHandler');
1112
var DistanceBetween = require('../math/distance/DistanceBetween');
1213
var Ellipse = require('../geom/ellipse/Ellipse');
1314
var EllipseContains = require('../geom/ellipse/Contains');
@@ -1297,6 +1298,48 @@ var InputPlugin = new Class({
12971298
return this;
12981299
},
12991300

1301+
/**
1302+
* Creates a function that can be passed to `setInteractive`, `enable` or `setHitArea` that will handle
1303+
* pixel-perfect input detection on an Image or Sprite based Game Object, or any custom class that extends them.
1304+
*
1305+
* The following will create a sprite that is clickable on any pixel that has an alpha value >= 1.
1306+
*
1307+
* ```javascript
1308+
* this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect());
1309+
* ```
1310+
*
1311+
* The following will create a sprite that is clickable on any pixel that has an alpha value >= 150.
1312+
*
1313+
* ```javascript
1314+
* this.add.sprite(x, y, key).setInteractive(this.input.makePixelPerfect(150));
1315+
* ```
1316+
*
1317+
* Once you have made an Interactive Object pixel perfect it impacts all input related events for it: down, up,
1318+
* dragstart, drag, etc.
1319+
*
1320+
* As a pointer interacts with the Game Object it will constantly poll the texture, extracting a single pixel from
1321+
* the given coordinates and checking its color values. This is an expensive process, so should only be enabled on
1322+
* Game Objects that really need it.
1323+
*
1324+
* You cannot make non-texture based Game Objects pixel perfect. So this will not work on Graphics, BitmapText,
1325+
* Render Textures, Text, Tilemaps, Containers or Particles.
1326+
*
1327+
* @method Phaser.Input.InputPlugin#makePixelPerfect
1328+
* @since 3.10.0
1329+
*
1330+
* @param {integer} [alphaTolerance=1] - The alpha level that the pixel should be above to be included as a successful interaction.
1331+
*
1332+
* @return {function} A Pixel Perfect Handler for use as a hitArea shape callback.
1333+
*/
1334+
makePixelPerfect: function (alphaTolerance)
1335+
{
1336+
if (alphaTolerance === undefined) { alphaTolerance = 1; }
1337+
1338+
var textureManager = this.systems.textures;
1339+
1340+
return CreatePixelPerfectHandler(textureManager, alphaTolerance);
1341+
},
1342+
13001343
/**
13011344
* Sets the hit area for the given array of Game Objects.
13021345
*
@@ -1331,6 +1374,12 @@ var InputPlugin = new Class({
13311374
gameObjects = [ gameObjects ];
13321375
}
13331376

1377+
if (typeof shape === 'function' && !callback)
1378+
{
1379+
callback = shape;
1380+
shape = {};
1381+
}
1382+
13341383
for (var i = 0; i < gameObjects.length; i++)
13351384
{
13361385
var gameObject = gameObjects[i];

0 commit comments

Comments
 (0)