My little Space Invaders clone hit a wall:

How am I going to implement those bases?

The bases in the original invaders game had this cute way of incrementally “breaking down” on bullet collisions. In fact, one common strategy was to deliberately shoot a thin hole through them to fire at the aliens while hiding behind your base.

But how was I going to pull that off?

So far I’ve been working only with sprites. I can animate sprites, but I can’t animate my way out of this decomposing thing! Not without a very big spritesheet!

What I need is some kind of owner-draw sprite action!

Enter the BitmapData-backed Sprite

Phaser has this awesome BitmapData abstraction which basically gives you a Canvas to do your own drawing on.

But you don’t want to give up those cool spites and their cool collision detection. Turns out you don’t have to! You can back a Phaser sprite with your own bitmap and draw on it later. Just the ticket!

So I load my base png into a bitmap, then setup the sprite so it’s backed by the bitmap. Later on I can draw destruction “holes” right onto the bitmap, but still use the sprite for collision detection. Epic win!

Here’s how I pull off the bitmap-backed sprite when I create the bases…

for (var x = 1; x <= 4; x++) {
   var baseBmp = game.make.bitmapData(96, 96);
   baseBmp.draw('base', 0, 0, 96, 96); // resize 32 src to 96 target
   baseBmp.update();

   var baseX = x * distanceBetweenBases;

   var base = game.add.sprite(baseX, baseY, baseBmp);
   
   bases.add(base);
   baseBmps.push( {
       bmp: baseBmp,
       worldX: baseX,
       worldY: baseY
   });
}

When I create the bases (which are 32x32), I resize them onto the bitmap as 96x96 so they look nicer in the game. Then I create my base sprite and squirrel away the backing raw bitmaps so I can draw on them later.

I wonder if there’s a smarter way to do that through the sprite api.. but whatever..

Pixel level collisions

Now I have my bitmapped-backed sprites, the next step is to think about bullet collisions. A standard arcade collision isn’t going to cut it, since my bitmap might have holes in it from previous bullets.

I want to end up something like this where bullets pass through the holes, but crash into the white pixels of the base on contact:

Shooting through holes in a sprite

Combining sprite and pixel-level collisions

So let’s go the best of both worlds - I’ll use the sprite collisions in general play to see whether a bullet is on top of my base, then a more expensive pixel-level test when a bullet is sitting over the base.

BitmapData objects support a getPixelRGB(x,y) method which will give back a pixel object with an r, g, b, and a properties for colour and alpha of the pixel.

The only snag is that I had to translate “world” X/Y of the collision into a relative X/Y for my BitmapData pixels.

Fiddly, but doable. Here’s one way to do it:

function hitBase(alienBullet, base) {
    var baseIdx = bases.getChildIndex(base); 
    
    var matchingBmp = baseBmps[baseIdx];
    
    var bmpRelativeX = Math.round(alienBullet.x - matchingBmp.worldX); 
    var bmpRelativeY = Math.round(alienBullet.y - matchingBmp.worldY); 
    var bmpPixelRgba = matchingBmp.bmp.getPixelRGB(bmpRelativeX, bmpRelativeY); 
    
    if (bmpPixelRgba.r > 0) { // we hit a "white" pixel	
        matchingBmp.bmp.draw(baseDamageBmp, bmpRelativeX, bmpRelativeY);
        matchingBmp.bmp.update();
        alienBullet.kill();       
    } 
       
}

In this example we’re grabbing that bitmap object that backs the base sprite - you might recall I squirreled away earlier by pushing it onto an array when I was creating it.

Once I have that bitmap, I use the X & Y co-ords of the alien bullet to work out where in my bitmap I am actually colliding. From there I see whether that’s over a white pixel which represents part of the base. If I am, draw damage directly onto the backing bitmap, then kill the bullet.

Drawing Damage

If I am over a white pixel, I draw a “damaged” circle which is the same colour as my backdrop (black-ish). This makes the base look like it’s breaking down. Since the bullet is in a higher group, it travels over the top of the damage blackness, and the illusion is complete.

You could use a black png for the damage I guess, but in my case baseDamageBmp is just a bitmap I created using a circle() with an 8px radius. My ‘black’ background is actually a CRT green hue RGB(0,27,7), so it was easy enough to go custom.

During my setup, I have something like this:

baseDamageBmp = game.make.bitmapData(16, 16);
baseDamageBmp.circle(8, 8, 8, 'rgba(0,27,7,1)');  // rgba(r,g,b,alpha)

The circle looks pretty naff as bullet damage. I really need to use a more explosion-like pattern, but the hard work was getting the damage happening. The rest is icing!

Anyways, that’s one strategy for custom bitmaps for sprites. Thought I’d write it up in case you even need to do these kind of dynamic collision things.

Time to get this game finished.. Already full of ideas for my next one!