Collision b/t hitbox & Pixelmask [SOLVED]


(Xavier Johnson) #1

I’m getting started with my first FlashPunk project, and I’m getting my feet wet with the various collision detection features it supports. So far everything has been working how I expected it to, except for collision between hitboxes and Pixelmasks.

With every other type of collision (hitbox vs hitbox, Pixelmask vs Pixelmask), two Entities are “colliding” when any amount of their hit regions overlap, which is normal. However, I can’t get collision to work the same way when only one of the Entities uses a Pixelmask.

The image below shows an example of the problem I’m running into. The small rectangle is the hitbox of the Entity that doesn’t have a Pixelmask. That hitbox is clearly heavily overlapping the Pixelmask of the other Entity (the big grey box), but FP doesn’t think they’re colliding.

However, they are considered to be colliding in the image below, when the Pixelmask is a bit higher:

I clearly have the wrong idea of how hitbox/mask collision works. Do they only collide once the entirety of a hitbox is inside the mask or something? I tried figuring it out myself but I can’t quite decipher what’s going on.


(Xavier Johnson) #2

Okay, I figured it out–things weren’t colliding because I centered the origin of the Pixelmask hitbox, which fudged things up.

The reason that causes a problem is because changing originX / originY of an Entity doesn’t update the _x / _y of a child hitbox, ruining the accuracy of the Pixelmask’s collision functions (which doesn’t look at the originX/Y of the parent Entity).

I made a quick fix for this by creating setters for originX/Y in Entity that make the appropriate updates to the child mask. I’m posting it here in case anyone runs into a similar problem in the future.

private var _originX:int;
/**
 * X origin of the Entity's hitbox.
 */
public function get originX():int
{
    return _originX;
}
public function set originX(value:int):void
{
    var hitbox:Pixelmask = _mask as Pixelmask;
    if (hitbox && hitbox.x != -value) hitbox.x = -value;
    else _originX = value;
}

//Similar version of this for originY

(Jacob Albano) #3

Why not set the origin of the pixelmask then? I feel like this might cause you some trouble in the future.


(Xavier Johnson) #4

Yes, setting the origin of the Pixelmask itself also works, but what I didn’t like was how setting a Hitbox/Pixelmask coordinate changes its parent Entity’s originX/Y to match it, but not the other way around.

I used the above patch to make sure Hitbox coordinates always match the parent’s originX/Y, rather than only when something triggers a hitbox’s update() (like setting its x/y).