EnJinnier

가위바위보 게임 만들기 본문

프로젝트/웹 프로젝트

가위바위보 게임 만들기

공학도진니 2024. 4. 6. 00:07

HTML/CSS/JS 만으로 가위바위보 게임을 만들어보았다!

뭔가 디자인이 다 흔해서 재밌게 만들고자 내가 좋아하는 포켓몬스터 느낌으로 꾸며봤다.

일러스트같은 것을 구하는게 힘들었지만 그래도 더 재밌게 만들 수 있었다.

(개인 소장용으로 만든거니까 저작권 문제는 없겠지?..)

 

게임 방식은 단순하다. 

사용자는 가위,바위,보,리셋 버튼 중 하나를 누를 수 있고 컴퓨터가 랜덤으로 가위,바위,보 중 하나를 뽑아 대결을 진행한다.

점수는 누적되어 보여지고, 리셋버튼을 누르면 0승0무0패부터 다시 시작한다.

 

코드 전문

HTML

<!DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>가위바위보 게임</title>

    <link rel="stylesheet" href="style.css" />
  </head>
  <body>
    <div class="back">
      <div class="main">
        <div class="top">
          <div class="side" id="computer">
            <h4><br />Computer</h4>
          </div>
          <div id="comp-icon">
            <img id="comp-img" src="images/comp-img.png" />
          </div>
          <div class="side" id="user">
            <h4>You</h4>
          </div>
          <div id="msg">
            <div id="text">
              ㅤ앗! 야생 컴퓨터(이)가 등장했다! 무엇을 할까?<br />
              <!--여기 전적이 업데이트 되어야함-->
              <span id="myScore">
                ㅤ전적: <span id="win">0</span>승 / <span id="draw">0</span>무 /
                <span id="lose">0</span>패
              </span>
            </div>
          </div>
        </div>
        <div class="bottom">
          <div class="choice">
            <button id="scissors">가위를 낸다.</button>
            <button id="rock">바위를 낸다.</button>
            <button id="paper">보를 낸다.</button>
            <button id="reset">점수를 리셋한다.</button>
          </div>
        </div>
      </div>
    </div>

    <script src="game.js"></script>
  </body>
</html>

 

CSS

@import url("//cdn.jsdelivr.net/gh/neodgm/neodgm-webfont@latest/neodgm/style.css");

body {
  position: relative;
  font-family: "NeoDunggeunmo";
}

.back {
  background-color: black;
}
.main {
  display: flex;
  flex-direction: column;
  display: grid;
  grid-template-rows: 1fr 1fr;
  background-color: white;
  position: fixed;
  top: 0;
  left: 0;

  width: 450px;
  height: 650px;
  z-index: 10;
}

#title {
  text-align: center;
}
.top {
  position: relative;
  background-image: url(https://nioting.com/xe/files/attach/images/47338/472/092/13yamamichi2.jpg);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}
.bottom {
  background-image: url(https://e0.pxfuel.com/wallpapers/723/266/desktop-wallpaper-pokeball.jpg);
  background-repeat: no-repeat;
  background-position: center;
  background-size: cover;
}
.side {
  line-height: 1em;
  padding-left: 10px;
}
#computer {
  width: 200px;
  height: 60px;
  position: relative;
  top: 20px;
  background-image: url("images/comp-info2.png");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 100%;
}
#comp-img {
  position: absolute;
  top: 40px;
  right: 60px;
  width: 80px;
  height: 80px;
}
#user {
  width: 220px;
  height: 80px;
  position: absolute;
  top: 140px;
  right: 0px;
  background-image: url("images/user-info.png");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 100%;
}
#user h4 {
  position: relative;
  top: -3px;
  left: 40px;
}
#msg {
  position: absolute;
  bottom: 0px;
  left: 0px;
  right: 0px;

  height: 65px;
  padding: 10px;
  background-image: url("images/IMG_4435.jpg");
  background-repeat: no-repeat;
  background-position: center;
  background-size: 100%;
}
#msg #text {
  padding: 10px;
}
.choice {
  width: 100%;
  height: 100%;
  display: grid;
  grid-template: 50% 50% / 50% 50%;
}
button {
  margin: 30px 10px;
  font-family: "NeoDunggeunmo";
  border-radius: 20px;
  background-color: white;
}

.font-neodgm {
  font-family: "NeoDunggeunmo";
}

.font-neodgm-code {
  font-family: "NeoDunggeunmo Code";
}

 

JS

//변수 할당
const curWin = document.getElementById("win");
const curDraw = document.getElementById("draw");
const curLose = document.getElementById("lose");

let msg = document.getElementById("text");

winScore = parseInt(curWin.innerText);
drawScore = parseInt(curDraw.innerText);
loseScore = parseInt(curLose.innerText);

const rock = document.getElementById("rock");
const scissors = document.getElementById("scissors");
const paper = document.getElementById("paper");
const reset = document.getElementById("reset");

//컴퓨터의 선택 고르기
function getComChoice() {
  const choiceArray = ["r", "s", "p"];
  const comChoice = Math.floor(Math.random() * 3);
  return choiceArray[comChoice];
}

function compareChoice() {}
//승리
function win() {
  console.log("승리");
  winScore += 1;
  curWin.innerText = winScore;
  setTimeout(() => {
    msg.innerText = "퍼비가 이겼다! 아싸!";
    setTimeout(() => {
      msg.innerText =
        "이제 무엇을 할까? \n전적: " +
        winScore +
        "승 " +
        drawScore +
        "무 " +
        loseScore +
        "패";
    }, 2500);
  }, 2500);
}
//무승부
function draw() {
  console.log("무승부");
  drawScore += 1;
  curDraw.innerText = drawScore;
  setTimeout(() => {
    msg.innerText = "둘이 똑같은 것을 냈군!";
    setTimeout(() => {
      msg.innerText =
        "이제 무엇을 할까? \n전적: " +
        winScore +
        "승 " +
        drawScore +
        "무 " +
        loseScore +
        "패";
    }, 2500);
  }, 2500);
}
//패배
function lose() {
  console.log("패배");
  loseScore += 1;
  curLose.innerText = loseScore;
  setTimeout(() => {
    msg.innerText = "이런.. 컴퓨터가 이겨버렸다!";
    setTimeout(() => {
      msg.innerText =
        "이제 무엇을 할까? \n전적: " +
        winScore +
        "승 " +
        drawScore +
        "무 " +
        loseScore +
        "패";
    }, 2500);
  }, 2500);
}
//리셋
reset.onclick = () => {
  msg.innerText = "에잇! 다시 시작하자.";
  curWin.innerText = 0;
  curDraw.innerText = 0;
  curLose.innerText = 0;

  winScore = 0;
  drawScore = 0;
  loseScore = 0;

  setTimeout(() => {
    msg.innerText =
      "이제 무엇을 할까? \n전적: " +
      winScore +
      "승 " +
      drawScore +
      "무 " +
      loseScore +
      "패";
  }, 1500);
};
rock.onclick = () => {
  const infomsg = document.getElementById("msg");
  msg.innerText = "퍼비는 바위를 냈다!";
  const comChoice = getComChoice();

  switch (comChoice) {
    case "r":
      setTimeout(() => {
        msg.innerText = "컴퓨터는 바위를 냈다!";
      }, 1000);
      draw();
      break;
    case "s":
      setTimeout(() => {
        msg.innerText = "컴퓨터는 가위를 냈다!";
      }, 1000);
      win();
      break;
    case "p":
      setTimeout(() => {
        msg.innerText = "컴퓨터는 보를 냈다!";
      }, 1000);
      lose();
      break;
  }
};

scissors.onclick = () => {
  const infomsg = document.getElementById("msg");
  msg.innerText = "퍼비는 가위를 냈다!";
  const comChoice = getComChoice();

  switch (comChoice) {
    case "r":
      setTimeout(() => {
        msg.innerText = "컴퓨터는 바위를 냈다!";
      }, 1000);
      lose();
      break;
    case "s":
      setTimeout(() => {
        msg.innerText = "컴퓨터는 가위를 냈다!";
      }, 1000);
      draw();
      break;
    case "p":
      setTimeout(() => {
        msg.innerText = "컴퓨터는 보를 냈다!";
      }, 1000);
      win();
      break;
  }
};

paper.onclick = () => {
  const infomsg = document.getElementById("msg");
  msg.innerText = "퍼비는 보를 냈다!";
  const comChoice = getComChoice();

  switch (comChoice) {
    case "r":
      setTimeout(() => {
        msg.innerText = "컴퓨터는 바위를 냈다!";
      }, 1000);
      win();
      break;
    case "s":
      setTimeout(() => {
        msg.innerText = "컴퓨터는 가위를 냈다!";
      }, 1000);
      lose();
      break;
    case "p":
      setTimeout(() => {
        msg.innerText = "컴퓨터는 보를 냈다!";
      }, 1000);
      draw();
      break;
  }
};

//버튼의 입력 구분
/*
function main() {
  rock.addEventListener("click", () => gameR());
  scissors.addEventListener("click", () => gameS());
  paper.addEventListener("click", () => gameP());
  reset.addEventListener("click", () => setReset());
}

main();*/

 

최종 실행 스크린샷

 

실행 영상

 

 

어려웠던 점 및 아쉬운 점

- 웹폰트 구현하는데 적용이 안돼서 애를 먹었다. 친구의 도움을 받았다.

- 가위,바위,보 일러스트가 나왔다가 사라지는것도 구현해보고 싶었는데 마음에 쏙 드는 일러스트를 찾지 못했을뿐더러 시간이 부족했다..

 

 

 

이미지 출처

top배경-https://nioting.com/xe/game_souce_XP/92472   

bottom배경-https://www.google.co.kr/url?sa=i&url=https%3A%2F%2Fwww.pxfuel.com%2Fko%2Fdesktop-wallpaper-jdzho&psig=AOvVaw1muf1a8Ni4-KujgY47vq_7&ust=1712329173723000&source=images&cd=vfe&opi=89978449&ved=0CBIQjRxqFwoTCLCb-7bpqIUDFQAAAAAdAAAAABAJ  

 

참고한 글

https://github.com/HBSPS/RPS