(2-4) [JS] shooting game 만들기

씩씩한 조약돌·2023년 1월 18일
0

미니프로젝트🤹

목록 보기
9/21
post-thumbnail

참고 영상 : https://youtu.be/c-NcYoTshHw (코딩알려주는누나)

4일차 내용

적군 내려오기
1. 적군의 위치는 랜덤 (x좌표)
2. 적군은 밑으로 내려온다 (y좌표의 값이 증가)
3. 1초마다 하나씩 생성


게임 오버 처리하기
1. 적군이 바닥에 닿으면 게임 오버

1. 적군생성 : Enemy함수

1-1. Enemy함수의 변수 : x좌표, y좌표 (기본값 : 0)

function Enemy() {
  this.x = 0;
  this.y = 0;
};

1-2. this.init함수 : 적군의 위치값 설정

  • y좌표 : 최상단에서 시작 = 0

  • x좌표 : 랜덤으로 위치설정

  • generateRandomValue(min, max) : 랜덤값 구하는 함수

  • 최소값 : 0 / 최대값 : 캔버스의 가로넓이 - 이미지 가로넓이

function generateRandomValue(min, max) {
  let randomNum = Math.floor(Math.random() * (max - min + 1)) + min;
  return randomNum;
}

function Enemy() {
  this.x = 0;
  this.y = 0;
  this.init = function () {
    this.x = generateRandomValue(0, canvas.width - 48); //랜덤으로 시작
    this.y = 0; //최상단에서 시작
  };

1-3. 적군을 담을 배열 생성

  • let enemyList = []; : 여러개의 적군을 담을 배열
  • enemyList.push(this); 생성된 적군을 배열에 push시켜줌
function generateRandomValue(min, max) {
  let randomNum = Math.floor(Math.random() * (max - min + 1)) + min;
  return randomNum;
}

let enemyList = [];
function Enemy() {
  this.x = 0;
  this.y = 0;
  this.init = function () {
    this.x = generateRandomValue(0, canvas.width - 48); //랜덤으로 시작
    this.y = 0; //최상단에서 시작

    enemyList.push(this);
  };

1-4. 적군을 생성시켜주는 함수 : createEnemy()

  • setInterval(호출할 함수, 시간)
  • 1초마다 적군을 생성
  • 1초 = 1000ms
function createEnemy() {
  const interval = setInterval(function () {
    let e = new Enemy();
    e.init(); //위치값 설정
  }, 1000);
}

1-5. createEnemy() 호출

  • 이미지로딩 / 키보드이벤트세팅 / 적군생성 / main()
loadImage();
setupKeyboardListener();
createEnemy();
main();

1-6. 이미지 그려주기

  • for문으로 enemyList를 불러줌
function render() {
  ctx.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);
  ctx.drawImage(mainImage, spaceshipX, spaceshipY, 64, 64);

  //총알 랜더링
  for (let i = 0; i < bulletList.length; i++) {
    if (bulletList[i].alive) {
      ctx.drawImage(bulletImage, bulletList[i].x, bulletList[i].y, 25, 25);
    }
  }
  // 적군 랜더링
  for (let i = 0; i < enemyList.length; i++) {
    ctx.drawImage(enemyImage, enemyList[i].x, enemyList[i].y, 40, 40);
  }
}

1-7. 적군 움직이기

  • this.update함수 생성 : 적군이 밑으로 내려올 수 있도록 y좌표의 값이 증가
let enemyList = [];
function Enemy() {
  this.x = 0;
  this.y = 0;
  this.init = function () {
    this.x = generateRandomValue(0, canvas.width - 48); //랜덤으로 시작
    this.y = 0; //최상단에서 시작

    enemyList.push(this);
  };
  //적군의 y좌표 변경
  this.update = function () {
    this.y += 3;
  };
}

1-8. update()함수에서 for문으로 update함수 호출

  • enemyList[i].update();
function update() {
  if (39 in keysDown) {
    spaceshipX += 5;
  } // right

  if (37 in keysDown) {
    spaceshipX -= 5;
  } //left

  if (spaceshipX <= 0) {
    spaceshipX = 0;
  }
  if (spaceshipX >= canvas.width - 64) {
    spaceshipX = canvas.width - 64;
  }

  // 총알의 y좌표 업데이트 하는 함수
  for (let i = 0; i < bulletList.length; i++) {
    if (bulletList[i].alive) {
      bulletList[i].update();
      bulletList[i].checkHit();
    }
  }

  // 적군의 y좌표 업데이트 하는 함수
  for (let i = 0; i < enemyList.length; i++) {
    enemyList[i].update();
  }
}

2. 게임오버

2-1. 게임의 상태값을 담는 변수

  • false는 게임진행중, true는 게임이 끝남 (우주선이 바닥에 닿으면 끝)
let gameOver = false; 

2-2. 적군이 캔버스바닥에 닿으면 게임 종료

  • if (this.y >= canvas.height - 40) : 우주선의 y값이 캔버스 세로길이 - 우주선의 세로길이와 같거나 더 커지면 게임 종료
let enemyList = [];
function Enemy() {
  this.x = 0;
  this.y = 0;
  this.init = function () {
    this.x = generateRandomValue(0, canvas.width - 48); //랜덤으로 시작
    this.y = 0; //최상단에서 시작

    enemyList.push(this);
  };
  //적군의 y좌표 변경
  this.update = function () {
    this.y += 3;

    if (this.y >= canvas.height - 40) {
      gameOver = true;
      console.log("Game Over");
    }
  };
}

2-3. gaemOver=true이면 이미지 렌더링(main())도 멈추기

function main() {
  if (!gameOver) {
    update(); // 좌표값 업데이트
    render(); //그려주기
    requestAnimationFrame(main);
    //console.log("anmiation calls");
  };
}

2-4. gaemOver=false이면 gameover이미지 띄우기

function main() {
  if (!gameOver) {
    update(); // 좌표값 업데이트
    render(); //그려주기
    requestAnimationFrame(main);
    //console.log("anmiation calls");
  } else {
    ctx.drawImage(gameOverImage, 10, 100, 380, 380);
  }
}


4일차 후기

1. 코드의 흐름에 대해서 이해할 필요가 있음
(1) 적군

  • Enemy() : x좌표, y좌표를 가짐
    / init() : x, y좌표값 초기화 설정
  • let enemyList = []; : Enemy()를 담을 배열
  • createEnemy() : 1초마다 Enemy()를 생성
  • 랜더링 : enemyList.length의 갯수만큼 반복하여 enemyImage를 drawImage해줌 (for문)
  • update() : Enemy()가 아래로 내려올 수 있도록 y좌표값을 증가시킴
  • 업데이트 : enemyList.length의 갯수만큼 반복하여 Enemy()의 y좌표를 증가시킴

(2) 게임오버

  • let gameOver = false; : 게임의 상태값 저장 (false가 실행중)
  • if(적군의 이미지가 캔버스의크기를 벗어나면) gameOver의 값을 true로 변경
  • gameOver=false일때 update(), render(), requestAnimationFrame(main) 함수 호출
  • gameOver=true일땐 함수들을 호출 하지않고 게임오버 이미지 출력

5일차에 할 일

점수 계산하기
1. 총알이 적군에 닿으면 총알과 우주선이 없어짐
2. 총알이 적군에 닿으면 점수+1
: 총알.y <= 적군y && (총알.x >= 적군.x && 총알.x <= 적군.width)
(총알의 y좌표가 적군의 y값보다 같거나 작아지면)
&& (총알의 x좌표가 적군의 x좌표보다 같거나 크고 && 총알의 x좌표가 적군의 width보다 같거나 작으면)

❗추가하기

  • 총알 y좌표 max값 설정(캔버스 밖에서 적군 잡지 않도록)
  • gameover 이미지 수정
  • 조작버튼 만들기 (키보드 또는 마우스로 할 수 있도록)
profile
씩씩하게 공부중 (22.11~)

0개의 댓글