Star Strike

A game made using three.js in a couple of weeks

This is a small game I made as part of my computer graphics module at university made using three.js. The objective of the game is to destroy the enemy spaceships by shooting them, while avoiding getting hit by enemy missiles. The player switches between piloting their ship in a top-down view and shooting the gun in a first-person view.

The game

I knew since getting this assignment that I wanted to make a game set in space since I'm a big sci-fi fan and love games that use Newtonian physics. The main idea for the game came from the requirement that the game must use two cameras that the player can switch between. This led to the idea of having two modes.

Flight mode has the player controlling the ship in a top-down view: flight-mode

Weapon mode has the player controlling the ship-mounted gun in a first-person view: weapon-mode

I decided to not let the player control their ship while in weapon mode to incentivise switching between the two modes and add an element of risk to using the weapon, since you cannot dodge enemy missiles.

Creating 3D Models with Blender

I used Blender (a fantastic open-source application) to create the 3D models used for the game, including the player ship, enemy ships, the gun turret, and the missiles.

blender

Starting from a cube, I created the general shape of the ship using reference images. I then added subdivisions and edge loops to add detail.

I used Blender's 'select non-manifold geometry' function to find problematic vertices, which I then fixed. The UVs were then unwrapped, and texture painting was used to add the base colour. Normal, metallic, and roughness maps were added in the shader editor to add further detail.

Finally, the models were exported as .gltf files and imported into three.js.

Using three.js

I split the code into five main functions. The main function initialises key three.js objects such as the scene, renderer, and loading manager, and sets up the event listeners. The init function then sets up level-independent things such as the cameras, render passes, ambient light, audio, and loads required GLTF models. There are two functions for loading their respective level which loads the skybox, stars, lights, and places the enemy ships. Finally, the animate function contains code that is run every frame, such as moving the player, enemy ships, and projectiles, checking for collisions, and updating animations.

For collision detection, I used three.js's raycasting. When the player shoots, a ray is cast in the direction of the gun and is checked for collisions with enemy ships. Missiles also cast a short ray in the direction they are travelling to detect collisions with the player. Invisible cubes are used as bounding boxes for the ships to make collision detection more efficient.


You can try out the game in your browser here