Since starting this series I have been looking forward to coding up Jet Fighter as it is where I got a lot of inspiration for my game Spaceheir. The idea was to create a mashup of Asteroids and Jet Fighter. Taking the Player vs environment aspects of Asteroids; shooting asteroids to gain levels. And the player vs player combat system of Jet Fighter.
What is Jet Fighter?
The game is beautifully simple, Player 1 controls a black jet and player 2 controls a white jet. The black jet shoots black bullets, the white jet shoots white bullets. If you hit the opposing player you gain a point represented by the score corresponding to your colour!
If you go off the end of the map you appear on the other side, same goes for the bullets.
The Jet
The first thing we need to code up is the Jet. Here are some things we need to consider.
- The Jet moves the direction it is facing.
- The jet shoots in the direction it is facing.
- If the jet goes off the map, it will appear the other side
The Images
I’ve created both the black and white jets in photoshop. Go ahead and copy these for your implementation!


Drawing the jets

Let’s spawn the jets in a random location on the map, by creating a Jet class.
[code lang="javascript"]
class Jet {
constructor(image) {
this.x = random(width);
this.y = random(height);
this.image = image;
}
draw() {
image(this.image, this.x, this.y);
}
}
[/code]
Let’s load the images in p5.js preload function, as this executes before setup and draw.
[code lang="javascript"]
let blackJet;
let whiteJet;
let blackJetImage;
let whiteJetImage;
function preload() {
blackJetImage = loadImage("black-jet.png");
whiteJetImage = loadImage("white-jet.png");
}
function setup() {
createCanvas(400, 400);
blackJet = new Jet(blackJetImage);
whiteJet = new Jet(whiteJetImage);
}
function draw() {
background(130);
blackJet.draw();
whiteJet.draw();
}
[/code]
Go the way we’re facing!
Let’s make the jets go forwards, like this.

I’ve added some comments to highlight what’s been added. Oh yeah, don’t forget to call update on the jets in sketch.js.
[code lang="javascript"]
class Jet {
constructor(image) {
this.x = random(width);
this.y = random(height);
this.image = image;
this.angle = 0;
this.speed = 0.7;
}
// added an update function
update() {
this.goTheWayWereFacing();
this.constrainToMap();
}
// make them go forwards!
goTheWayWereFacing() {
this.x += this.speed * sin(this.angle);
this.y += this.speed * cos(this.angle);
}
// lets keep on the map now you buggers
constrainToMap() {
if (this.x < -this.image.width) {
this.x = width;
} else if (this.x > width) {
this.x = 0;
}
if (this.y > height) {
this.y = 0;
} else if (this.y < -this.image.height) {
this.y = height;
}
}
draw() {
// the push/pop is to prevent the rotation from happening to other stuff!
push();
translate(this.x, this.y);
imageMode(CENTER);
// the plus HALF_PI bit is because I drew the images upside down, sorry!
rotate(this.angle + HALF_PI);
image(this.image, 0, 0);
pop();
}
}
[/code]
Steering!
I’ve coded it so the black jet uses the arrow keys to move and the white jet uses a and d.

The rotation stuff is pretty much identical to the previous tutorial for how to code Gran Trak 10. Don’t worry if you haven’t seen it the concept is pretty simple If the player clicks a key we then set the rotateAmount which is added to the angle each frame. If the player lets go of the key we set the
rotateAmount to 0, so it doesn’t rotate.
Jet class
[code lang="javascript"]
class Jet {
constructor(image) {
this.x = random(width);
this.y = random(height);
this.image = image;
this.angle = 0;
this.speed = 0.7;
// added this new rotate amount variable
this.rotateAmount = 0;
}
update() {
this.goTheWayWereFacing();
this.constrainToMap();
// increment the angle each frame
this.angle += this.rotateAmount;
}
[/code]
Sketch
[code lang="javascript"]
// set ROTATE_AMOUNT at the top of the file, I've set it to 0.05
// have a play around with the numbers, find a rotate amount that you like
function keyPressed() {
if (keyCode === RIGHT_ARROW) {
blackJet.rotateAmount = ROTATE_AMOUNT;
} else if (keyCode === LEFT_ARROW) {
blackJet.rotateAmount = -ROTATE_AMOUNT;
} else if (keyCode === 68) {
// d
whiteJet.rotateAmount = ROTATE_AMOUNT;
} else if (keyCode === 65) {
// a
whiteJet.rotateAmount = -ROTATE_AMOUNT;
}
}
function keyReleased() {
if (keyCode === RIGHT_ARROW || keyCode === LEFT_ARROW) {
blackJet.rotateAmount = 0;
} else if (keyCode === 65 || keyCode === 68) {
whiteJet.rotateAmount = 0;
}
}
[/code]
Bullets!
Bullets require a lot of functionality that the Jets do, they need to go in the direction that the ship was facing when it was shot. They also need to be constrained to the map.

Bullet class
Created a new Bullet class, this takes the x and y position of the jet at the point the bullet was shot, as well as the angle, and a new isWhite flag which is used to determine the colour of the bullet.
[code lang="javascript"]
class Bullet {
constructor(x, y, angle, isWhite) {
this.x = x;
this.y = y;
this.angle = angle;
this.isWhite = isWhite;
this.speed = 2;
this.r = 1.5;
}
update() {
this.x += this.speed * cos(this.angle);
this.y += this.speed * sin(this.angle);
this.constrainToMap();
}
constrainToMap() {
if (this.x < -this.r) {
this.x = width;
} else if (this.x > width) {
this.x = 0;
}
if (this.y > height) {
this.y = 0;
} else if (this.y < -this.r) {
this.y = height;
}
}
draw() {
if (this.isWhite) {
push();
noStroke();
fill(255);
ellipse(this.x, this.y, this.r*2, this.r*2);
pop();
} else {
push();
fill(0);
ellipse(this.x, this.y, 3, 3);
pop();
}
}
}
[/code]
Add a new bullets array to the Jet class. Once again, I’ve added comments so you can quickly see what has been added.
[code lang="javascript"]
class Jet {
// added an is white flag, so we know which bullets to shoot!
constructor(image, isWhite) {
this.x = random(width);
this.y = random(height);
this.image = image;
this.angle = 0;
this.speed = 0.7;
this.rotateAmount = 0;
this.bullets = [];
this.isWhite = isWhite;
}
update() {
this.goTheWayWereFacing();
this.constrainToMap();
// increment the angle each frame
this.angle += this.rotateAmount;
}
goTheWayWereFacing() {
this.x += this.speed * cos(this.angle);
this.y += this.speed * sin(this.angle);
}
constrainToMap() {
if (this.x < -this.image.width) {
this.x = width;
} else if (this.x > width) {
this.x = 0;
}
if (this.y > height) {
this.y = 0;
} else if (this.y < -this.image.height) {
this.y = height;
}
}
// when the player shoots add to the bullet array
shoot() {
let bullet = new Bullet(this.x, this.y, this.angle, this.isWhite);
this.bullets.push(bullet);
}
draw() {
push();
translate(this.x, this.y);
imageMode(CENTER);
rotate(this.angle + HALF_PI);
image(this.image, 0, 0);
pop();
// call to draw and update the buggers
this.drawBullets();
}
// draw and update the buggers
drawBullets() {
for (let bullet of this.bullets) {
bullet.update();
bullet.draw();
}
}
}
[/code]
And then just update your sketch so you pass that new isWhite flag in, so true if it is white and false if it isn’t.
Make the bullets de-spawn!
We don’t want every bullet ever shot to be in circulation forever as our game would look really silly and probably blow up after a while. Let’s make the bullets de-spawn after some time of being alive, when they de-spawn we then remove them from the bullets array.
So in the bullets class let’s add a new field, we will call it timeAlive, which we will increment every frame.
[code lang="javascript"]
constructor(x, y, angle, isWhite) {
this.x = x;
this.y = y;
this.angle = angle;
this.isWhite = isWhite;
this.speed = 2;
this.r = 1.5;
console.log(this.angle);
// this bugger was added
this.timeAlive = 0;
}
update() {
this.x += this.speed * cos(this.angle);
this.y += this.speed * sin(this.angle);
this.constrainToMap();
// increment the time alive
this.timeAlive++;
}
[/code]
Then let’s check each bullet to see if it has been alive for longer than a certain period of time, if it has remove it. This is in our Jet class where we draw and update the bullets.
Notice how we loop through the bullets backwards, see what happens if you loop through it forwards!
[code lang="javascript"]
// draw and update the buggers
drawBullets() {
for (let i = this.bullets.length - 1; i >= 0; i--) {
this.bullets[i].update();
this.bullets[i].draw();
if (this.bullets[i].timeAlive > 200) {
this.bullets.splice(i, 1);
}
}
}
[/code]
Scoring system
It’s no game without a scoring system, so let’s add one!

Hitting an enemy
Each frame, we need to loop through all of the bullets and check against their target jet if they have hit them. So we need to check all of the white bullets against the black jet and all the black bullets against the white jet.
To do that, let’s pass the bullets array of the other jet into the update function.
Sketch.js
[code lang="javascript"]
function draw() {
background(130);
// add the enemy bullets into the update function
blackJet.update(whiteJet.bullets);
whiteJet.update(blackJet.bullets);
blackJet.draw();
whiteJet.draw();
}
[/code]
In the Jet class we need to loop through the bullets, if the bullet has hit the current ship we need to remove that bullet from the array.
[code lang="javascript"]
update(enemyBullets) {
this.goTheWayWereFacing();
this.constrainToMap();
this.angle += this.rotateAmount;
// new function to check if player has been hit
this.processBeingHitByBullet(enemyBullets);
}
processBeingHitByBullet(enemyBullets) {
// I use 10 as the radius for the ship, you can tweak it
for (let i = enemyBullets.length - 1; i >= 0; i--) {
if (dist(this.x, this.y, enemyBullets[i].x, enemyBullets[i].y) < (10 + enemyBullets[i].r)){
enemyBullets.splice(i, 1);
}
}
}
[/code]
Displaying scores!
As is a tradition with these tutorials I leave a little bit of development left to do so you can get stuck in and write some code. This one may require you to restructure how we’ve just implemented the bullets hitting the player.
[…] The game is completely opensource, here’s the github For a step by step process on how to code Jet Fighter – click here! […]
[…] The game is completely opensource, here’s the github For a step by step process on how to code Jet Fighter – click here! […]
Hello everyone! This is my first time ever coding in java and I was wondering if someone had a video tutorial of how to code this game because Im getting a little confused on the steps right now.