가위바위보 게임 만들기
작업개요
38가지 자바스크립트&리액트 튜토리얼 16번째,
가위 바위 보 게임 만들기 가위, 바위, 보 선택할 수 있는 버튼과
게임 스크린 정도만 있으면 될것 같다.
random으로 나오는 부분과 게임성을 위해 약간의 애니메이션을 추가해보자.
![rock](https://tistory3.daumcdn.net/tistory/6338466/skin/images/r.png)
![scissors](https://tistory3.daumcdn.net/tistory/6338466/skin/images/s.png)
![paper](https://tistory3.daumcdn.net/tistory/6338466/skin/images/p.png)
결과물
작업 에셋 구하기
일단 게임이니까 무료 이미지 사이트에서 가위, 바위, 보 이미지를 찾아보자.
딱히 마음에 드는게 없긴 한데..
노란 피부 톤의 만화 손 제스처 컬렉션 | 무료 벡터
노란 피부 톤의 만화 손 제스처 컬렉션에 대한 이 무료 벡터를 다운로드하시고, 53백만 개 이상의 전문 그래픽 자료를 확인하세요. #freepik #벡터 #ok #손바닥 #손가락
kr.freepik.com
요 이미지를 잘라서 사용해보자.
작업 체크리스트
- 가위바위보 이미지 만들기
- HTML 구성하기
- 게임 시작 - 랜덤으로 결과 - 결과 나오기 전 1초 내외의 애니메이션
HTML
뭐 요건 따로 설명할 필요 없을것 같다.
<div class="game_container">
<div class="result_screen">
<div class="img_container">
<img src="https://tistory3.daumcdn.net/tistory/6338466/skin/images/r.png" alt="rock">
<img src="https://tistory3.daumcdn.net/tistory/6338466/skin/images/s.png" alt="scissors">
<img src="https://tistory3.daumcdn.net/tistory/6338466/skin/images/p.png" alt="paper">
</div>
<p class="result_text"></p>
</div>
<div class="button_wrap">
<button type="button" data-action="r">
<img src="https://tistory3.daumcdn.net/tistory/6338466/skin/images/r.png" alt="rock">
</button>
<button type="button" data-action="s">
<img src="https://tistory3.daumcdn.net/tistory/6338466/skin/images/s.png" alt="scissors">
</button>
<button type="button" data-action="p">
<img src="https://tistory3.daumcdn.net/tistory/6338466/skin/images/p.png" alt="paper">
</button>
</div>
</div>
JS
const buttons = document.querySelectorAll('button');
const images = document.querySelectorAll('.result_screen img');
const computerPick = () => {
const random = Math.floor(Math.random() * 3);
const computer = ['r', 's', 'p'][random];
return computer;
}
const gameStart = async (userPick) => {
const computer = computerPick();
const result = document.querySelector('.result_text');
const imgContainer = document.querySelector('.img_container');
const [r, s, p] = images;
r.classList.remove('active');
s.classList.remove('active');
p.classList.remove('active');
result.textContent = '...';
await new Promise((resolve) => {
setTimeout(() => {
r.classList.add('active');
setTimeout(() => {
s.classList.add('active');
r.classList.remove('active');
p.classList.remove('active');
setTimeout(() => {
p.classList.add('active');
r.classList.remove('active');
s.classList.remove('active');
setTimeout(() => {
r.classList.remove('active');
s.classList.remove('active');
p.classList.remove('active');
setTimeout(() => {
computer === 'r'
? r.classList.add('active')
: computer === 's'
? s.classList.add('active')
: p.classList.add('active')
;
resolve();
}, 400)
}, 300);
}, 300);
}, 300);
}, 300);
}, 100);
if (userPick === computer) {
result.textContent = 'Draw';
} else if (userPick === 'r' && computer === 's' ||userPick === 's' && computer === 'p' || userPick === 'p' && computer === 'r') {
result.textContent = 'Win';
} else {
result.textContent = 'Lose';
}
}
buttons.forEach((button) => {
button.addEventListener('click', (e) => {
gameStart(e.target.closest('button').dataset.action);
});
});
조금 지저분하긴 한데..
computerPick()은 랜덤으로 r, s, p 중 하나를 리턴해주는 함수고,
gameStart는 userPick을 인자로 받는 함수인데, 각 버튼과 연결시켜 주었다.
애니메이션을 위해 async를 이용했다.
![rock](https://tistory3.daumcdn.net/tistory/6338466/skin/images/r.png)
![scissors](https://tistory3.daumcdn.net/tistory/6338466/skin/images/s.png)
![paper](https://tistory3.daumcdn.net/tistory/6338466/skin/images/p.png)