위코드 1주차 선택형 과제로 Vanilla JS를 활용해 Enemy Rain이라는 게임을 만들어 보는 과제를 주셨다.
게임의 내용은 간단하다. 하단에 용사는 좌,우로 움직일 수 있고 상단엔 랜덤 위치에 유령이 생성된 뒤 점점 내려오며 용사와 유령이 부딪히면 유령이 죽는 게임이다.
Github 링크
게임 링크
실행시 초기 화면은 위 처럼 중앙에 용사 캐릭터가 있고, START 버튼이 있다.
START 버튼을 누르면 유령이 랜덤 위치에서 생성 된 후 내려오기 시작한다.
const hero = document.querySelector("#hero");
let heroLocation = 383;
hero.style.marginLeft = `${heroLocation}px`;
function heroMove(e) {
switch (e.keyCode){
case 37:
moveToHero("left");
break;
case 39:
moveToHero("right");
break;
default:
break;
}
}
function heroStop() {
hero.className = "hero";
}
function moveToHero(move) {
if(move === "left"){
hero.className = "hero-left"
heroLocate(-10);
}else if(move === "right"){
hero.className = "hero-right"
heroLocate(10);
}
}
function heroLocate(move) {
if(heroLocation > 5){
if(move < 0){
heroLocation += move;
hero.style.marginLeft = `${heroLocation}px`;
}
}
if(heroLocation < 760){
if(move > 0){
heroLocation += move;
hero.style.marginLeft = `${heroLocation}px`;
}
}
}
window.addEventListener("keydown",heroMove);
window.addEventListener("keyup",heroStop);
용사를 hero
변수에 담고 위치를 marginLeft
로 조정해 나갔다. 키 입력은 addEventListener
를 이용해 좌, 우 방향키를 읽어 방향키에 따라 className을 부여해 css를 통한 용사의 이미지 변환을 진행하며 marginLeft
값을 조정해 용사의 위치를 변경 했다.
용사 이미지는 상단처럼 하나의 이미지를 잘라서 이용했다.
이렇게 하나의 이미지를 잘라서 보여주는 이유는 실시간으로 변하는 이미지가 다른 파일인 경우, 이미지가 깜빡이는 경우가 생겨 이미지 하나를 잘라서 사용한다.
#hero {
position: absolute;
width: 35px;
height: 54px;
bottom : 0;
}
.hero {
background-image: url("images/hero.png");
}
.hero-left {
background-image: url("images/hero.png");
background-position: right -35px bottom 0px;
}
.hero-right {
background-image: url("images/hero.png");
background-position: right 0px;
}
css background-position
속성을 사용하면 이미지 내에서 원하는 부분의 이미지로 교체해서 사용 가능하다. 상단과 같은 방식으로 방향키 이벤트가 들어오면 className을 변경해 이미지를 교체하는 형식으로 구현 했다.
function ghostAdd(){
const ghostNum = Math.floor(Math.random()*10000);
const ghost = document.createElement("div");
ghost.className = "ghost";
ghost.classList.add(ghostNum);
bg.appendChild(ghost);
ghostNumbering(ghostNum);
}
function ghostNumbering(num) {
const ghostAcount = document.getElementsByClassName(num)[0];
ghostMove(ghostAcount);
}
Math.random()
과 createElement
를 사용해 새로운 Element를 만들고 ghost
와 랜덤한 번호를 각각의 할당해 준다.
function ghostMove(account){
let die = 0;
let yValue = 0;
const xValue = Math.floor(Math.random()*750);
account.style.marginLeft = `${xValue}px`;
function ghostDown(){
yValue += 10;
account.style.marginTop = `${yValue}px`;
if(yValue > 545){
account.remove();
}
if(yValue > 500 && xValue-heroLocation > -25 && xValue-heroLocation < 25 || die === 1){
account.className = "die"
yValue -= 10;
die = 1;
setTimeout(() => account.remove(),1000);
}
}
setInterval(ghostDown,50);
}
유령이 생성되면 초기값으로 die
와 위치값을 할당할 yValue
를 0으로 선언한다.
그 후 Math.random()
과 marginLeft
를 이용해 x 좌표를 구현하고 setInterval
을 이용해 50ms 마다 ghostDown
함수가 실행되도록 했다.
ghostDown
함수는 실행시마다 marginTop
을 10씩 증가 시키고 화면 끝까지 내려올 경우 삭제, 용사와 좌표 값이 일치한 경우 clssName을 die
로 변경해 이미지를 바꿔 준뒤, 1초 뒤 사라지게 구현했다.
처음 과제를 주실때 클래스를 이용해 만들어 보지만, 아직 미숙할 경우 함수를 이용해 게임을 만들어도 된다고 하셨다.
나는 아직 클래스에 대한 개념이 확실하지 않아 함수로 만들었지만, 게임을 거의 완성했을 때 즈음 클래스로 변경하는것도 어렵지 않겠다고 생각이 들었다.
내가 아직 자바스크립트를 잘 알지 못해 이미지를margin
값을 이용해 x, y 좌표를 구현했는데 다른 방법이 있을 것이다.
나중에 클래스로 다시 구현해보면서margin
을 주는 방식이 아닌 다른 방식으로도 구현해볼 예정이다.