수업

[드림코딩 : browser101] 게임 만들기 실전 1 🍝

Po_tta_tt0 2021. 10. 24. 12:54
반응형

HTML

일단 게임 화면이 보이는 창과

시작 버튼.

시간 버튼.

남은 당근의 개수

가 필요할 것이다.

 

HTML

    <div class="game">

        <button class="game__startBtn">

            <i class="fas fa-play"></i>

        </button>

        <h2 class="game__time">0:10</h2>

        <h1 class="game__numOfCarrots">10</h1>

    </div>

 

 

+

.game 안에 bug와 carrot이 나올 공간 박스를 마련해주었다(<h1> 아래 삽입)

        <div class="pop">

            <img src="img/bug.png" alt="">

            <img src="img/carrot.png" alt="">

        </div>

 

 

 

CSS

  background-position: center;

  background-size: cover;

  background-repeat: no-repeat;

이렇게 하나하나 쓸 필요 없다

background: url(img/background.png) center/cover no-repeat;

background를 이렇게 편하게 모아서 쓸 수 있다.

 

편의를 위해 ground에 background color을 주고 진행했다.

 

 

JS

해야 할 일

1. 시작 버튼

- 버튼을 누르면 버튼의 모양이 바뀐다

- 버튼을 누르면 시간이 줄어든다

- 버튼을 누르면 벌레와 당근이 무작위로 10개씩 생성된다

 

2. 벌레와 당근  

- 벌레를 누르면 실패했다는 알람이 뜬다

- 당근을 누르면 당근의 개수가 줄어드는 것이 표시된다

- 제한 시간 내에 당근을 다 누르면 성공했다는 알람이 뜬다

 

3. 제한시간

- 제한시간이 지나면 실패했다는 알람이 뜬다

 

 

 

1-1

처음에는 toggle btn으로 만들려고 했는데 css변경만 가능하다는 것을 깨닫고 방법을 변경했다.

function changeShape(){

    if(startBtn.innerHTML === play){

        startBtn.innerHTML = `${stop}`

    }else if (startBtn.innerHTML === stop){

        startBtn.innerHTML = `${play}`

    }

}

changeShape();

 

1-2

setGameTime을 만들어서 시간을 10초로 설정하고

1초마다 1씩 줄어들게 만들기로 했다.

..

class로 선언해야 하나 고민하다가 문제를 해결했다.

 

// - 버튼을 누르면 시간이 줄어든다

function setGameTime(){

    gameTime.innerHTML=`0:${timeLeft}`

    timeLeft--

    if(timeLeft === -1 ){

        console.log('게임 끝')

        clearInterval(intervalTime)

    }

}

    const intervalTime = setInterval(setGameTime, 1000)

    intervalTime

하지만.. button을 클릭했을 때 interval이 실행되게는 하지 못하고 있다.

setInterval에 대한 기본적인 이해가 부족하다.

위의 방법처럼 intervalTime을 const로 정의하는 것이 아니라 function에 넣는 것이 더 좋을 것이다.

 

+

따라서

let timer = false;

를 정의해두고

// - 버튼을 누르면 시간이 줄어든다

function gameTimer() {

  let time = gameSecond;

  timer = setInterval(() => {

    timeRemaining(time);

    if (time <= 0) {

      popupInfo.innerHTML = "Return😢";

      changeShape();

      popupBox();

      clearInterval(timer);

      return;

    }

    time--;

  }, 1000);

}

// - 시간을 화면에 출력하는 함수

function timeRemaining(time) {

  const minute = Math.floor(time / 60);

  const second = time % 60;

  gameTime.innerHTML = `${minute}:${second}`;

}

function stopTimer() {

  clearInterval(timer);

}

이렇게 만들었다

 

이 과정에서 배운 것

1.

timer(이후 setInterval이 될 것)을 false로 등록한 후 

setInterval이 들어있는 함수를 실행시키면 이 timer에 setInterval의 내용이 들어가는 식으로 setInterval을 이용할 수 있다

=> setInterval을 평소에는 이용하지 않고 있다가 function이 실행되면 timer가 setInterval로 바뀌면서 즉시 setInterval이 실행된다

2.

clearInterval()는 setInterval이 들어있는 function 밖에서도 실행 가능하다

 

 

 

 

1-3

이 부분부터 하기로 했다

// - 버튼을 누르면 벌레와 당근이 무작위로 10개씩 생성된다

const ground = document.querySelector('.pop');

function randomItem(){

    console.dir(ground)

    console.log(ground.offsetHeight)

    console.log(ground.offsetWidth)

    console.log(Math.random());

}

일단 넓이와 높이를 정하고 random을 이용해 넓이 안에 있는random값과 높이 안에 있는 random값을 위치로 주면 될 것 같다.

 

아무래도 모르겠어서 힌트를 받았다.

function addItem (className, count, imgPath){

   

}

이렇게 className과 개수, img의 경로를 주는 함수를 하나 더 만드는 것이다.

 

 

function addItem (className, count, imgPath, size){

    const width = groundRect.width

    const height = groundRect.height;

    for(let i = 0 ; i < count ; i++){

        const item = document.createElement('img');

        item.src=imgPath

        item.setAttribute('class', className)

        ground.appendChild(item)

        const x = Math.floor(Math.random()*width)

        const y = Math.floor(Math.random()*height)

        console.dir(item)

        item.style.left = `${x}px`

        item.style.top = `${y}px`

        console.log(x, y)

    }

    console.log(ground)

}

이렇게 만들었더니

벌레와 당근이 화면을 빠져나간다

 

 

    addItem('carrot', 5, 'img/carrot.png', 80)

    addItem('bug', 5, 'img/bug.png', 50)



        item.style.left = `${x-size}px`

        item.style.top = `${y-size}px`

그래서 이렇게 만들었더니

이제는 왼쪽과 위로 빠져나간다

 

 

다른 방법이 필요하다

 const x = Math.floor(Math.random()*(width-size))

 const y = Math.floor(Math.random()*(height-size))

됐다!!!

이 과정에서 배운 것

Math.random()에 원하는 최댓값을 곱하면 Math.random은 0과 원하는 최댓값 사이에서 값을 도출하게 된다.

코드가 왼쪽과 위로 빠져나간 이유는 

 const x = Math.floor(Math.random()*width-size)

 const y = Math.floor(Math.random()*height-size)

(width-size)를 한 번에 묶지 않고 random값의 최대값을 width(or height)로 준 다음에 그 값에서 size를 뺐기 때문이다.

즉. 최솟값이 0 밑으로 내려가 당근과 벌레의 크기만큼 마이너스 값을 가졌던 것이다.

 

 


이 후 막힌 부분은 없다

 

2-2

// 2. 벌레와 당근

// - 당근을 누르면 당근의 개수가 줄어드는 것이 표시된다

ground.addEventListener("click", (e) => {

  const target = e.target.dataset.name;

  if (target === "carrot") {

    carrot = ground.childElementCount - itemNum - 1;

    e.target.remove();

    soundPlay(carrot_pull);

    gameScore.innerHTML = carrot;

    carrotNum(carrot);

  } else if (target === "bug") {

    startBtn.innerHTML = `${stop}`;

    soundPlay(bug_pull);

    changeShape();

    stopTimer();

    popupInfo.innerHTML = "Return😢";

    soundStop(bg);

    soundPlay(alertSound);

    popupBox();

  } else {

    return;

  }

});

 

하지만 코드가 아주 더럽다.

일단 원하는 동작은 잘 이루어지지만 코드의 복잡함이 가히 스파게티를 방불케 한다.

 

 

 

function carrotNum(carrot) {

  if (carrot === 0) {

    changeShape();

    soundStop(bg);

    soundStop(alertSound);

    soundPlay(game_win);

    popupInfo.innerHTML = "congratulate!💕";

    stopTimer();

    popupBox();

  }

}

이 또한 마찬가지로

정말 더럽다

똑같은 함수를 몇 군대에서 정의하고 있고

popupInfo.innerHTML같은 경우는 그냥 함수 파라메타로 이용해도 됐을 텐데... 라는 생각이 든다

바로 30분전에 감격하며 만들어낸 코드도 다시 뜯어보니 고칠 곳이 한두곳이 아니다💀

 

 

일단 지금은 결과를 즐기자!

 

 

반응형