Create, Compete & Win at Redbrick Connect 2024! 🎉
스니펫슈팅 게임 만들기

슈팅 게임 만들기

먼저 슈팅 로직 코드를 작성하세요

camera.useFPS()로 FPS 모드를 설정하고, OnPointerDown()을 사용하여 마우스 클릭을 감지해 createBullet()을 트리거합니다.
이 함수는 총알을 초기화하고 배치하며, BULLET_SPEEDBULLET_RANGE_SQUARED를 사용하여 총알의 속도와 범위를 정의합니다.
그런 다음, 총알을 씬에 추가하고 Update()를 통해 moveBullets()를 호출하여 총알의 이동과 범위를 벗어난 총알의 제거를 처리합니다.


슈팅
Shooting logic
const camera = WORLD.getObject("MainCamera");
camera.useFPS();
 
let bullets = [];
const BULLET_SPEED = 1.5;
const BULLET_RANGE_SQUARED = 30000;
 
// 포인터를 눌렀을 때 트리거됩니다.
function OnPointerDown() {
  createBullet();
}
 
// 총알을 생성하고 초기 속성을 설정합니다.
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);
 
  // 카메라 앞에 총알을 배치합니다.
  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);
}
 
// 일반적으로 프레임마다 상태를 업데이트합니다.
function Update(dt) {
  moveBullets();
}
 
// 총알을 이동시키고 수명주기를 관리합니다.
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
    );
 
    // 총알이 정의된 범위를 벗어났는지 확인합니다.
    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);
    }
  }
}

타겟 객체 추가하기

TARGET_HIT_RANGE로 피격 감지 범위를 정의하고 타겟을 저장할 배열 targetObjects를 초기화합니다.
"car"와 같은 객체를 WORLD.getObject()를 사용하여 targetObjects에 추가합니다.
moveBullets()를 수정하여 targetObjects와의 충돌 감지를 추가하고, 각 총알과 타겟 사이의 거리를 확인합니다.
총알이 TARGET_HIT_RANGE 내에 있는 경우, target.kill()을 호출하여 피격을 처리하고 총알을 씬에서 제거하고, 관련 리소스를 정리합니다.


image 슈팅 타겟
Shooting logic
const TARGET_HIT_RANGE = 32;
 
const targetObjects = [];
targetObjects.push(WORLD.getObject("car"));
// 필요에 따라 더 많은 객체를 targetObjects에 추가하세요.
 
// 다른 코드
 
// moveEnergyBall 내부에서
function moveEnergyBall() {
  // 다른 코드
 
  // 총알이 타겟을 맞추는지 확인
  for (let j = 0; j < targetObjects.length; j++) {
    const target = targetObjects[j];
    if (
      bullet.object.position.distanceToSquared(target.position) <
      TARGET_HIT_RANGE
    ) {
      target.kill(); // 타겟 피격 처리
      WORLD.remove(bullet.object);
      bullet.object.geometry.dispose();
      bullet.object.material.dispose();
      bullets.splice(i, 1);
    }
  }
}

최종 코드

이 코드를 복사하여 붙여넣고 슈팅 기능을 사용하세요. 타겟 객체를 변경하는 것을 잊지 마세요.

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")); // 타겟을 변경하세요
// 필요에 따라 더 많은 객체를 targetObjects에 추가하세요.
 
// 포인터를 눌렀을 때 트리거됩니다.
function OnPointerDown() {
  createBullet();
}
 
// 총알을 생성하고 초기 속성을 설정합니다.
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);
 
  // 카메라 앞에 총알을 배치합니다.
  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);
}
 
// 일반적으로 프레임마다 상태를 업데이트합니다.
function Update(dt) {
  moveBullets();
}
 
// 총알을 이동시키고 수명주기를 관리합니다.
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
    );
 
    // 총알이 정의된 범위를 벗어났는지 확인합니다.
    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(); // 타겟 피격 처리
        WORLD.remove(bullet.object);
        bullet.object.geometry.dispose();
        bullet.object.material.dispose();
        bullets.splice(i, 1);
      }
    }
  }
}

커스터마이즈 하기

총과 GUI를 추가하여 커스터마이즈 할 수 있습니다.


image 커스텀 슈팅 게임

자신의 에셋을 추가하는 방법은 My asset 페이지에서 확인하세요.

만약 총알을 Three.js를 이용해 생성하지 않고 에셋을 추가해 사용하고 싶다면 이전 최종 코드에서 다음 코드들을 수정하세요.

//최종 코드의 26~28라인, 아래 3개의 코드를 삭제하세요
// const geometry = new THREE.SphereGeometry(1, 32, 32);
// const material = new THREE.MeshBasicMaterial({ color: 0x00ff00 });
// const bullet = new THREE.Mesh(geometry, material);
 
//그리고 아래 코드를 그 자리에 추가합니다
const bullet = WORLD.getObject("bullet_object").clone();
 
 
 
//최종 코드의 80~81 라인, 아래 2개의 코드를 삭제하세요
// bullet.object.geometry.dispose();
// bullet.object.material.dispose();