1 decade ago by Heiko
Hey I've uploaded a hitmask plugin to github.
The hitmask is intended for determining hit detection on transparent buttons. The plugin takes the button's image as input, and creates a hitmask (pixel array) with 0's for transparent pixels (hit misses) and 1's for opaque pixels (hits).
You can also set a scaling factor - this will reduce the resulting hitmasks size.
Have a look and let me know if it proves useful to you. Would also appreciate feedback on bugs, and/or ways to improve this plugin.
Get the plugin and documentation here: Impact-ScaledAlphaHitmask-Plugin
Below is an example implementation of a game button using the hitmask plugin (see github repo for more complete example and docs).
* in
* we then set hitmask properties and assign the image to be used to derive hitmask from (the rgba button image)
* then in our hit detection we query the hitmask by passing in relative mouse coordinates. A return value of
The hitmask is intended for determining hit detection on transparent buttons. The plugin takes the button's image as input, and creates a hitmask (pixel array) with 0's for transparent pixels (hit misses) and 1's for opaque pixels (hits).
You can also set a scaling factor - this will reduce the resulting hitmasks size.
Have a look and let me know if it proves useful to you. Would also appreciate feedback on bugs, and/or ways to improve this plugin.
Get the plugin and documentation here: Impact-ScaledAlphaHitmask-Plugin
Below is an example implementation of a game button using the hitmask plugin (see github repo for more complete example and docs).
* in
init() we create an instance of ScaledAlphaHitmask()* we then set hitmask properties and assign the image to be used to derive hitmask from (the rgba button image)
* then in our hit detection we query the hitmask by passing in relative mouse coordinates. A return value of
true indicates a hit, else we got a miss (i.e. mouse event outside of button).
// -------------------------------------------------------------------------------------------------------------
// DemoGamebtn.js
// -------------------------------------------------------------------------------------------------------------
ig.module(
'game.entities.demogamebtn'
)
.requires(
'plugins.scaled-alpha-hitmask',
'plugins.button-state-machine',
'impact.entity'
)
.defines(function() {
EntityDemoGamebtn = ig.Entity.extend({
size: {x: 16, y: 16},
btnStateMachine: null,
hitmask: null,
// -------------------------------------------------------------------------------------------------------------
// Button States
// -------------------------------------------------------------------------------------------------------------
endClick: function() { this.currentAnim = this.anims.btnNormal; },
endClickIgnore: function() { this.currentAnim = this.anims.btnNormal; },
endHover: function() { this.currentAnim = this.anims.btnNormal; },
startClick: function() { this.currentAnim = this.anims.btnDown; },
startHover: function() { this.currentAnim = this.anims.btnHover; },
// -------------------------------------------------------------------------------------------------------------
// Alpha Hit Detection
// -------------------------------------------------------------------------------------------------------------
// hittest - returns true if mouse cursor within bounds, else false
hittest: function() {
if ((ig.input.mouse.x > this.pos.x && ig.input.mouse.x < (this.pos.x + this.size.x)) &&
(ig.input.mouse.y > this.pos.y && ig.input.mouse.y < (this.pos.y + this.size.y)))
{
// if we have hitmask defined then check if we inside or outside of hitmask,
// if no hitmask then we already inside and return true
if (this.hitmask) {
return this.hitmask.hittest(ig.input.mouse.x - this.pos.x, ig.input.mouse.y - this.pos.y, 0 /* we only interested in frame 0 so no need to pass any other*/);
} else {
return true;
}
}
return false; // hittest failed - mouse outside of entity
},
init: function(x, y, settings) {
this.animSheet = new ig.AnimationSheet('media/btns/' + settings.image , settings.width, settings.height);
this.addAnim('btnNormal', 1, [0]);
this.addAnim('btnHover', 2, [1]);
this.addAnim('btnDown', 3, [2]);
this.addAnim('btnDisabled', 4, [3]);
this.currentAnim = this.anims.btnNormal;
this.size.x = settings.width;
this.size.y = settings.height;
// ...
// ...
this.btnStateMachine = new ig.ButtonStateMachine();
this.btnStateMachine.isMouseInside = this.hittest.bind(this);
this.btnStateMachine.isMouseDown = function() { return ig.input.state('click'); };
this.btnStateMachine.startClick = this.startClick.bind(this);
this.btnStateMachine.endClick = this.endClick.bind(this);
this.btnStateMachine.startHover = this.startHover.bind(this);
this.btnStateMachine.endHover = this.endHover.bind(this);
this.btnStateMachine.endClickIgnore = this.endClickIgnore.bind(this);
this.hitmask = new ig.ScaledAlphaHitmask();
this.hitmask.scale = 8;
this.hitmask.verticalFrames = 4; // normal | hover | down | disabled
this.hitmask.drawHitmask = true; // set to 'false' to disable drawing of hitmask over btn image
this.hitmask.setImage(this.animSheet.image);
this.parent(x, y, settings);
},
update: function() {
this.parent();
this.btnStateMachine.updateState();
}
});
});
