Create, Compete & Win at Redbrick Connect 2024! 🎉
SnippetHow to create shooting game

How to create shooting game

Code shooting logic first

Set FPS mode with camera.useFPS(), detect mouse clicks with OnPointerDown() to trigger createBullet() which initializes and positions bullets stored in the bullets array, using BULLET_SPEED and BULLET_RANGE_SQUARED to define their speed and range, then add bullets to the world, and move them using Update() which calls moveBullets() to handle movement and removal of out-of-range bullets.


Shooting
Shooting logic
const camera = WORLD.getObject("MainCamera");
camera.useFPS();
 
let bullets = [];
const BULLET_SPEED = 1.5;
const BULLET_RANGE_SQUARED = 30000;
 
// Triggered when the pointer is pressed
function OnPointerDown() {
  createBullet();
}
 
// Creates a bullet and sets its initial properties
function createBullet() {
  let cameraDirection = new THREE.Vector3();
  camera.getWorldDirection(cameraDirection);
  cameraDirection.setLength(BULLET_SPEED);
 
  const cameraPosition = camera.position;
 
  const geometry = new THREE.SphereGeometry(1, 32, 32);
  const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
  const bullet = new THREE.Mesh(geometry, material);
 
  // Position the bullet in front of the camera
  bullet.position.set(
    cameraPosition.x + cameraDirection.x,
    cameraPosition.y + cameraDirection.y,
    cameraPosition.z + cameraDirection.z
  );
  bullet.rotation.copy(camera.rotation);
 
  bullets.push({ object: bullet, direction: cameraDirection.clone() });
 
  WORLD.add(bullet);
}
 
// Updates the state, usually on a per-frame basis
function Update(dt) {
  moveBullets();
}
 
// Moves the bullets and handles their lifecycle
function moveBullets() {
  for (let i = bullets.length - 1; i >= 0; i--) {
    const bullet = bullets[i];
    const bulletPosition = bullet.object.position;
    const movementVector = bullet.direction;
 
    bullet.object.position.set(
      bulletPosition.x + movementVector.x,
      bulletPosition.y + movementVector.y,
      bulletPosition.z + movementVector.z
    );
 
    // Check if the bullet is beyond the defined range
    if (
      bullet.object.position.distanceToSquared(PLAYER.position) >
      BULLET_RANGE_SQUARED
    ) {
      WORLD.remove(bullet.object);
      bullet.object.geometry.dispose();
      bullet.object.material.dispose();
      bullets.splice(i, 1);
    }
  }
}

add Target Objects

Define a hit detection range with TARGET_HIT_RANGE and initialize an array targetObjects to store targets. Add objects like a "car" to targetObjects using WORLD.getObject(). Modify moveBullets() to include collision detection with targetObjects, checking the distance between each bullet and target. If a bullet is within TARGET_HIT_RANGE of a target, invoke target.kill() to handle the hit, remove the bullet from the world, and clean up its resources.


image Shooting Target
Shooting logic
const TARGET_HIT_RANGE = 32;
 
const targetObjects = [];
targetObjects.push(WORLD.getObject("car"));
//add more objects as targetObject as you need.
 
// other code
 
//inside of moveEnergyBall
function moveEnergyBall() {
  // other code
 
  // Check if the ball hits any target
  for (let j = 0; j < targetObjects.length; j++) {
    const target = targetObjects[j];
    if (
      bullet.object.position.distanceToSquared(target.position) <
      TARGET_HIT_RANGE
    ) {
      target.kill(); // Handle target hit
      WORLD.remove(bullet.object);
      bullet.object.geometry.dispose();
      bullet.object.material.dispose();
      bulets.splice(i, 1);
    }
  }
}

Final code

Just copy paste this code and use shooting feature. Just dont forget to change targetObjects.

Shooting logic
const camera = WORLD.getObject("MainCamera");
camera.useFPS();
 
let bullets = [];
const BULLET_SPEED = 1.5;
const BULLET_RANGE_SQUARED = 30000;
const TARGET_HIT_RANGE = 32;
 
const targetObjects = [];
targetObjects.push(WORLD.getObject("car")); // change to your target
//add more objects as targetObject as you need.
 
// Triggered when the pointer is pressed
function OnPointerDown() {
  createBullet();
}
 
// Creates a bullet and sets its initial properties
function createBullet() {
  let cameraDirection = new THREE.Vector3();
  camera.getWorldDirection(cameraDirection);
  cameraDirection.setLength(BULLET_SPEED);
 
  const cameraPosition = camera.position;
 
  const geometry = new THREE.SphereGeometry(1, 32, 32);
  const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
  const bullet = new THREE.Mesh(geometry, material);
 
  // Position the bullet in front of the camera
  bullet.position.set(
    cameraPosition.x + cameraDirection.x,
    cameraPosition.y + cameraDirection.y,
    cameraPosition.z + cameraDirection.z
  );
  bullet.rotation.copy(camera.rotation);
 
  bullets.push({ object: bullet, direction: cameraDirection.clone() });
 
  WORLD.add(bullet);
}
 
// Updates the state, usually on a per-frame basis
function Update(dt) {
  moveBullets();
}
 
// Moves the bullets and handles their lifecycle
function moveBullets() {
  for (let i = bullets.length - 1; i >= 0; i--) {
    const bullet = bullets[i];
    const bulletPosition = bullet.object.position;
    const movementVector = bullet.direction;
 
    bullet.object.position.set(
      bulletPosition.x + movementVector.x,
      bulletPosition.y + movementVector.y,
      bulletPosition.z + movementVector.z
    );
 
    // Check if the bullet is beyond the defined range
    if (
      bullet.object.position.distanceToSquared(PLAYER.position) >
      BULLET_RANGE_SQUARED
    ) {
      WORLD.remove(bullet.object);
      bullet.object.geometry.dispose();
      bullet.object.material.dispose();
      bullets.splice(i, 1);
    }
 
    for (let j = 0; j < targetObjects.length; j++) {
      const target = targetObjects[j];
      if (
        bullet.object.position.distanceToSquared(target.position) <
        TARGET_HIT_RANGE
      ) {
        target.kill(); // Handle target hit
        WORLD.remove(bullet.object);
        bullet.object.geometry.dispose();
        bullet.object.material.dispose();
        bullets.splice(i, 1);
      }
    }
  }
}

Customize it

You can add gun objects and guis to customize it.


image Custom Shooting Game

Check out the My asset page for instructions on how to add your assets.

If you want to use an asset instead of creating bullets with Three.js, modify the following lines in the previous final code.

// Delete the following 3 lines (lines 26-28 in the final code)
// const geometry = new THREE.SphereGeometry(1, 32, 32);
// const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// const bullet = new THREE.Mesh(geometry, material);
 
// Then add this code in their place
const bullet = WORLD.getObject("bullet_object").clone();
 
 
 
// Delete the following 2 lines (lines 80-81 in the final code)
// bullet.object.geometry.dispose();
// bullet.object.material.dispose();