타닥타닥 개발자의 일상

Java Script / DOM 언어 querySelector, getElementById, addEventListner로 주사위 게임 만들기 classList.remove/classList.add 본문

코딩 기록/JavaScript

Java Script / DOM 언어 querySelector, getElementById, addEventListner로 주사위 게임 만들기 classList.remove/classList.add

NomadHaven 2023. 1. 30. 22:51

<게임 규칙>

주사위를 굴려 나온수를 합산, 주사위를 굴릴때 1이 나오면 자가 차례에서 합산된 수가 0이 되고

다른 선수에게 차례가 넘어감.

주사위가 1이 나오기 전에 나온 점수를 합산하고 다른 선수에게 넘기려면 hold를 누름.

hold를 누를시 차기 차례에서 나온 주사위 수가 합산되며 다른 선수에게 차례가 돌아감.

그런식으로 게임을 해서 먼저 합해진 수가 100이 넘는 사람이 승리.

 

 

 

 

index.html
<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <meta http-equiv="X-UA-Compatible" content="ie=edge" />
    <link rel="stylesheet" href="style.css" />
    <title>Pig Game</title>
  </head>
  <body>
    <main>
      <section class="player player--0 player--active">
        <h2 class="name" id="name--0">Player 1</h2>
        <p class="score" id="score--0">43</p>
        <div class="current">
          <p class="current-label">Current</p>
          <p class="current-score" id="current--0">0</p>
        </div>
      </section>
      <section class="player player--1">
        <h2 class="name" id="name--1">Player 2</h2>
        <p class="score" id="score--1">24</p>
        <div class="current">
          <p class="current-label">Current</p>
          <p class="current-score" id="current--1">0</p>
        </div>
      </section>

      <img src="dice-5.png" alt="Playing dice" class="dice" />
      <button class="btn btn--new">🔄 New game</button>
      <button class="btn btn--roll">🎲 Roll dice</button>
      <button class="btn btn--hold">📥 Hold</button>
    </main>
    <script src="script.js"></script>
  </body>
</html>

 

 

style.css
@import url('https://fonts.googleapis.com/css2?family=Nunito&display=swap');

* {
  margin: 0;
  padding: 0;
  box-sizing: inherit;
}

html {
  font-size: 62.5%;
  box-sizing: border-box;
}

body {
  font-family: 'Nunito', sans-serif;
  font-weight: 400;
  height: 100vh;
  color: #333;
  background-image: linear-gradient(to top left, #753682 0%, #bf2e34 100%);
  display: flex;
  align-items: center;
  justify-content: center;
}

/* LAYOUT */
main {
  position: relative;
  width: 100rem;
  height: 60rem;
  background-color: rgba(255, 255, 255, 0.35);
  backdrop-filter: blur(200px);
  filter: blur();
  box-shadow: 0 3rem 5rem rgba(0, 0, 0, 0.25);
  border-radius: 9px;
  overflow: hidden;
  display: flex;
}

.player {
  flex: 50%;
  padding: 9rem;
  display: flex;
  flex-direction: column;
  align-items: center;
  transition: all 0.75s;
}

/* ELEMENTS */
.name {
  position: relative;
  font-size: 4rem;
  text-transform: uppercase;
  letter-spacing: 1px;
  word-spacing: 2px;
  font-weight: 300;
  margin-bottom: 1rem;
}

.score {
  font-size: 8rem;
  font-weight: 300;
  color: #c7365f;
  margin-bottom: auto;
}

.player--active {
  background-color: rgba(255, 255, 255, 0.4);
}
.player--active .name {
  font-weight: 700;
}
.player--active .score {
  font-weight: 400;
}

.player--active .current {
  opacity: 1;
}

.current {
  background-color: #c7365f;
  opacity: 0.8;
  border-radius: 9px;
  color: #fff;
  width: 65%;
  padding: 2rem;
  text-align: center;
  transition: all 0.75s;
}

.current-label {
  text-transform: uppercase;
  margin-bottom: 1rem;
  font-size: 1.7rem;
  color: #ddd;
}

.current-score {
  font-size: 3.5rem;
}

/* ABSOLUTE POSITIONED ELEMENTS */
.btn {
  position: absolute;
  left: 50%;
  transform: translateX(-50%);
  color: #444;
  background: none;
  border: none;
  font-family: inherit;
  font-size: 1.8rem;
  text-transform: uppercase;
  cursor: pointer;
  font-weight: 400;
  transition: all 0.2s;

  background-color: white;
  background-color: rgba(255, 255, 255, 0.6);
  backdrop-filter: blur(10px);

  padding: 0.7rem 2.5rem;
  border-radius: 50rem;
  box-shadow: 0 1.75rem 3.5rem rgba(0, 0, 0, 0.1);
}

.btn::first-letter {
  font-size: 2.4rem;
  display: inline-block;
  margin-right: 0.7rem;
}

.btn--new {
  top: 4rem;
}
.btn--roll {
  top: 39.3rem;
}
.btn--hold {
  top: 46.1rem;
}

.btn:active {
  transform: translate(-50%, 3px);
  box-shadow: 0 1rem 2rem rgba(0, 0, 0, 0.15);
}

.btn:focus {
  outline: none;
}

.dice {
  position: absolute;
  left: 50%;
  top: 16.5rem;
  transform: translateX(-50%);
  height: 10rem;
  box-shadow: 0 2rem 5rem rgba(0, 0, 0, 0.2);
}

.player--winner {
  background-color: #2f2f2f;
}

.player--winner .name {
  font-weight: 700;
  color: #c7365f;
}

.hidden {
  display: none;
}

 

 

script.js
'use strict';

//Selecting Elements

const player0El = document.querySelector('.player--0');
const player1El = document.querySelector('.player--1');

//selector로 id를 select 할때는 #를 사용한다.
const score0El = document.querySelector('#score--0');
//getElementById를 사용하면 #없이 id값만 입력하면 된다
const score1El = document.getElementById('score--1');
const current0El = document.getElementById('current--0');
const current1El = document.getElementById('current--1');

const diceEl = document.querySelector('.dice');
const btnNew = document.querySelector('.btn--new');
const btnRoll = document.querySelector('.btn--roll');
const btnHold = document.querySelector('.btn--hold');

//후에 정의될 변수들은 let으로 선언만 해놓는다.
//score은 player1과 2의 점수를 저장할 배열
//currentScore은 해당 선수의 차례에서 더해진 점수
//activePlayer는 게임을 하고 있는 선수
//playing은 게임이 진행중인지 아닌지의 boolean 
let scores, currentScore, activePlayer, playing;


//Starting Condition 
//처음 시작할때의 상태로 초기화 하는 initialize함수.
const init = function () {
  scores = [0, 0];
  currentScore = 0;
  activePlayer = 0;
  playing = true;

  //보이는 부분의 세팅 초기화
  score0El.textContent = 0;
  score1El.textContent = 0;
  current0El.textContent = 0;
  current1El.textContent = 0;
  diceEl.classList.add('hidden');

  player0El.classList.remove('player--winner');
  player1El.classList.remove('player--winner');

  player0El.classList.add('player--active');
  player1El.classList.remove('player--winner');
};

//페이지 로드시 자동으로 게임 초기화
init();


//선수를 바꾸는 함수 switchPlayer
const switchPlayer = function () {
  document.getElementById(`current--${activePlayer}`).textContent = 0;

  //주사위를 돌리는 선수를 교체한다.
  //activePlayer가 0이면 1이고 0이 아니면 0이다.
  currentScore = 0;
  activePlayer = activePlayer === 0 ? 1 : 0;

  //toggle의 기능 클래스에 괄호안 부분이 있으면 지우고 없으면 괄호안 부분을 붙인다. 배경색이 css 적용되는 클래스 이름 변경 통해서 바뀜
  player0El.classList.toggle('player--active');
  player1El.classList.toggle('player--active');
};

//버튼을 누르면 주사위가 던져지는 이벤트 Roliing dice functionality
btnRoll.addEventListener('click', function () {
  if (playing) {
    //1. Generating a random dice roll 1~6까지의 랜덤넘버 생성하기
    const dice = Math.trunc(Math.random() * 6) + 1;
    console.log(dice);

    //2. Display dice 주사위 보이게 하기
    diceEl.classList.remove('hidden');
    //dice-(숫자).png 라는 파일명을 가진 이밎 파일이 폴더 내에 존재.
    //랜덤넘버가 할당될시 그에 맞는 이미지가 동적으로 보여진다.
    diceEl.src = `dice-${dice}.png`;

    //3. Check for rolled 1: if true, 주사위 숫자 1이 나온지 안나왔는지 확인
    if (dice !== 1) {
      // Add dice to current score 1이 아니면 current score에 주사위 수를 더하기
      currentScore += dice;
      //동적으로 점수 변경
      document.getElementById(`current--${activePlayer}`).textContent =
        currentScore;
    } else {
      // switch to next player 1 나왔을시 선수 교체
      switchPlayer();
    }
  }
});

//홀드 버튼을 눌렀을때 발생하는 이벤트 
btnHold.addEventListener('click', function () {
  if (playing) {
    //1. Add current score to active player's score 
    scores[activePlayer] += currentScore;
    //  scores[1] = scores[1] + currentScore

    document.getElementById(`score--${activePlayer}`).textContent =
      scores[activePlayer];

    //2. Check if player's score is >=100 점수가 100점이 넘었으면 승자가 나온 상황
    if (scores[activePlayer] >= 100) {
      //Finish the game 게임 종료
      playing = false;
      diceEl.classList.add('hidden');
      document
        .querySelector(`.player--${activePlayer}`)
        .classList.add('player--winner');
      document
        .querySelector(`.player--${activePlayer}`)
        .classList.remove('player--active');
    } else {
      //and if not, switch to the next player
      switchPlayer();
    }
  }
});


new버튼을 누르면 다시 init함수 불러서 게임 초기화
btnNew.addEventListener('click', init);
Comments