I’m trying to use collision with Spritemap using a sprite sheet, the Spritemap is about a small object that gets bigger and a player who hits it, but when i calculate the mask of the Spritemap it’s set to the first image of the sprite sheet so my player goes through all the Spritemap, i wounder if there is a way to calculate the mask for every image in the Spritemap so collisions will be launched once the player touches any of image sequence ?
Collision With A Spritemap
If your sprites can be used as pixelmask you can simply do this:
In the constructor:
var spritemap:Spritemap = new Spritemap(IMG, 20, 20);
//the animations
graphic = spritemap;
var maskSource:BitmapData = new BitmapData(20, 20, true, 0); //20, 20 are the sizes of your sprite
var pixelmask:Pixelmask = new Pixelmask(maskSource);
//copy-paste the animation list and change the variable name
mask = pixelmask;
In the render function:
override public function render():void
{
maskSource.fillRect(maskSource.rect, 0);
spritemap.render(maskSource, new Point, new Point);
super.render();
}
This works if, and only if, your sprites can be interpretated as a pixelmask.
Sorry but i don’t understand where to place my sprite sheet Class, the embedded code for my PNG file ?
Sorry, i writed it wrong. Already edited.
The idea is to take the same image and convert it to the mask.
PD: Just to be sure, this goes in the class that extends Entity (usually Player, Enemy, etc.)
Thank You so much, that worked great, except for one thing, i replaced Bitmap with BitmapData ;), but just one more thing my mask sometimes doesn’t fit exactly the image :
Which launches the collision before even touching the object, is there a way to fix that ?
… I guess it’s just a problem of the sprite sheet images :D, can you please explain the code, that would be a great
Edited (WTF did i do with Bitmap?) >.<
Don’t compress the image becouse the noice created will effect the collision.
How does it work?
Ok so at this point i assume you know how OOP, AS3 and FP works (the last one in a more practical way).
So what i do is make the Pixelmask be the BitmapData that i create. Becouse it is not cloned and i save an instance, i can modify the Pixelmask source directly.
How do i modify it? Well i simply fill the source with a non-colliding color (AKA 0) and render the image directly there (does not consume many resources).
So in the end we have a pixelmask wich have the same image than the rendered one.
Code explained line by line
//As you should think we need the Spritemap
var spritemap:Spritemap = new Spritemap(IMG, 20, 20);
//the animations
graphic = spritemap;
var maskSource:BitmapData = new BitmapData(20, 20, true, 0);
//We create the BitmapData that is used to chack the collisions
var pixelmask:Pixelmask = new Pixelmask(maskSource);
//We create the pixelmask wich uses the bitmapData we just created to check collisions
mask = pixelmask;
//we set the mask to be our pixel mask (pretty obvious)
override public function render():void
{
maskSource.fillRect(maskSource.rect, 0);
//Errase the bitmapdata by filling with 0 (transparent black)
spritemap.render(maskSource, new Point, new Point);
//Renders the spritemap into our bitmapdata in the position 0, 0 (the pixelmask will already be relative to the Entity)
super.render();
//render the graphic (in this case the Spritemap)
}
Animated pixelmask has a huge hitbox?
Hey guys I have been following along and trying to incorporate this into my code, but it is just making a square hitbox rather than a pixel perfect collision of the object. Have I put some of the code in wrong spots or anything?
package entities {
/**
* ...
*
*/
import net.flashpunk.*;
import net.flashpunk.graphics.Spritemap;
import entities.Player;
import flash.display.*;
import net.flashpunk.masks.*;
import flash.geom.*;
public class Projectile extends Entity
{
private var spriteMP:Spritemap;
private var initX:Number;
private var initY:Number;
private var maxDistance:Number;
private var faceRight:Boolean;
private var eddy:Player;
private var maskSource:BitmapData;
public function Projectile(x:Number, y:Number, width:int, height:int, maxDistance:Number, assetSprite:*,
spriteID:int, collideType:String, faceRight:Boolean)
{
initX = x;
initY = y;
this.x = x;
this.y = y;
this.width = width;
this.height = height;
this.maxDistance = maxDistance;
this.faceRight = faceRight;
this.spriteMP = new Spritemap(Assets[assetSprite], width, height);
spriteMP.add("this", [spriteID], 0, false);
type = collideType;
graphic = spriteMP;
maskSource = new BitmapData(width, height, true, 0);
//We create the BitmapData that is used to chack the collisions
var pixelmask:Pixelmask = new Pixelmask(maskSource);
//We create the pixelmask wich uses the bitmapData we just created to check collisions
this.mask = pixelmask;
//we set the mask to be our pixel mask (pretty obvious)
} // end constructor function
override public function update():void
{
this.eddy = eddy || world.getInstance("eddy") as Player;
shoot();
if (FP.distance(initX, initY, x, y) > maxDistance) destroyThis();
super.update();
} // end update function
private function shoot():void
{
spriteMP.play("this");
if (faceRight)
{
x ++;
}
if (!faceRight)
{
x --;
}
} // end shoot function
private function destroyThis():void
{
FP.world.remove(this);
} // end destroy this function
override public function render():void
{
maskSource.fillRect(maskSource.rect, 0);
//Errase the bitmapdata by filling with 0 (transparent black)
spriteMP.render(maskSource, new Point, new Point);
//Renders the spritemap into our bitmapdata in the position 0, 0 (the pixelmask will already be relative to the Entity)
super.render();
//render the graphic (in this case the Spritemap)
}
} // end class
}
I would gess it’s becouse of the tilemap you are using. Try doing cahnging this line:
override public function render():void
{
maskSource.fillRect(maskSource.rect, 0xFFFFFF);
spriteMP.render(maskSource, new Point, new Point);
super.render();
}
PD: You don’t need to keep the comments. If you understand what’s going on that’s all you need.
I might be thinking this thread is doing something other than what I was trying to get out of it :S
I was thinking this would make a pixel perfect mask, as in a ball would have a circle collision mask rather than a square.
Is that meant to happen? changing to hex white 0xFFFFFF didn’t affect it.
Spritemaps in Masklists
This thread is another thing. You are looking for a class called Pixelmask. You create the mask and simply do:
[Embed]
public static const MASK:Class;
public function MyEntity()
{
mask = new Pixelmask(MASK);
}
For more information have a look at the documentation.
Thank You So Much, i’ve been thinking about how to implement the mask with Spritemaps
The mask is 100% independent to the graphic. This thread is only referyng a dynamic Pixelmask that have the same collision than a Spritemap wich sizes modifies. You can simply use the regular mask types as you do with a Stamp or a Image.