https://conquer-it.tistory.com/132
HTML/CSS/JS로 게임 만들기 3
11. 적군 만들어 주기
총알 발사까지 마친 상태에서 다음으로 만들 것은 적군이다.
적군의 특징으로는
적군의 특징 1. 적군의 위치는 랜덤하다. 2. 적군은 위에서 아래로 내려온다. 3. n초마다 적군이 생성된다. 4. 적군이 바닥에 닿으면 게임이 종료된다. 5. 적군과 총알이 만나게 되면 적군은 사라지고 스코어가 1씩 올라간다. |
총알 만드는 것처럼 적군도 클래스를 만들어 줘야 한다.
const 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.y = 0;
this.x = generateRandomValue(0, canvas.width-48);
enemyList.push(this);
}
}
이 적군의 초기 위치의 y좌표는 항상 맨 위에서 시작이 되므로 0으로 셋팅해주면 되지만
x좌표같은 경우, 랜덤하게 생성되어야 하기 때문에 랜덤한 위치에 생성되게 따로 함수를 만들어 준다.
generateRandomValue 함수는 최소값과 최대값 사이에서 랜덤한 값을 구하는 함수이다. *참고 https://velog.io/@mementomori/Javascript-%EC%B5%9C%EC%86%8C-%EC%B5%9C%EB%8C%80%EA%B0%92-%EC%82%AC%EC%9D%B4%EC%9D%98-%EB%9E%9C%EB%8D%A4-%EC%88%AB%EC%9E%90-%EB%BD%91%EA%B8%B0 |
적군 n초마다 생성
다음으로 해야 할 것은 이 적군을 n초만큼 생성하는 것이다.
총알 발사하는 것 처럼 만들어 주면 되는데 적군은 n초마다 생성이 되어야한다.
그렇기 때문에 조금 특별하게 setInterval이라는 함수를 사용할 것이다.
setInterval() - 자바스크립트에서 기본으로 제공하는 함수로 매개변수 2개를 가진다. setInterval(호출할 함수, 초) 첫번째 매개변수에 호출할 함수를 작성하고, 두번째 매개변수에는 호출할 함수를 몇 초마다 부를것인지 초를 작성하면 된다. *자바스크립트에서의 1초는 1000이다. |
//적군 1초 생성
const createEnemy=()=>{
const interval = setInterval(()=>{
let e = new Enemy()
e.init();
},1000)
}
(1초마다 적군을 생성하기 위해 1000 작성)
또한 적군은 웹 페이지가 열리자마자 생성되어야 하기 때문에
이 함수를 아래와 같이 작성해 준다.
loadImage();
setupKeyboardListener();
createEnemy();
main();
적군 화면에 보여주기
아직 적군을 그려주지 않았기 때문에 화면에 보이지는 않을 것이다.
적군을 그려주기 위해 render 함수에 간다.
//이미지 보여주기
const render=()=>{
// 생략 //
for(let i = 0; i<enemyList.length; i++){
ctx.drawImage(enemyImage, enemyList[i].x, enemyList[i].y);
}
}
render 함수에 이렇게 그려주고 실행을 시키면
아래 사진과 같이 적군이 생성되는 것을 볼 수 있다.
하지만, 적군이 아래로 내려오고 있지는 않다.
적군 아래로 내려오기
적군이 내려온다는 뜻은 무엇일까?
바로 y좌표가 증가한다는 뜻이다.
이 y좌표를 증가 시키기 위해
아까 만들어 놓은 Enemy 함수에 추가 코드를 작성한다.
let enemyList = [];
function Enemy(){
this.x = 0;
this.y = 0;
this.init=function(){
this.y = 0;
this.x = generateRandomValue(0, canvas.width-48);
enemyList.push(this);
}
this.update = function(){ // 추가한 코드, 적군이 4px 만큼 내려온다.
this.y += 4;
}
}
그 후에 이 update를 불러주기 위해 update 함수에 코드를 작성해 준다.
const update=()=>{
// 생략 //
for(let i = 0; i < enemyList.length; i++){
enemyList[i].update();
}
}
이렇게 하면 적군이 1초에 4px씩 아래로 내려오는 것을 볼 수 있다.
GameOver 만들기
이 게임의 규칙 상 적군이 바닥에 닿게 되면 게임이 끝나야 한다.
우선 gameOver 변수를 만들어 false 값을 준다.
만약 게임오버가 되면 이 값을 true로 바꿔줄 것이다.
let gameOver = false // true이면 게임이 끝남, false이면 게임이 안 끝남
Enemy 함수로 와서 if문을 작성해 준다.
적군이 4px 씩 내려오다가 캔버스의 바닥에
닿으면 gameOver를 true로 바꿔준다.
let enemyList = [];
function Enemy(){
this.x = 0;
this.y = 0;
this.init=function(){
this.y = 0;
this.x = generateRandomValue(0, canvas.width-48);
enemyList.push(this);
}
this.update = function(){
this.y += 4;
if(this.y >= canvas.height-48){ // 게임오버 변수를 true로 변경
gameOver = true;
}
}
}
그 후 main 함수에 가서 아래와 같은 조건문을 만들어 넣어준다.
gameOver 가 false일때만 3개의 함수가 호출되는 것이다. (true 일때는 호출하지 않는다.)
그리고 만약 gameOver가 false가 아니고 true면 게임오버 이미지를 그려준다.
// 계속 호출해주는 함수 만들기
const main=()=>{
if(gameOver == false){
update();
render();
requestAnimationFrame(main);
}else{
ctx.drawImage(gameOverImage, 10, 100, 400, 380);
}
}
적군이 총에 맞았을 때 제거하기
적군이 총에 맞았다는 의미는
y값 기준으로 총알.y <= 적군.y
x값 기준으로 총알.x >= 적군.x && 총알.x <= 적군.x+48이동시에 만족하는 경우이다.
만약 위와 같은 상황이 되면 적군과 총알은 없어지고 점수가 올라가게 된다.
let bulletList = []; // 총알들을 저장하는 리스트
function Bullet(){
// 생략 //
this.alive = true; // true면 살아있는 총알, false면 죽은 총알
// 생략 //
this.checkHit=function(){
for(let i =0; i < enemyList.length; i++){
if(this.y <= enemyList[i].y && this.x >=enemyList[i].x && this.x <= enemyList[i].x +48){
// 총알과 적군이 사라지고 점수 증가
score++;
this.alive = false;
enemyList[i].splice(i,1);
}
}
}
}
const update=()=>{
// 생략 //
//총알의 y좌표 업데이트하는 함수 호출
for(let i =0; i< bulletList.length; i++){
if(bulletList[i].alive == true){
bulletList[i].update();
bulletList[i].checkHit();
}
}
// 생략 //
}
//이미지 보여주기
const render=()=>{
// 생략 //
for(let i = 0; i< bulletList.length; i++){
if(bulletList[i].alive == true){
ctx.drawImage(bulletImage, bulletList[i].x, bulletList[i].y);
}
}
// 생략 //
}
이렇게만 작성하면 점수는 알 수 없다.
그렇기 때문에 점수를 보여줘야 하는데
점수를 화면에 보여주기 위해 render 함수에
아래와 같은 코드를 작성한다.
const render=()=>{
// 생략 //
ctx.fillText(`Score: ${score}`, 20, 20);
ctx.fillStyle = "white";
ctx.font = "20px Arial";
// 생략 //
}
이렇게 하면 게임 만들기의 모든 과정이 끝나게 된다.
최종 결과
(조금 더 꾸밀 필요가 있을 것 같다...)
https://kangin-lee.github.io/shooting-game/
참고 영상
https://www.youtube.com/watch?v=c-NcYoTshHw