WWECODE 과정중에서 처음으로 개인 프로젝트를 해봤다.
솔직히 기본적인 파일셋이나 이미지는 WECODE 에서 제공하는
GIT REPOSITORY 에서 CLONE 으로 받아왔기 때문에
내가 특별히 한 것이라고는 JS 코딩밖에 없다.
필요 조건
Hero
클래스와Ghost
클래스를 이용할 것Ghost
클래스의 객체는#bg
의 최상단 , 영역 내 무작위 X축에서 등장.Ghost
클래스의 객체는 일정 주기마다 생성됨.Ghost
클래스의 모든 객체는 생성된 지점에서 시간이 지날수록 내려옴.Hero
클래스의 객체와Ghost
클래스의 객체가 부딫히면 1점을 얻고
Ghost
클래스의 객체는 동시에 사망처리.Hero
클래스의 객체와Ghost
클래스의 객체가 부딫히지 않고,
Ghost
클래스의 객체가#bg
최하단에 닿는다면 점수발생 없이 사망처리.
추가한 조건
START
버튼을 누르면 게임이 시작되며 버튼이 비활성화됨.
// init.js
const bg = document.querySelector("#bg");
const start = document.querySelector("#start");
const superMan = new Hero("hero");
// START 를 누르면 시작 버튼이 비활성화 되며 게임 시작.
start.addEventListener("click", () => {
document.querySelector("#score").innerHTML = 0;
start.disabled = true;
start.style.backgroundColor = "gray";
start.style.color = "black";
start.innerHTML = "RUNNING";
// Hero Class의 객체를 통해 해당 클래스의 Method를 호출하여 클래스객체를 움직임.
window.addEventListener("keydown", function (e) {
if (e.key == "a") {
superMan.moveHeroLeft();
}
if (e.key == "d") {
superMan.moveHeroRight();
}
if (e.key == "w") {
superMan.HeroTop();
}
if (e.key == "s") {
superMan.HeroBottom();
}
});
// 게임이 시작되자마자 첫번째 유령이 생성
new Ghost("ghost");
// 이후 5초마다 지속적으로 유령이 생성됨.
const game = setInterval(() => {
new Ghost("ghost");
}, 5000);
});
//enemy.js
let killCount = 0;
class Ghost {
constructor(id) {
this.id = id;
this.randomX = Math.ceil(Math.random() * 740);
this.topXPosition = this.randomX;
// Ghost Class 객체가 선언되며 생성자가 동작하면 동시에 ghost가등장.
this.createGhost();
// 생성된 ghost는 setInterval로 인해 지속적으로 아래로 내려감.
this.Raining(superMan);
}
// 생성한 Ghost객체의 정보를 받아서 게임의 스테이지인 #bg에 append하는 함수.
createGhost() {
this.div = document.createElement("div");
this.div.className = this.id;
this.div.style.left = this.topXPosition + "px";
bg.appendChild(this.div);
}
// ghost가 죽고나서 일정시간이 지나면 삭제하는 함수.
cleaning() {
setTimeout(() => (this.div.style.display = "none"), 1200);
}
// ghost가 지속적으로 떨어지게 만드는 함수
// setinterval이 동작하며 반복적으로 각 객체의 top Value를 수정 , 적용한다.
// ghost 와 hero 의 픽셀이 곂치게되면 (첫번째 if문의 조건),
// ghost의 background-position을 dead기준으로 변경하고
// Raining setInterval을 종료한다.
Raining(heroName) {
this.raining = 0;
const intervalY = setInterval(() => {
this.raining += 30;
this.div.style.top = this.raining + "px";
if (
this.raining > 475 &&
this.topXPosition <= heroName.moveLeft + 35 &&
this.topXPosition >= heroName.moveLeft - 35
) {
this.div.style.backgroundPosition = "-45px";
clearInterval(intervalY);
killCount++;
document.querySelector("#score").innerHTML = killCount;
this.cleaning();
} else if (this.raining > 510) {
this.div.style.backgroundPosition = "-45px";
clearInterval(intervalY);
this.cleaning();
}
}, 500);
}
}
// hero.js
class Hero {
constructor(name) {
this.zeroPoint = 382.5;
this.moveLeft = this.zeroPoint;
this.name = name;
this.faceup = -35;
this.facedown = 0;
this.faceleft = -70;
this.faceright = -105;
// Hero Class 객체가 선언되며 생성자가 동작하면 동시에 Hero가 등장.
this.createHero();
}
// 생성한 Hero객체의 정보를 받아서 게임의 스테이지인 #bg에 append하는 함수.
createHero() {
this.hero = document.createElement("div");
this.hero.className = this.name;
this.hero.style.left = this.zeroPoint + "px";
bg.appendChild(this.hero);
}
// A를 누르면 왼쪽으로 10px 움직이며 캐릭터가 왼쪽으로 회전.
// 부모 요소인 #bg와의 좌측 거리가 0이되면 (left : 0px;) 조건 미달성으로
// 캐릭터의 방향만 변경되고 더이상 왼쪽으로 움직이지 않음.
moveHeroLeft() {
this.hero.style.backgroundPosition = this.faceleft + "px";
if (this.moveLeft > 0) {
this.moveLeft -= 10;
this.hero.style.backgroundPosition = this.faceleft + "px";
this.hero.style.left = this.moveLeft + "px";
}
}
// D를 누르면 오른쪽으로 10px 움직이며 캐릭터가 오른쪽으로 회전.
// 부모 요소인 #bg와의 우측 거리가 0이되면 (left : (800 - 45)px;) 조건 미달성으로
// 캐릭터의 방향만 변경되고 더이상 오른쪽으로 움직이지 않음.
moveHeroRight() {
this.hero.style.backgroundPosition = this.faceright + "px";
if (this.moveLeft < 755) {
this.moveLeft += 10;
this.hero.style.backgroundPosition = this.faceright + "px";
this.hero.style.left = this.moveLeft + "px";
}
}
// 위 아래 움직임은 구현하지 않았음
// W를 누르면 캐릭터가 위쪽을 바라봄.
HeroTop() {
this.hero.style.backgroundPosition = this.faceup + "px";
}
// 위 아래 움직임은 구현하지 않았음
// S를 누르면 캐릭터가 아래쪽을 바라봄.
HeroBottom() {
this.hero.style.backgroundPosition = this.facedown + "px";
}
}
이번 프로젝트로 새롭게 알게된 사실을 정리해보자
사실 대부분의 웹사이트 이미지는 이미지를 불러오는 로딩시간을 단축하기 위해서
여러가지 이미지가 하나의 파일로 되어있는 상태로 사용한다.
그리고 해당 이미지의 크기는 부모 div
의 크기로 조절하며
사용하고자 하는 이미지의 위치는 background-position
으로 조절한다.
class
의 생성자에 내부 함수를 this.method
의 형태로 삽입하여
객체 생성과 동시에 함수를 실행시키는것이 가능하다.
setInterval
함수와 setTimeOut
함수를 사용해 봤다.
내가 사용한 방법, 목적은 아주 단순하고 사용중에 있음에도 함수의 처리방식과 작동원리를 제대로 알지 못했다. 프로젝트 이후에 다시 곰곰히 이해해 봐야겠다.
참고 - https://ko.javascript.info/settimeout-setinterval
처음으로 나의 깃허브 저장소가 아닌 다른 저장소에서 CLONE
을 통해
파일을 복사했다. 앞으로 깃을 자주 사용해서 점차 사용이 자연스러워지길
기대해본다.
GIT HUB - https://github.com/pmb087/Enemy_Rain
HOSTING GAME - https://pmb087.github.io/Enemy_Rain/