circle bullet pattern in phaser

After working on tinyRPG for a while I wanted to share some of the my approaches to implement common game mechanics in phaser. Therefore this example will show you how to create a circular bullet wave as seen in many bullet hell games.

The final demo should be able to create an arbitrary number of bullets evenly distributed in a circle and give then the correct velocity to move away from the center.

First we will need bullets. To save some bandwidth we can create the bitmapdata on the fly to make a bullet sprite obsolete. Phasers bitmapData object gives us a canvas to draw on. Using the arc function we can then get a filled circle stored in an object we can use as a sprite.

// Create BitmapData
var bmd = game.add.bitmapData(30,30);

// Draw circle
bmd.ctx.fillStyle = '#CC181E';
bmd.ctx.beginPath();
bmd.ctx.arc(15, 15, 5, 0, Math.PI*2, true); 
bmd.ctx.closePath();
bmd.ctx.fill();

If we would create a new sprite every time a bullet is spawned, we would end up with an enormous amount of unnecessary objects. To avoid this we can create a group and fill it with a number of sprites that matches the approximated maximum number of bullets that may be on screen simultaneously. Whenever a bullet is spawned the group will be searched for a sprite that is not on screen anymore and it will be reset.

var bullets = game.add.group();
bullets.enableBody = true;
bullets.physicsBodyType = Phaser.Physics.ARCADE;
bullets.createMultiple(2000, bmd);
bullets.callAll('body.setSize', 'body', 10, 10, 10, 10);
bullets.setAll('checkWorldBounds', true);
bullets.setAll('outOfBoundsKill', true);
bullets.setAll('anchor.x', 0.5);
bullets.setAll('anchor.y', 0.5);

But the most important part is still missing. How do we calculate the direction and velocity of the bullets? To do this, we will first calculate the radian angle of each bullet. As the radius of our default circle is 2*pi, we will define a starting angle of -pi and then add pi/bulletcount*2 for each bullet. This way we get an evenly distributed circle of bullets. Now we can easily calculate the velocity by using the sinus and cosinus of the radian angle.

var amount, start, step, i, angle, speed;
amount = 36;
start = Math.PI * -1;
step = Math.PI / amount * 2;
i = amount;
while (i > 0) {
    bullet = bullets.getFirstDead();
    if (bullet) {
        bullet.reset(
	        game.input.activePointer.x,
	        game.input.activePointer.y
        );
        var angle = start + i * step;
        speed = 200;
        bullet.body.velocity.x = Math.cos(angle) * speed;
        bullet.body.velocity.y = Math.sin(angle) * speed;
    }
    i--;
}

Using this method you can change the amount and speed of the bullets without having to rewrite the rest of your code. You can try the example by clicking or taping in the box below.