I’m trying to use a drawMask to mask off my oddly shaped healthbar. But when I move the healthbar image down, the mask moves with it. I’ve tried many solutions, and nothing seems to work. Chevy told me on twitter that the mask should have its own x,y and that I only need to move the image.x, but I’ve done this and it moves the mask with it. I am out of ideas, and would greatly appreciate if anyone knows of a solution. Thanks!
How to keep drawMask from moving with image?
DrawMasks don’t have their own x/y - collision masks do. This must be where he is getting confused. To move the DrawMask, you’d have to modify the actual BitmapData of the DrawMask:
var targetX: Number = 0;
var targetY: Number = 0;
var buf: BitmapData = new BitmapData(drawMaskBmpData.rect.width, drawMaskBmpData.rect.height, true, 0);
//buf.fillRect(buf.rect, 0); //you'll need this if you reuse the bitmap data
buf.copyPixels(drawMaskBmpData, drawMaskBmpData.rect, new Point(targetX, targetY));
myImage.drawMask = buf;
Update targetX and targetY to draw the mask to a different x/y position relative to the Image.
This can be optimised by not allocating a new BitmapData and Point each time - store them as class members and only create the instances once - if you do this, you’ll need the ‘buf.fillRect’ line in there to clear the buffer between frames.
I got it working, but I’m having a big lag issue. It seems to move the mask back up the frame after it moves the image down. Here is my results: https://dl.dropboxusercontent.com/u/1906363/Game%20Design%20Stuf/Super%20Pisser/old%20versions/SuperPisser.swf
Space to move the image down 5 pixels. Up and Down arrow keys to move it up and down 1 pixel.
And here is my code:
package {
import net.flashpunk.Entity;
import flash.geom.Point;
import net.flashpunk.graphics.Spritemap;
import flash.display.BitmapData;
import net.flashpunk.graphics.Image;
import net.flashpunk.utils.Input;
import net.flashpunk.utils.Key;
import net.flashpunk.FP;
/**
* ...
* @author Skelyton
*/
public class Bladder extends Entity
{
[Embed(source = '../assets/graphics/bladderFill.png')] private const BLADDERFILL_GRAPHIC:Class;
[Embed(source = '../assets/graphics/bladderMask.png')] private const BLADDERMASK_GRAPHIC:Class;
protected var bladderFillImg:Spritemap;
public var bladderEmptyLevel:Number = 0;
private var targetX:Number;
private var targetY:Number;
private var buffer:BitmapData;
private var fillBitmap:BitmapData;
public function Bladder()
{
bladderFillImg = new Spritemap(BLADDERFILL_GRAPHIC, 92, 108);
graphic = bladderFillImg;
bladderFillImg.add("bubble", [0, 1, 2], 8, true);
bladderFillImg.play("bubble");
this.x = FP.screen.width - 112;
this.y = 10;// + (1 - (bladderEmptyLevel / 100)) * 92;
targetX = 0;
targetY = 0;
fillBitmap = new BLADDERMASK_GRAPHIC().bitmapData;
buffer = new BitmapData(fillBitmap.rect.width, fillBitmap.rect.height, true, 0);
buffer.copyPixels(fillBitmap, fillBitmap.rect, new Point(targetX, targetY));
bladderFillImg.drawMask = buffer;
}
override public function update():void
{
if (bladderEmptyLevel >= 100)
{
return;
}
if (Input.pressed(Key.SPACE))
{
bladderEmptyLevel += 5;
bladderFillImg.y += 5;
targetY -= 5;
buffer.fillRect(buffer.rect, 0);
buffer.copyPixels(fillBitmap, fillBitmap.rect, new Point(targetX, targetY));
}
if (Input.pressed(Key.DOWN))
{
bladderEmptyLevel += 1;
bladderFillImg.y += 1;
targetY -= 1;
buffer.fillRect(buffer.rect, 0);
buffer.copyPixels(fillBitmap, fillBitmap.rect, new Point(targetX, targetY));
}
if (Input.pressed(Key.UP))
{
bladderEmptyLevel -= 1;
bladderFillImg.y -= 1;
targetY += 1;
buffer.fillRect(buffer.rect, 0);
buffer.copyPixels(fillBitmap, fillBitmap.rect, new Point(targetX, targetY));
}
//bladderFillImg.y = 10 + (1 - (bladderEmptyLevel / 100)) * 92;
}
}
Try adding
super.update()
to the end of your update()
function.
I think this is the problem. Even if it’s not, you should have it in there anyway!
You could try overriding render() and adding the bladder update code into your overridden render function.
When you override any function, remember you must always call super.functionName somewhere (usually the end or beginning of the override function). So when you override render, remember to call super.render() and as Jonathan says, call super.update() at the end of your current update function.
How about purposely delaying the update of the object’s position by a frame. That way, although there is a 1-frame delay before the drawMask takes effect, the position move will be 1 frame delayed also so they will update at the same time (albeit 1 frame late). The player would have to be superhuman to notice the overall delay of 1 frame (in fact, many games use ‘input buffering’ where all of the input is 1-frame delayed and most people don’t notice).