[JS]Ghost Rain 게임 만들기(2)

김zunyange·2023년 2월 1일
0

2023/2/2

DOM EVENT 타입을 배웠다.
이전까지는 계속 봤던 문법들이어서 쉽게 넘어갈 수 있었지만, 처음 보는 속성이어서 다시 복습해야겠다.

style.css 파일에서 hero의 앞모습에만 css를 주었고 뒤,오른쪽,왼쪽 모습에는 아래 코드와 같이 position만 주고 끝나서 다음시간에 속성을 추가하는 줄 알았다.

#hero {
  position: absolute;
  width: 35px;
  height: 54px;
  background: url("./images/hero.png") no-repeat;
  bottom: 0;
  left: 50%; 
  margin-left: -17px; /*큰 차이 없어서 생략 가능 *.
  
#hero.stop {
  background-position: 0px;
}
#hero.right {
  background-position: -105px;
}
#hero.left {
  background-position: -70px;
}

하지만, hero의 방향만 다를 뿐 #hero와 속성이 같기 때문에 저 코드에서 끝난 것이 제대로 끝난 것이며, 이제 자바스크립트 문법을 사용하게 되었다. index.html파일에서 <script> 태그로 4개의 파일을 작성했는데 그것도 뭔지 몰랐으나 HTML 코드와 JavaScript 코드를 연결하는 방법 중 하나인 HTML파일 내부에서 <script> 태그를 사용한 것이었다.

따라서, 이제 용사의 방향을 바꾸기 위해 hero.js파일에서 document 변수(?) 를 사용하여 작성하였다.

const heroElement = document.getElementById("hero");
console.log(heroElement);

heroElement.className = "right";

👉🏻 index.html 을 열어서 개발자 도구에서 보면,
html에 <div id="hero" class="right"></div> 코드를 작성하지 않았는데도 자바스크립트를 통해서 생성됨을 알 수 있다.

하나 연습을 더 하자면, hero.js에 아래 코드를 추가해주면

heroElement.style.left = "30px"; /*숫자+문자 데이터는 없음.문자 데이터 형식으로 써줘야 함*/

이렇게 나오는지 확인해준다. 잘 나왔으면 잘 진행하고 있다는 것 !!


2023/2/3

  1. 이전까지는 혼자 만들 수 있었다.
  2. 모르겠다.
  3. 강의를 한번 더 봤다. 모르겠다
  4. 유투브를 봤다. 더 어렵다
  5. 강의를 한번 더 봤다. 왜 갑자기 난이도 급상승한거지 ??
  6. 차근차근 순서를 적어보려 한다.
  • 용사에 key event를 다는게 아님.
  • 우리가 원하는 건 화면 자체에 EventListener를 달고 용사가 움직이게 하는 것 => 우리가 이벤트를 달고 싶은 요소는 화면 전체!!
  • 따라서 hero.js 가 아니라 공통 코드를 모아놓을만한 init.js 파일을 따로 만들어서 거기에 이벤트를 적어야 한다.
  • 그렇다면 화면 자체에 어떻게 이벤트를 달 수 있을까?
  • 이제까지 document.getElementbyID() 등 이런거로 요소를 접근했다면, 지금은 document.addEventListener() 로 화면 자체에 이벤트를 감지하는 함수를 추가해야 한다.
  • 괄호() 안에는 keydown 을 써줘야할까 keyup 일까? => keydown
  • 왜냐면 빨리빨리 화면이 움직여야 되는 게임이니까 누르는 그 순간부터 용사가 움직여야 해!
  • 그리고 함수에는 keydown을 했을 때 무슨일이 일어나게 할 것인지 작성한다.
  • hero.js에 heroElement를 선언했기 때문에 init.js에는 heroElement를 선언하지 않고 바로 변수를 사용할 수 있는데, index.html 에서 script 태그 작성에는 hero.js가 init.js 보다는 먼저 적어줘야 한다.
<script src="js/settings.js"></script>
<script src="js/ghost.js"></script>
<script src="js/hero.js"></script>
<script src="js/init.js"></script>
//hero.js
const heroElement = document.getElementById("hero");
console.log(heroElement);

//init.js
document.addEventListener("keydown", function () {
  //화면에서 키 누르면 발생할 동작


	heroElement.style.left = "30px"; 

☝🏻keydown event를 발생할 때 마다 function() {heroElement.style.left = "30px";} 함수를 계속 호출하고 있는 것.

여기까지 했을 때 결과는 Enter든지 Space든지 뭘 누르든지 용사는 가운데에서 왼쪽으로 움직여야 성공 !!

이제 아무 key가 아닌 방향키, 거기서도 왼쪽 key오른쪽 key를 알아야 하는데 어떻게 아느냐 하면 ! keydown event 가 발생할 때 브라우저에 event 정보를 넘겨주게 되고 개발자 도구에서 event.keyCode 를 알 수 있다. 혹은 "자바스크립트 키코드", "자바스크립트 키보드 이벤트", "javascript keycode" 등 검색으로도 알 수 있다. 키코드 확인하기

개발자 도구에서Enter를 치면 콘솔창에 아래와 같이 이벤트 정보가 주어진다.

☝🏻Enter의 keycode는 13이라는 뜻!

이런 2가지 방법으로 왼쪽 방향 키 는 37 이고 오른쪽 방향 키는 39임을 알았다.

만약 ‘왼쪽키'를 누르면 left가 0px로, ‘오른쪽키'누르면 left가 800px로 변경되도록 해주세요.

document.addEventListener("keydown", function (e) {
  //화면에서 키 누르면 발생할 동작
  console.log(e.keyCode);
  if (e.keyCode === 37) {
    heroElement.style.left = '0px';
  } else if (e.keyCode === 39) {
    heroElement.style.left = '800px';
  }
});

여기까지 하면, 용사가 왼쪽 방향키 누르면 왼쪽으로, 오른쪽 방향키 누르면 오른쪽 끝으로 간다.

그런데 이때, 용사가 배경이미지를 넘어서 밖으로 나가게 되는데 배경이미지의 가로 길이가 800px 이기 때문이다. (용사의 왼쪽 손을 기준으로) 따라서, 800px 에서 용사의 가로 길이(34px) 만큼 빼주면 배경이미지 안으로 들어오게 된다. heroElement.style.left = '765px';
단, 이전에 생략 가능하다고 했던 margin-left: -17px 를 생략해야 함.

#hero {
  position: absolute;
  width: 35px;
  height: 54px;
  background: url("./images/hero.png") no-repeat;
  bottom: 0;
  left: 50%; 
  margin-left: -17px; //큰 차이 없어서 생략 가능. 정 가운데로 오기 위함.

  • 이제 특정값(0px / 765px)으로 이동하는 것이 아니라 1px 씩 이동시켜야 한다.
  • keydown 을 했을 때, 현재 left 값 (right 값)을 받아서 -1로 줄여줘야 한다.
  • 현재 값을 어떻게 구하는가?
  • heroElment.style.left 값을 console.log로 찍어보자. (if 문은 고정값이니까 주석처리 하고)
document.addEventListener("keydown", function (e) {
  
  console.log('용사의 왼쪽 값: ' heroElement.style.left); 
  // (안나옴)
  /*if (e.keyCode === 37) {
    heroElement.style.left = "0px";
  } else if (e.keyCode === 39) {
    heroElement.style.left = "765px";
  }*/
});

🪄개발자도구 - 왼쪽 방향키 누르기 - 콘솔창 확인

왜 안나올까 ?
inline값이 아니기 때문!
그렇다면, DOM에서 CSS값을 갖고오자 : getComputedStyle()

document.addEventListener("keydown", function (e) {
  
  console.log('용사의 왼쪽 값: ', getComputedStyle(heroElement));
}

아무 keydown을 누르면 띠용! 종류가 엄청 많이 나온다.

이중에서 left 값을 가져오려면
getComputedStyle(heroElement).left

💡 현재값은 400px 라는 것!

  • getComputedStyle(heroElement).left 는 너무 길기 때문에 저장을 해주자
  • const heroLeft = getComputedStyle(heroElement).left
document.addEventListener("keydown", function (e) {
  //화면에서 키 누르면 발생할 동작
  const heroLeft = getComputedStyle(heroElement).left;
  console.log("용사의 왼쪽 값: ", heroLeft);
  if (e.keyCode === 37) {
    //왼쪽키 37
    //heroElement.style.left = "0px";
    console.log("용사의 왼쪽 값 -1: ", heroLeft);
  } else if (e.keyCode === 39) {
    //오른쪽키 39
    //heroElement.style.left = "765px";
  }
});

하지만 문자열+단위 - 숫자 는 불가능함.
'400px' + 1 = NaN
cf) 문자열 + 숫자 = 문자열
'400' + 1 = '4001'
390 + 'px' = '390px'
cf) 문자열 - 숫자 = 숫자
'400' - 1 = '399'
390 - 'px' = NaN

💡px 기준으로 400 과 px를 분리하기
'400px'.split('px')[0] = '400'

document.addEventListener("keydown", function (e) {
  //화면에서 키 누르면 발생할 동작
  const heroLeft = getComputedStyle(heroElement).left;
  console.log("용사의 왼쪽 값: ", heroLeft);
  if (e.keyCode === 37) {
    //왼쪽키 37
    //heroElement.style.left = "0px";

    heroElement.style.left = heroLeft.split("px")[0] - 1
    //heroLeft 값이 400
    //heroElement~ 에 heroLeft~ 값을 대입하겠다는 의미
    //split 는 문자 변수에서 쓸 수 있는데 'px'기준으로 나누고 배열을 만든다.

    console.log("용사의 왼쪽 값 -1: ", heroLeft);
  } else if (e.keyCode === 39) {
    //오른쪽키 39
    //heroElement.style.left = "765px";

    heroElement.style.left = heroLeft.split("px")[0] + 1
  }
});

왼쪽키 누르면 399가 나오지만, 오른쪽키를 누르면 4001 이 나온다.
왜일까?
heroLeft 가 문자열인데, heroLeft.split("px")[0] - 1 이 또 문자열이 나왔기 때문!
Number()로 문자열을 숫자로 바꿔준다.

  document.addEventListener("keydown", function (e) {
  //화면에서 키 누르면 발생할 동작
  const heroLeft = getComputedStyle(heroElement).left;
  console.log("용사의 왼쪽 값: ", heroLeft);

  const heroLeftwithoutPx = Number(heroLeft.split("px")[0]);
  //heroLeft.split("px")[0] <- 문자열이라 숫자로 바꿔줘야 함 : Number()
  console.log("heroLeftWithoutPx =>", heroLeftwithoutPx);

  if (e.keyCode === 37) {
    //heroElement.style.left = heroLeft.split('px')[0] -1
    console.log("용사의 왼쪽 값 -1: ", heroLeftwithoutPx - 1);
  } else if (e.keyCode === 39) {
    //오른쪽키 39
    //heroElement.style.left = heroLeft.split('px')[0] + 1

    console.log("용사의 왼쪽 값 +1: ", heroLeftwithoutPx + 1);
  }
});

🥳 성공 !!

확인을 했으니 주석을 풀고, 변수를 바꿨었으니 바뀐 변수를 다시 넣어준다.

if (e.keyCode === 37) {
    heroElement.style.left = heroLeftwithoutPx - 1;

    console.log("용사의 왼쪽 값 -1: ", heroLeftwithoutPx - 1);
} else if (e.keyCode === 39) {
    heroElement.style.left = heroLeftwithoutPx + 1;

    console.log("용사의 왼쪽 값 +1: ", heroLeftwithoutPx + 1);
}

그리고 left 는 언제나 단위와 함께 써줘야해서 숫자에다가 문자열 'px'를 추가한다.

document.addEventListener("keydown", function (e) {
  //화면에서 키 누르면 발생할 동작
  const heroLeft = getComputedStyle(heroElement).left;
  console.log("용사의 왼쪽 값: ", heroLeft);

  const heroLeftwithoutPx = Number(heroLeft.split("px")[0]);
  //heroLeft.split("px")[0] <- 문자열이라 숫자로 바꿔줘야 함 : Number()
  console.log("heroLeftWithoutPx =>", heroLeftwithoutPx);

  if (e.keyCode === 37) {
    heroElement.style.left = heroLeftwithoutPx - 1 + 'px';

    console.log("용사의 왼쪽 값 -1: ", heroLeftwithoutPx - 1);
  } else if (e.keyCode === 39) {
    heroElement.style.left = heroLeftwithoutPx + 1 + 'px';

    console.log("용사의 왼쪽 값 +1: ", heroLeftwithoutPx + 1);
  }
});

이제 용사가 방향키에 따라 움직이게 된다!!
1px 은 너무 미세하니 10px로 바꿔주자


다시 복습 ❗️

getComputedStyle 을 왜썼지?
hero.style.left 에서 갖고온 값 heroElement.style.left 을 사용하고 싶었는데 아직 inline에 존재하지 않기 때문에 최초에 <div id="hero"><div> 에서 style이 존재하지 않았다.
그렇다면 getComputedStyle 을 사용하지 않으려면?
1. style.css에서 #hero {left: 50} 을 삭제하고,
2. index.html에서 <div id="hero" style="left: 400px"><div> 로 style을 추가하고
3. init.js에서 const heroLeft = getComputedStyle(heroElement).left;
-> const heroLeft = heroElement.style.left; 로 바꾼다.

profile
배움은 즐거워 ~(*ૂ❛ᴗ❛*ૂ)

0개의 댓글