포포를 찾아라 미니 게임 만들기(1)

Gorae·2021년 8월 6일
0

스몰 프로젝트

목록 보기
3/9
post-thumbnail

0. 동기

엘리님 당근게임 강의를 듣고, 다른 게임 만들기를 시도했다.
이모티콘 파일 30개로 월리를 찾아라! 같은 게임을 만들고 싶다는 생각을 했고, 실행에 옮겼다.


1. 계획

  1. 게임 시작하면 타이머가 시작되고, 고래들이 랜덤 위치로 등장한다.
  2. 상단에 찾아야 할 고래가 나타난다.
  3. 같은 고래를 시간 내에 찾으면 성공 팝업.
  4. 다른 고래를 클릭하거나, 시간 내에 못찾으면 실패 팝업.
  5. 상단의 “?” 버튼을 누르면, 간략한 게임 스토리를 볼 수 있다.

2. 진행(js 코드)

파일 하나에 일단 차근차근 작성해봤다.

const gameBtn = document.querySelector(".game__btn");
const gameField = document.querySelector(".game__field");
const gameTarget = document.querySelector(".game__target");
const whales = document.querySelectorAll(".whale");
const timer = document.querySelector(".game__timer");
const popUp = document.querySelector(".pop-up");
const popUpText = document.querySelector(".pop-up__text");
const popUpBtn = document.querySelector(".pop-up__btn i");
const howToBtn = document.querySelector(".game__how-to-play");

const WHALE_SIZE = 100; 
let sec = 5;
let clock;

// 랜덤한 숫자 x, y 반환
const getRandomPosition = () => {
	const x = gameField.clientWidth - WHALE_SIZE;
	const y = gameField.clientHeight - WHALE_SIZE;
	const randomX = Math.floor(Math.random()*Math.floor(x));
	const randomY = Math.floor(Math.random()*Math.floor(y));
	return [randomX,randomY];
}

// 랜덤하게 배치
const displayItems = () => {
	whales.forEach((whale)=>{
		const xy = getRandomPosition();
		whale.style.top = `${xy[1]}px`;
		whale.style.left = `${xy[0]}px`;
		whale.classList.remove("hidden");
	})
}

// 찾아야 할 이미지를 랜덤하게 표시
const showSelectedImage = () => {
	const randomNum = Math.floor(Math.random()*30)+1;
	gameTarget.innerHTML = `<img src="/imgs/icons/${randomNum}.png" id="game__target__img" data-num="${randomNum}">`;
}

// 고래를 클릭했을 때 조건에 따라 결과 출력
const onTargetClick = (e) => {
	const target = e.target.dataset.num;
	const gameTargetImg = document.querySelector("#game__target__img");
	if(!target){
		e.preventDefault();
	}
	else if(gameTargetImg.dataset.num == target && sec>0 && sec<5){
		popUpWin();
		stopGame();
	}
	else{
		popUpLose();
		stopGame();
	}
};

const popUpWin = () => {
	popUp.classList.remove("hidden");
	popUpText.innerHTML = `REPLAY ?<br>엄마 🐳: 정말 고마워요~ 당신의 눈썰미에 건배!!`;
}

const popUpLose = () => {
	popUp.classList.remove("hidden");
	popUpText.innerHTML = `REPLAY ?<br>엄마 🐳: 포포~ 이눔시끼 어딨는 거야~`;
}

const startTimer = () => {
	clock = setInterval(()=>{
		timer.innerText = `0${--sec}:00`;
		if(sec === 0){
			stopGame();
			popUpLose();
		}
	},1000);
}

const startGame = () => {
	//popup 초기화
	popUp.classList.add("hidden");
	// 타이머 시작
	startTimer();
	gameBtn.innerHTML = `<i class="far fa-stop-circle"> STOP</i>`;
	showSelectedImage();
	displayItems();
}

const stopGame = () => {
	// 타이머 정지
	clearInterval(clock);
	// 타이머 초기화
	sec = 5;
	timer.innerText = `0${sec}:00`;
	gameBtn.classList.add("cant-see")
	whales.forEach((whale)=>whale.classList.add("hidden"));
}

const showHowTo = () => {
	const howToPopUp = document.querySelector(".pop-up-how-to-play");
	howToPopUp.classList.toggle("hidden");
}

gameBtn.addEventListener("click", () => {
	const btnText = document.querySelector(".game__btn i");
	if(btnText.innerText === " PLAY"){
		startGame();
	} else {
		stopGame();
		popUpLose();
	}
});

gameField.addEventListener("click", onTargetClick);
popUpBtn.addEventListener("click", startGame);
howToBtn.addEventListener("click", showHowTo);

3. 진행 화면

  1. 게임 설명 화면

  1. 게임 화면

  1. 팝업

4. 느낀점

  • HTML에 이모티콘 파일 30개를 그대로 넣는 것 말고 다른 방법이 없을지 생각해 봐야겠다.
  • CSS 가 귀여워서, 정말 재밌게 만들었다. 함수를 하나하나 쌓아가면서 동작을 확인하는 과정이 즐거웠다.
  • 더 효율적인 코드를 작성할 수 있는 방법은 없는지 고민하며 리팩토링해야겠다.
profile
좋은 개발자, 좋은 사람

0개의 댓글