Player Bullets
Now that we have asteroids hurtling towards us, we need to be able to shoot them out of the sky! Every spaceship needs some cannons to fight with, so lets move on and add a weapon to the player’s space ship.
Making it so that the player can shoot bullets is almost the same task as creating asteroids that fly down the screen. Now is a chance to put the skills you learned from creating asteroids to the test!
Task Definition
Bullets in Space Avengers should abide by the following rules;
- You should fire a new bullet if the player is pressing the ‘Space’ key on the keyboard.
- If the user is holding down the ‘Space’ key, you shouldn’t allow them to shoot more than 1 bullet every 0.3 seconds.
- All bullets should constantly move up the screen.
- Bullets that have disappeared off the top of the screen should be destroyed.
The stages for this task are very similar to that of the asteroids task, so you should refer back to that if the details seem a little limited here.
Hints
- This task is actually pretty similar to the asteroids task, and the user input is similar to the ‘player movement’ task.
- The main difference is that you will want to spawn bullets whenever you press the Space key instead of using a timer.
- However, you will still need to add another time to prevent the user from firing too many bullets at once!
The following Phaser properties and functions will be usfeul for this task;
this.cursors.space.isDown
Walkthrough
1. Preload the Bullet Image
Just like any other image you intend to show on the screen, you will need to preload the image in your ‘preload’ function. We have provided a few different bullet images in the assets/images folder. Pick the one you want and load it using this.load.image(name, imagePath).
preload() {
this.load.image('bullet', 'assets/images/bullet-simple.png');
}2. Check for the ‘Space’ Key
Checking for whether the user is pressing the ‘Space’ key is almost identical to how we check whether the user is pressing an arrow key down. Check back to the player movement task and see if you can figure this step out from there.
For now, why not just print some text to the console to make sure that your code is working correctly?
update() {
if (this.cursors.space.isDown) {
console.log("Fire Bullet!");
}
}3. Create a “Bullet” Group
We need an easy way to group and keep track of the bullets that we create in our game. This is so that we can check whether any bullets collide with asteroids later on.
In your create() function, you should create an empty group for bullets just like we already have for asteroids. Call it this.bulletGroup.
create() {
// Existing Code
this.bulletGroup = this.add.group();
}4. Spawning Bullets
You should base your answer for this stage on what you did during the Asteroid Task. Here is a summary of the task steps;
- Create a ‘fireBullet’ function in your MainGameScene.
- Create a bullet similar to how asteroids are created in createAsteroid().
- Ensure the bullet starts where the playerShip is located (based on the x,y values of the playerShip).
- Give the bullet an upwards velocity.
- Call ‘spawnBullet’ when you know the space bar is pressed down.
update() {
if (this.cursors.space.isDown) {
this.fireBullet();
}
}
fireBullet() {
let x = this.playerShip.x;
let y = this.playerShip.y;
let bullet = this.physics.add.image(x, y, 'bullet');
bullet.setVelocity(0, -100);
this.bulletGroup.add(bullet);
}5. Destroy off-screen bullets
This step is just like steps 3 and 4 from the asteroids task and you should do the following;
- Add bullets to that group whenever you spawn a new one.
- At the end of your update function, iterate over the items in bulletGroup by accessing this.bulletGroup.getChildren().
- For each bullet that is way off the top of the screen - destroy it by calling the this.bulletGroup.getChildren()[i].destroy() function.
update(time, delta) {
let bullets = this.bulletGroup.getChildren();
for(let i = 0; i < bullets.length; i++) {
let bullet = bullets[i];
if ( bullet.y < 0 ) {
bullet.destroy();
}
})
}update(time, delta) {
this.bulletGroup.getChildren().forEach((bullet) => {
if ( bullet.y < 0 ) {
bullet.destroy();
}
})
}6. Restricting Bullet Count
If you have run the game since step 2, you will notice that when you press fire you shoot a near uncountable stream of bullets! This isn’t great because there isn’t going to be much challenge in the game if this is how it works.
We’re going to setup another timer like we did with the asteroids in order to restrict how many bullets the player can shoot. While similar, there are some subtle differences in this task to the asteroids;
- Create the variable this.bulletTimer in your create method.
- In your update method, subtract the current frame time from the timer this.bulletTimer -= delta.
- In your ‘fireBullet’ function, do not allow the user to shoot a bullet if the timer is above zero.
- If you do shoot a bullet, you will need to reset the bulletTimer to prevent the player from shooting a stream of bullets.
create() {
this.bulletTimer = 0;
}
update(time, delta) {
this.bulletTimer -= delta;
}
fireBullet() {
if ( this.bulletTimer < 0 ) {
// Do existing code
this.bulletTimer = 300; // 300 ms
}
}Extensions
- The code in your update function continues to grow! Now would be a good time to break some of the code out into functions. Perhaps make an updatePlayerBullets() function and move all of your bullet related update code there. Don’t forget to call that function from your main update function!
- It would also be a good idea to use variables to set the minTimeBetweenPlayerShots and the playerBulletSpeed.