Asteroids Session 3 of 3

Level: Advanced (11+) Duration: 3 × 1 Hour

Part 4: Firepower 60 Minutes

We’ve now created a fun game of dodgeball! We’re sitting ducks without some way to fight back.

To fire a bullet, we'll create a new circle at the location of our spaceship and send it flying. We'll attach this code to the "space" event.

function fire() { let x = spaceship.x let y = spaceship.y let bullet = circle(x, y, 5) bullet.speed = 5 bullet.direction = spaceship.angle } on('space', fire)

And remove anything the bullet comes in contact with. We can achieve this by again listening for the "collision" event, this time on the bullet.

function fire() { let x = spaceship.x let y = spaceship.y let bullet = circle(x, y, 5) bullet.speed = 5 bullet.direction = spaceship.angle bullet.on('collision', hit) } on('space', fire) function hit(target) { target.remove() this.remove() }

For collision events, the event handler is passed a parameter containing the object we collided with. We can call the remove() method on this object to get rid of it.

We also want to get rid of the bullet itself. Here we'll use the infamous JavaScript keyword this. this is one of the most misunderstood concepts in JavaScript, as it can mean different things at different times. In an event handler it refers to the object that triggered the event, in this case the bullet.

Houston, we have another problem! Since the bullet starts at our ship’s position, we end up blowing ourselves up. We need to start the bullet at a distance from our ship. The question is, how do we determine that position?

Trigonometry

Early mathematicians recognized something else. As you move around a circle, the x and y coordinates follow a predictable wave-like pattern. These are referred to as sine and cosine.

Using this knowledge, we can work a little math-magic to determine where to place the bullet, given the angle of the spaceship and a safe distance.

function fire() { let direction = ship.angle * Math.PI / 180 let distance = 5 let x = spaceship.x + Math.cos(direction) * distance let y = spaceship.y + Math.sin(direction) * distance let bullet = circle(x, y, 5) bullet.speed = 5 bullet.direction = spaceship.angle bullet.on('collision', hit) }

Putting It All Together

let body = triangle(300, 300, 40, 80) body.color = 'silver' body.angle = 90 let leftWing = triangle(280, 270, 20, 60) leftWing.color = 'silver' leftWing.angle = -10 let rightWing = triangle(280, 330, 20, 60) rightWing.color = 'silver' rightWing.angle = 190 let spaceship = group(body, leftWing, rightWing) spaceship.x = width / 2 spaceship.y = height / 2 spaceship.angle = -90 function moveShip(key) { if (key == 'ArrowLeft') { spaceship.rotate(-1) } if (key == 'ArrowRight') { spaceship.rotate(1) } if (key == 'ArrowUp') { spaceship.forward(1) } } on('keydown', moveShip) for (let i = 0; i < 20; i = i + 1) { let x = random(0, width) let y = random(0, height) let size = random(40, 70) let a = spaceship.x - x let b = spaceship.y - y let distance = Math.sqrt(a * a + b * b) if (distance > 200) { let asteroid = circle(x, y, size) asteroid.speed = random(1, 2) asteroid.direction = random(0, 360) } } function crash() { spaceship.explode() } spaceship.on('collision', crash) function fire() { let direction = spaceship.angle * Math.PI / 180 let distance = 80 let x = spaceship.x + Math.cos(direction) * distance let y = spaceship.y + Math.sin(direction) * distance let bullet = circle(x, y, 10) bullet.speed = 5 bullet.direction = spaceship.angle bullet.on('collision', hit) } on('space', fire) function hit(target) { target.remove() this.remove() } gravity = false