砲を探してミニゲームを作る(1)


0、動機


エリーのニンジンゲームの授業を聞いて、他のゲームを作ってみました.
30個の表情ファイルでウォーリーを探せ!同じゲームをして実行したい.

1.計画

  • ゲーム開始後にタイマーがスタートし、クジラがランダムな位置で登場.
  • 商団に探しているクジラが現れた.
  • 時間内に
  • のようなクジラが見つかれば、飛び出すことに成功する.
  • をクリックして他のクジラが時間内に見つからない場合は、ポップアップに失敗します.
  • 商団の「?」ボタンをクリックすると、短いゲームの物語が表示されます.
  • 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.進捗画面

  • ゲーム説明画面
  • ゲーム画面
  • ポップアップメニュー
  • 4.感じ

  • HTMLに直接30個の表情ファイルを入れる以外に、他に方法はないかと考えなければなりません.
  • CSSが可愛くて面白かったです.一つ一つ関数を積み重ねて、動作を確認する過程が楽しいです.
  • より効率的なコード作成方法があるかどうかは、再設計が必要です.