[JavaScript Toy Project] Mini Game | 가위바위보 게임 만들기 토이프로젝트
바닐라 자바스크립트로 간단한 가위바위보 게임을 만들어보았습니다. 사용자가 가위, 바위, 보 중에 한 개를 선택하면 컴퓨터 측에서 랜덤으로 선택해, 그 결과를 위에 출력해주는 방식입니다. 애초에 기획했던 비주얼만으로는 난이도 최하일 줄 알았는데 생각보다 시간이 더 소요된 프로젝트였습니다.
contents
- Mini Game UI/UX
- Main Features
2-1. How the game works
2-2. Update status
2-3. Save data into the local storage
2-4. Reset button - Details
3-1. Hover effects
3-2. Total score stays when refreshed
1. Mini Game UI/UX
가위바위보 게임은 크게 스코어를 알려주는 상단 바, 사용자와 컴퓨터가 선택한 것을 보여주는 박스, 사용자가 선택할 항목이 있는 박스로 나뉘어 있습니다.
2. Main Features
2-1. How the game works
사용자의 측에서 선택한 옵션과 컴퓨터 측에서 랜덤으로 출력한 옵션을 비교해서 일반적인 가위바위보 규칙에 따라 점수가 업데이트되는 방식으로 작동합니다.
//selecting buttons function
const selectImage = () => {
if (rockBtn.classList.contains('click') &&
!scissorsBtn.classList.contains('click') &&
!paperBtn.classList.contains('click')) {
playerSelectedImg.style.background = bgImage[0]
playerSelectedText.innerText = selectedText[0]
} else if (!rockBtn.classList.contains('click') &&
scissorsBtn.classList.contains('click') &&
!paperBtn.classList.contains('click')) {
playerSelectedImg.style.background = bgImage[1]
playerSelectedText.innerText = selectedText[1]
} else if (!rockBtn.classList.contains('click') &&
!scissorsBtn.classList.contains('click') &&
paperBtn.classList.contains('click')){
playerSelectedImg.style.background = bgImage[2]
playerSelectedText.innerText = selectedText[2]
} else {
return
}
}
컴퓨터가 출력할 랜덤 이미지는 Math.floor()
메서드와 Math.random()
메서드로 가져왔습니다.
const bgImage = [
"url(image/rock.png) no-repeat center",
"url(image/scissors.png) no-repeat center",
"url(image/paper.png) no-repeat center"
]
const selectedText = ["Rock", "Scissors", "Paper"]
//get random computer image
const getRandomComputerImage = () => {
const randomNum = Math.floor(Math.random() * 3)
computerSelectedImg.style.background = bgImage[randomNum]
computerSelectedText.innerText = selectedText[randomNum]
}
사용자가 클릭한 엘리먼트에 'click
'이라는 클래스가 생성되면 그 결과에 따라 중간 영역의 왼쪽에 이미지가 출력됩니다. 그리고 나서 0.3초 후 컴퓨터가 랜덤한 이미지를 오른쪽에 출력하면 최종 결과가 나오게 됩니다.
//select button event listener
const selectBox = document.getElementById('select-box')
const rockBtn = document.getElementById('rock')
const scissorsBtn = document.getElementById('scissors')
const paperBtn = document.getElementById('paper')
//select button event listener
selectBox.addEventListener('click', (e) => {
computerSelectedImg.style.background = ''
computerSelectedText.innerText = ''
if (e.target === rockBtn) {
rockBtn.classList.add('click')
scissorsBtn.classList.remove('click')
paperBtn.classList.remove('click')
} else if (e.target === scissorsBtn) {
rockBtn.classList.remove('click')
scissorsBtn.classList.add('click')
paperBtn.classList.remove('click')
} else if (e.target === paperBtn) {
rockBtn.classList.remove('click')
scissorsBtn.classList.remove('click')
paperBtn.classList.add('click')
} else {
return false
}
selectImage()
setTimeout(() => {
getRandomComputerImage()
updateStatus()
updateLocalstorage()
}, 300);
})
2-2. Update status
updateStatus()
함수는 게임의 결과를 크게 세 가지 경우로 나누어, 결과를 status라는 객체에 push()
메서드로 추가해 줍니다. 사용자가 선택한 옵션, 컴퓨터가 선택한 옵션, 어느 쪽이 이겼는지에 대한 내용이 배열에 포함돼 있습니다. 사용자가 옵션을 클릭했을 때 이 함수가 실행됩니다.
//updating status
const updateStatus = () => {
if ( ( (playerSelectedText.innerText === selectedText[0]) &&
(computerSelectedText.innerText === selectedText[1]) ) ||
( (playerSelectedText.innerText === selectedText[1]) &&
(computerSelectedText.innerText === selectedText[2]) ) ||
( (playerSelectedText.innerText === selectedText[2]) &&
(computerSelectedText.innerText === selectedText[0]) ) ) {
const result = {
playerSelect: playerSelectedText.innerText,
player: 'win',
computerSelect: computerSelectedText.innerText,
computer: 'lose',
}
results.push(result)
playerStatusEl.innerText++
} else if ( ( (playerSelectedText.innerText === selectedText[0]) &&
(computerSelectedText.innerText === selectedText[2]) ) ||
( (playerSelectedText.innerText === selectedText[1]) &&
(computerSelectedText.innerText === selectedText[0]) ) ||
( (playerSelectedText.innerText === selectedText[2]) &&
(computerSelectedText.innerText === selectedText[1]) )) {
const result = {
playerSelect: playerSelectedText.innerText,
player: 'lose',
computerSelect: computerSelectedText.innerText,
computer: 'win',
}
results.push(result)
computerStatusEl.innerText++
} else {
results.push({
playerSelect: playerSelectedText.innerText,
player: 'draw',
computerSelect: computerSelectedText.innerText,
computer: 'draw',
})
}
}
나중에 게임 결과를 저장하고 출력할 때 이 객체의 키와 값에 접근하여 데이터를 활용합니다.
const playerStatusEl = document.getElementById('status-result__player')
const computerStatusEl = document.getElementById('status-result__computer')
//rendering status by localstorage data
const renderStatus = () => {
const results = getLocalStorageData
playerStatusEl.innerText = results
.map((result) => result["player"])
.filter((word) => word === "win").length
computerStatusEl.innerText = results
.map((result) => result["computer"])
.filter((word) => word === "win").length
}
2-3. Save data into the local storage
로컬스토리지에 데이터가 저장됩니다. localStorage.setItem()
, localStorage.getItem()
메서드로 데이터를 넣고 가져옵니다. 원래 굳이 로컬스토리지에 정보를 저장하지 않고 결과에 따라 스코어를 +1 하는 걸로 만족하려고 했는데, 나중에 기능을 또 추가하게 되면 이전 정보를 활용할 수 있어야 하기 때문에 로컬스토리지를 활용하기로 했습니다.
let results = []
//update data in local storage
const updateLocalstorage = () => {
localStorage.setItem('results', JSON.stringify(results))
}
//get data from local storage
const getLocalStorageData = JSON.parse(localStorage.getItem('results'))
console.log(getLocalStorageData)
results = getLocalStorageData // 새로고침 시 로컬스토리지 데이터를 사용하겠다는 의미
2-4. Reset button
스코어를 리셋해주는 버튼입니다. resetStatus()
함수가 실행되면 상단의 스코어와 게임 창이 리셋될 뿐만 아니라 로컬스토리지에서도 모든 게임 정보가 지워집니다.
const playerStatusEl = document.getElementById('status-result__player')
const computerStatusEl = document.getElementById('status-result__computer')
//reset status
const resetBtn = document.getElementById('reset')
const resetStatus = () => {
playerStatusEl.innerText = 0
computerStatusEl.innerText = 0
playerSelectedImg.style.background = ''
playerSelectedText.innerText = ''
computerSelectedImg.style.background = ''
computerSelectedText.innerText = ''
results = []
updateLocalstorage()
}
//reset button
resetBtn.addEventListener('click', resetStatus)
3. Details
3-1. Hover effects
약간의 마우스 오버 효과를 주어 사용자가 선택하려 하는 타겟을 잘 알아볼 수 있도록 했습니다.
.reset {
all: unset;
width: 100px;
height: 36px;
background: #fdfdfd;
border: 1px solid #ddd;
border-radius: 18px;
font-size: 16px;
font-family: Verdana, Geneva, Tahoma, sans-serif;
display: flex;
justify-content: space-evenly;
align-items: center;
cursor: pointer;
padding: 0 6px;
margin: 0 10px;
transition: all .2s ease;
}
.reset:hover {
background: #dec6eb;
border: 1px solid #777;
}
.rock, .scissors, .paper {
width: 80px;
height: 80px;
background: #aaa;
border: 1px solid #444;
border-radius: 40px;
margin-right: 10px;
cursor: pointer;
transition: all .1s ease;
}
.rock:hover, .scissors:hover, .paper:hover{
background-size: 56px 56px;
}
.rock {
background: url("image/rock.png") center no-repeat;
background-size: 50px 50px;
}
.scissors {
background: url("image/scissors.png") center no-repeat;
background-size: 50px 50px;
}
.paper {
background: url("image/paper.png") center no-repeat;
background-size: 50px 50px;
}
3-2. Total score stays when refreshed
로컬스토리지에 저장된 데이터를 새로고침했을 때 불러오도록 했습니다. 새로고침했을 때는 로컬스토리지에 데이터가 남아있지만 게임을 다시 이어나가면 데이터가 초기화되는 문제가 생겨서 꽤 오랜 시간 동안 고민을 했습니다. 고민끝에 마지막에 results = getLocalStorageData
한 줄을 추가해 주니 새로고침 후 다시 게임을 시작했을 때 로컬스토리지에서 가져온 results에 추가로 배열을 넣어줄 수 있게 됐습니다.
let results = []
//get data from local storage
const getLocalStorageData = JSON.parse(localStorage.getItem('results'))
console.log(getLocalStorageData)
results = getLocalStorageData
Author And Source
이 문제에 관하여([JavaScript Toy Project] Mini Game | 가위바위보 게임 만들기 토이프로젝트), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@eunjin/Javascript-Toy-Project-Mini-Game-가위바위보-게임-만들기-토이프로젝트저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)