간단한 웹게임 만들기 - javascript(유령)

wldls·2022년 11월 5일
0

javascript

목록 보기
10/33

Random 수를 반환하여 랜덤한 유령 위치

유령 위치를 랜덤하게 시작하게 할수 있게 한다
유령은 여러마리 생성해야 하므로 코드의 재활용이 필요하다
유령의 위치는 컴퓨터가 랜덤한 수를 계산하고
그 값을 유령의 left 값으로 지정한다

먼저 유령을 랜덤하게 나오는 법을 알아보자

범위를 지정한 난수 생성하기

Math.random() 함수는 0 이상 1 미만의 구간에서 근사적으로 균일한(approximately uniform) 부동소숫점 의사난수를 반환한다
하지만 소수점 숫자를 랜덤하게 나오게만 하는게 아니다
이 값으로 사용자가 원하는 범위로 변형해보자

Math.floor(Math.random() * 100);

0~99 범위의 정수 난수를 생성하려면

Math.random() 함수의 결과에 100을 곱해주고, 소수점 이하를 버림합니다

출처:https://hianna.tistory.com/454

이제 위의 함수를 적용하여 bg 범위 안에서 정수 난수를 생성해보자
bg 범위 안에서만 유령을 랜덤하게 위치 시키려면
우선 정확한 값을 알아야한다
bg 의 width는 800px, 유령의 width는 45px 이다
두 값을 마이너스 해보면 755px이 나온다

Math.floor(Math.random() * 755);  

755 를 곱하면 0~755 사이의 난수가 랜덤으로 생성된다

이제 재사용이 가능하게 유령 위치 난수 함수를 만들어
유령이 어떻게 나오는지 살펴보자

// 유령의 left 위치값
  let randomLeft = randomNum();
  ghostElement.style.left = randomLeft + "px";
  
// 유령 랜덤 함수
function randomNum() {
  let randomLeftDown755 = Math.floor(Math.random() * 755);

  return randomLeftDown755;
}

left의 위치값 이전에 랜덤 함수를 호출하여
0~755사이의 난수를 변수에 담아 유령의 position : left 값에 할당한다


새로고침 할 때마다 유령의 left 값이 랜덤하게 나오는 모습이다
이렇듯 return이 필요한 이유는 함수내의 값을 함수 바깥으로 꺼내
다른 함수 내에서도 적용 시킬 수 있는 점이다

여기서 크기가 다른 배경으로 바꿔보고 싶다하면
코드를 하나하나 수정 하는게 아니라(하드코딩❌)
인자를 받아서 반환하는 함수로 바꿔보자
코드안에 숫자가 있는 것은 그렇게 좋지 않은 코드이다

// 유령의 left 위치값
let randomLeft = randomRange(0, BG_WIDTH - GHOST_WIDTH);
ghostElement.style.left = randomLeft + "px";

// 유령 랜덤 함수
function randomRange(min, max) {
 return Math.floor(Math.random() * (max + 1 - min)) + min;
}

유령의 위치값의 정해진 범위는
0부터 bg width 변수 - 유령 width 변수로 넣으면
어떠한 크기의 이미지든 최소,최대 값이 정해진 범위내에서
유령이 움직이게 된다

유령비 내리기

유령비를 내리기 위해선 다음과 같은 조건이 반복되야 한다

  • 유령의 현재 top 위치를 가져온다
  • 현재보다 +1 / +10(빠르게)을 추가하여 top을 다시 할당한다
  • 배경보다 넘어가면 움직이지 않도록 멈춘다

여기서 사용할 setInterval() 함수를 알아보자

setInterval()메서드 는
정해진 주기마다 특정 함수를 반복적으로 호출하거나 코드 조각을 실행한다
(ex - 휴대폰 인증번호를 입력할 때 제한 시간)

참고 : https://www.w3schools.com/jsref/met_win_setinterval.asp

  // 유령비 내리기 함수
 setInterval(function () {
    let ghostTopNum = Number(ghostElement.style.top.split("px")[0]) + 10;
    
    if (ghostTopNum > BG_HEIGHT - GHOST_HEIGHT) {
      return;
    }
      ghostElement.style.top = ghostTopNum + "px";
    }, 100);

ghostElement.style.top로 유령의 top값에 접근한다
.split로 "px"를 기준으로 제외한뒤 새로 생성된 배열의 0번째 인
숫자 값을 ghostTopNum 변수에 할당한다 (+ 10px씩 유령이 top값이 이동이게 함)
if문으로 유령의 움직임 범위 조건을 설정하는데
유령의 현재 top 값의 숫자만을 가지고 있는 변수 ghostTopNum가
bg width - 유령 width를 뺀 값보다 커질 때 멈추게 한다
그리고 "px"를 붙여 현재 유령의 top 에 할당한다
(숫자열에는 바로 문자열 붙일수 있다)

여기까지 완성 화면을 확인해보자

다수의 유령 내리고 일정 범위에서 삭제

유령이 하늘에서 주기적으로 생성되어야 하므로 setInterval을 사용한다

setInterval(createGhost, 3000);

setInterval로 유령 생성 함수를 3초후에 생성한다

유령이 3초후에 생성 되지만 사라지지 않는다
다음 if 조건문을 살펴보면 배경을 넘어가지 않게 멈춤에서 리턴된다
멈추면 삭제해야 된다

 setInterval(function () {
    let ghostTopNum = Number(ghostElement.style.top.split("px")[0]) + 10;
    
    if (ghostTopNum > BG_HEIGHT - GHOST_HEIGHT) {
     	ghostElement.remove(); // 추가
      return;
    }
      ghostElement.style.top = ghostTopNum + "px";
    }, 100);

유령이 배경을 넘어가기전에 리턴 하는것 이전에
유령 엘리먼트를 제거하는 코드를 추가하였다
이로써 넘어가기전에 유령 엘리먼트를 제거하고 리턴 하는 것으로 구현 되었다

유령과 용사가 마주친다면?

유령과 용사가 마주친다면 유령이 죽어 사라지는 모습을 구현해보자

먼저
유령과 용사가 접촉 하는 위치를 알아야 하기 때문에
유령과 용사의 top(y축) , left(x축) 지점을 찾아야 한다

let ghostLeftNum = Number(ghostElement.style.left.split("px")[0]);

위의 코드처럼 현재 유령의 왼쪽 값을 splite으로 "px"기준,
새 배열을 생성하여 [0]번째 인덱스 숫자를 왼쪽의 ghostLeftNum으로 할당 하는 식으로 유령과 용사 각 top 과 left 지점을 찾았다

유령과 용사가 접촉하는 그 순간의 유령 top 위치는 어떻게 구할것인가?
해당 조건을 살펴보자

 if (ghostTopNum > BG_HEIGHT(배경높이) - (GHOST_HEIGHT(유령높이) + HERO_HEIGHT(영웅높이)))

배경 전체 높이에서 유령과 영웅을 더한 값을 뺀 값이
영웅과 유령이 접촉하는 그 순간의 유령 top 값 이다
그 top 값보다 ghostTopNum 즉,현재 유령 top 값이 더 커질때(나아갈 때)..

위의 조건이 true 일 때 아래 중첩 if문 계속 👇

if (ghostLeftNum < heroLeftNum + HERO_WIDTH &&
    heroLeftNum < ghostLeftNum + GHOST_WIDTH) 

위의 구한 top 이 접촉한 순간 -> 용사와 유령의 left 가 겹치는지 확인하는 조건문이 실행된다

유령은 left가 고정된 상태로 top만 줄어들고
용사의 left가 계속 움직이므로 용사의 left 기준으로
현재 겹치는지 확인 할 수 있다

위의 중첩 if문 조건이 모두 충족 되면
killGhost 함수를 실행한다
죽은 유령의 내용을 담고 있는 killGhost 함수는
image Sprite 이미지인 position값을 죽은 유령 이미지의 위치 값으로 할당하고,
setTimeout() 함수로써 콜백함수로 0.5초 뒤에 ghostElement가 삭제되는 코드를 설정하였다

{
	killGhost(ghostElement);
	return;
 }
 
 
function killGhost(ghostElement) {
  ghostElement.style.backgroundPosition = "-45px";

  setTimeout(function () {
    ghostElement.remove();
  }, 500);

이로써 용사와 유령의 top, left 위치가 겹치면
유령의 엘리먼트가 사라지게 되는 모습을 확인할 수 있다

배운대로 함수는 한번 만들면 호출만으로 재사용이 편리하다구나 ! 🥰 여기에 scope 개념, 지역변수/전역변수 의 범위 대해 좀 더 이해 하는것에 대해 나에게 꼭 필요한 시간이었다
엘리먼트 들에게 조건을 걸어 실제 화면을 컨트롤 할 수 있다는 점이
신기하고 또 어렵기도 했으며 결과로 도출 하기까지 생각해야 될 것이 많다고 느꼈다 🥲

profile
다양한 변화와 도전하는 자세로

0개의 댓글