참고 영상 : https://youtu.be/c-NcYoTshHw (코딩알려주는누나)
점수 계산하기
1. 총알이 적군에 닿으면 총알과 우주선이 없어짐
2. 총알이미지가 적군이미지에 닿으면 점수+1
:총알.y <= 적군y && (총알.x >= 적군.x && 총알.x <= 적군.width)
(총알의 y좌표가 적군의 y값보다 같거나 작아지면)
&& (총알의 x좌표가 적군의 x좌표보다 같거나 크고 && 총알의 x좌표가 적군의 width보다 같거나 작으면)
1-1. checkHit()함수 생성
let bulletList = [];
function Bullet() {
this.x = 0;
this.y = 0;
this.init = function () {
this.x = spaceshipX + 20;
this.y = spaceshipY;
bulletList.push(this);
};
this.update = function () {
this.y -= 7;
};
//총알이 적군과 닿으면 처리할 내용
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 + 40
) {
}//if
}//for
}; //checkHit()
}
1-1. 총알이 적군에 닿이면 점수증가
score++
: 점수증가let score = 0;
let bulletList = [];
function Bullet() {
this.x = 0;
this.y = 0;
this.init = function () {
this.x = spaceshipX + 20;
this.y = spaceshipY;
bulletList.push(this);
};
this.update = function () {
this.y -= 7;
};
//총알이 적군과 닿으면 처리할 내용
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 + 40
) {
//점수추가
score++;
}
}
};
}
1-2. 총알이 적군에 닿이면 총알의 상태를 false
this.init()
에 this.alive = true;
추가 : 총알이 닿이면 false로 바꿈let score = 0;
let bulletList = [];
function Bullet() {
this.x = 0;
this.y = 0;
this.init = function () {
this.x = spaceshipX + 20;
this.y = spaceshipY;
this.alive = true; // 적군과 닿이면 false
bulletList.push(this);
};
this.update = function () {
this.y -= 7;
};
//총알이 적군과 닿으면 처리할 내용
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 + 40
) {
//점수추가
score++;
// 적군과 닿으면 false로 바꿔줌
this.alive = false;
}
}
};
}
1-3. 총알이 적군에 닿이면 총알 이미지가 사라짐
function render() {
ctx.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);
ctx.drawImage(mainImage, spaceshipX, spaceshipY, 64, 64);
// ctx.fillText(`Score:${score}`, 20, 20);
// ctx.fillStyle = "white";
// ctx.font = "20px Arial";
//bulletLIst[i].alive가 true일때만 총알이미지 보여주기
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-4. 총알이 적군에 닿이면 적군이 없어짐
enemyList.splice(i, 1);
: i번째 요소 1개를 삭제let bulletList = [];
function Bullet() {
this.x = 0;
this.y = 0;
this.init = function () {
this.x = spaceshipX + 20;
this.y = spaceshipY;
this.alive = true; // 적군과 닿이면 false
bulletList.push(this);
};
this.update = function () {
this.y -= 7;
};
//총알이 적군과 닿으면 처리할 내용
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 + 40
) {
//점수추가
score++;
// 적군과 닿으면 false로 바꿔줌
this.alive = false;
// 우주선 없애기
enemyList.splice(i, 1);
}
}
};
}
1-5. checkHit()함수 호출
y좌표 업데이트
하면서 checkHit()적군과 닿으면 점수추가/alive=false/우주선삭제
해줌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++) {
bulletList[i].update();
bulletList[i].checkHit();
}
-> 총알 1개에 적군 2개가 사라짐
1-6. bulletList[i].alive=true일때만 update()되도록 수정
if (bulletList[i].alive)
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-1. 점수판 생성
fillText(넣어줄 텍스트, x좌표, y좌표)
fillStyle = 색깔
font
function render() {
ctx.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);
ctx.drawImage(mainImage, spaceshipX, spaceshipY, 64, 64);
ctx.fillText(`Score:${score}`, 20, 20);
ctx.fillStyle = "white";
ctx.font = "20px Arial";
//bulletLIst[i].alive가 true일때만 총알이미지 보여주기
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. Canvas 세팅
let canvas;
let ctx;
canvas = document.createElement("canvas");
ctx = canvas.getContext("2d");
canvas.width = 400;
canvas.height = 700;
document.body.appendChild(canvas);
// 2. image 가져오기
let backgroundImage, mainImage, bulletImage, enemyImage, gameOverImage;
let gameOver = false; // false는 게임진행중, true는 게임이 끝남 (우주선이 바닥에 닿으면 끝)
let score = 0;
//주인공 좌표
let spaceshipX = canvas.width / 2 - 32;
let spaceshipY = canvas.height - 64;
let bulletList = [];
function Bullet() {
this.x = 0;
this.y = 0;
this.init = function () {
this.x = spaceshipX + 20;
this.y = spaceshipY;
this.alive = true; // 적군과 닿이면 false
bulletList.push(this);
};
this.update = function () {
this.y -= 7;
};
//총알이 적군과 닿으면 처리할 내용
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 + 40
) {
//점수추가
score++;
// 적군과 닿으면 false로 바꿔줌
this.alive = false;
// 우주선 없애기
enemyList.splice(i, 1);
}
}
};
}
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);
};
//적군의 y좌표 변경
this.update = function () {
this.y += 3;
if (this.y >= canvas.height - 40) {
gameOver = true;
//console.log("Game Over");
}
};
}
function loadImage() {
backgroundImage = new Image();
backgroundImage.src = "images/background.jpg";
mainImage = new Image();
mainImage.src = "images/main.png";
bulletImage = new Image();
bulletImage.src = "images/bullet.png";
enemyImage = new Image();
enemyImage.src = "images/enemy.png";
gameOverImage = new Image();
gameOverImage.src = "images/gameover.jpg";
}
//방향키 누르면
let keysDown = {};
function setupKeyboardListener() {
document.addEventListener("keydown", function (event) {
//console.log("무슨 키가 눌렸어?", event.keyCode);
keysDown[event.keyCode] = true;
//console.log("KeysDown =", keysDown);
});
document.addEventListener("keyup", function (event) {
delete keysDown[event.keyCode];
//console.log("버튼 클릭 후 = ", keysDown);
if (event.keyCode == 32) {
//32 : spacebar
createBullet(); //총알 생성
}
});
}
function createBullet() {
//console.log("총알 생성");
let b = new Bullet(); // 총알 1개 생성
b.init();
console.log("총알 리스트 : ", bulletList);
}
function createEnemy() {
const interval = setInterval(function () {
let e = new Enemy();
e.init();
}, 1000);
}
// 우주선의 xy좌표가 바뀌고
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();
}
}
function render() {
ctx.drawImage(backgroundImage, 0, 0, canvas.width, canvas.height);
ctx.drawImage(mainImage, spaceshipX, spaceshipY, 64, 64);
ctx.fillText(`Score:${score}`, 20, 20);
ctx.fillStyle = "white";
ctx.font = "20px Arial";
//bulletLIst[i].alive가 true일때만 총알이미지 보여주기
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);
}
}
function main() {
if (!gameOver) {
update(); // 좌표값 업데이트
render(); //그려주기
requestAnimationFrame(main);
//console.log("anmiation calls");
} else {
ctx.drawImage(gameOverImage, 10, 100, 380, 380);
}
}
loadImage();
setupKeyboardListener();
createEnemy();
main();
1. 코드 정리
checkHit()
: 총알이미지가 적군이미지와 겹치면 / score++ / alive=false / enemyList.splice(i,1)2. 지금까지 배운 배열, 반복문, 함수를 이용해서 실제로 작동시킬 수 있는 프로그램을 만들어 흥미로웠다.
3. 깃허브로 게임 배포 : https://apebstr.github.io/
4. 아래 내용 추가하기 !!! !
❗추가하기
- 총알 y좌표 max값 설정(캔버스 밖에서 적군 잡지 않도록)
- gameover 이미지 수정
- 조작버튼 만들기 (키보드 또는 마우스로 할 수 있도록)
- 닷홈 또는 깃허브로 사이트 배포