본문 바로가기
HTML/CSS

[HTML/CSS]스탑워치 기능을 활용한 10초 클릭 게임 만들기

by teamnova 2024. 12. 9.
728x90

타이머 관리를 통해 누가 10초 동안 클릭을 많이 하는 게임을 만들어 보겠습니다

 

  • 타이머 관리
       setInterval() - 게임 타이머 구현
       setTimeout() - 애니메이션 효과
  • 이벤트 처리
       클릭 이벤트
       키보드 이벤트 (스페이스바)
  • 로컬 스토리지 활용
       최고 기록 저장
       데이터 지속성 구현
  • DOM 조작
       요소 생성 및 수정
       클래스 조작
       스타일 동적 변경
<!DOCTYPE html>
<html lang="ko">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>10초 클릭 게임</title>
    <style>
        body {
            font-family: 'Arial', sans-serif;
            display: flex;
            justify-content: center;
            align-items: center;
            min-height: 100vh;
            margin: 0;
            background: linear-gradient(135deg, #1e3c72, #2a5298);
            color: white;
        }

        .game-container {
            text-align: center;
            background: rgba(255, 255, 255, 0.1);
            padding: 2rem;
            border-radius: 20px;
            backdrop-filter: blur(10px);
            box-shadow: 0 8px 32px rgba(0, 0, 0, 0.1);
        }

        h1 {
            color: #fff;
            margin-bottom: 2rem;
            text-shadow: 2px 2px 4px rgba(0, 0, 0, 0.3);
        }

        .stats {
            display: flex;
            justify-content: space-around;
            margin-bottom: 2rem;
        }

        .stat-box {
            background: rgba(255, 255, 255, 0.2);
            padding: 1rem;
            border-radius: 10px;
            min-width: 120px;
        }

        .stat-box h3 {
            margin: 0;
            font-size: 0.9rem;
            color: #afd3ff;
        }

        .stat-box .value {
            font-size: 2rem;
            font-weight: bold;
            margin: 0.5rem 0;
        }

        .click-area {
            width: 150px;
            height: 150px;
            background: #4CAF50;
            border-radius: 50%;
            margin: 2rem auto;
            cursor: pointer;
            position: relative;
            transition: transform 0.1s;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
        }

        .click-area:hover {
            transform: scale(1.05);
        }

        .click-area:active {
            transform: scale(0.95);
        }

        .click-area.disabled {
            background: #ccc;
            cursor: not-allowed;
        }

        .start-btn {
            background: #FF4081;
            color: white;
            border: none;
            padding: 1rem 2rem;
            font-size: 1.2rem;
            border-radius: 30px;
            cursor: pointer;
            transition: all 0.3s;
            margin-top: 1rem;
            box-shadow: 0 4px 15px rgba(0, 0, 0, 0.2);
        }

        .start-btn:hover {
            background: #E91E63;
            transform: translateY(-2px);
        }

        .start-btn:active {
            transform: translateY(0);
        }

        .start-btn.disabled {
            background: #ccc;
            cursor: not-allowed;
        }

        @keyframes countdown {
            0% { transform: scale(1); }
            50% { transform: scale(1.5); }
            100% { transform: scale(1); }
        }

        .countdown {
            animation: countdown 1s ease-in-out;
        }

        .click-effect {
            position: absolute;
            pointer-events: none;
            background: rgba(255, 255, 255, 0.8);
            border-radius: 50%;
            transform: translate(-50%, -50%);
            animation: clickEffect 0.5s ease-out forwards;
        }

        @keyframes clickEffect {
            0% {
                width: 0px;
                height: 0px;
                opacity: 0.5;
            }
            100% {
                width: 50px;
                height: 50px;
                opacity: 0;
            }
        }

        .high-score {
            color: #FFD700;
            font-weight: bold;
            text-shadow: 0 0 10px rgba(255, 215, 0, 0.5);
        }

        .result-message {
            margin-top: 1rem;
            font-size: 1.2rem;
            min-height: 2rem;
        }
    </style>
</head>
<body>
    <div class="game-container">
        <h1>🎮 10초 클릭 게임</h1>
       
        <div class="stats">
            <div class="stat-box">
                <h3>시간</h3>
                <div class="value" id="timer">10.0</div>
                <div></div>
            </div>
            <div class="stat-box">
                <h3>클릭 수</h3>
                <div class="value" id="clickCount">0</div>
                <div></div>
            </div>
            <div class="stat-box">
                <h3>최고 기록</h3>
                <div class="value" id="highScore">0</div>
                <div></div>
            </div>
        </div>

        <div id="clickArea" class="click-area disabled"></div>
       
        <button id="startBtn" class="start-btn" onclick="startGame()">게임 시작</button>
       
        <div class="result-message" id="resultMessage"></div>
    </div>

    <script>
        let clickCount = 0;
        let timeLeft = 10.0;
        let gameInterval;
        let isGameRunning = false;
        let highScore = localStorage.getItem('clickGameHighScore') || 0;

        // 초기 최고 기록 표시
        document.getElementById('highScore').textContent = highScore;

        function startGame() {
            if (isGameRunning) return;

            // 게임 상태 초기화
            clickCount = 0;
            timeLeft = 10.0;
            document.getElementById('clickCount').textContent = '0';
            document.getElementById('timer').textContent = '10.0';
            document.getElementById('resultMessage').textContent = '';
            document.getElementById('startBtn').classList.add('disabled');

            // 카운트다운 동안은 클릭 영역 비활성화 상태 유지
            document.getElementById('clickArea').classList.add('disabled');

            // 카운트다운 시작
            let countdown = 3;
            document.getElementById('resultMessage').textContent = countdown;
           
            const countdownInterval = setInterval(() => {
                countdown--;
                if (countdown > 0) {
                    document.getElementById('resultMessage').textContent = countdown;
                    document.getElementById('resultMessage').classList.add('countdown');
                    setTimeout(() => {
                        document.getElementById('resultMessage').classList.remove('countdown');
                    }, 500);
                } else {
                    clearInterval(countdownInterval);
                    document.getElementById('resultMessage').textContent = '시작!';
                    // 실제 게임 시작 시점에 클릭 영역 활성화 및 게임 상태 변경
                    document.getElementById('clickArea').classList.remove('disabled');
                    isGameRunning = true;
                    startTimer();
                }
            }, 1000);
        }

        function startTimer() {
            const startTime = Date.now();
            gameInterval = setInterval(() => {
                const elapsedTime = (Date.now() - startTime) / 1000;
                timeLeft = Math.max(0, 10 - elapsedTime);
                document.getElementById('timer').textContent = timeLeft.toFixed(1);

                if (timeLeft <= 0) {
                    endGame();
                }
            }, 100);
        }

        function endGame() {
            clearInterval(gameInterval);
            isGameRunning = false;
            document.getElementById('clickArea').classList.add('disabled');
            document.getElementById('startBtn').classList.remove('disabled');
            document.getElementById('timer').textContent = '0.0';

            // 최고 기록 체크 및 업데이트
            if (clickCount > highScore) {
                highScore = clickCount;
                localStorage.setItem('clickGameHighScore', highScore);
                document.getElementById('highScore').textContent = highScore;
                document.getElementById('resultMessage').innerHTML =
                    `🎉 새로운 기록! ${clickCount}회 달성! 🎉`;
            } else {
                document.getElementById('resultMessage').textContent =
                    `게임 종료! ${clickCount}회 클릭했습니다!`;
            }
        }

        document.getElementById('clickArea').addEventListener('click', (e) => {
            if (!isGameRunning || e.target.classList.contains('disabled')) return;

            // 클릭 효과 생성
            const effect = document.createElement('div');
            effect.className = 'click-effect';
            effect.style.left = (e.offsetX) + 'px';
            effect.style.top = (e.offsetY) + 'px';
            e.target.appendChild(effect);

            // 1초 후 효과 제거
            setTimeout(() => effect.remove(), 1000);

            clickCount++;
            document.getElementById('clickCount').textContent = clickCount;
        });

        // 스페이스바로 게임 시작
        document.addEventListener('keydown', (e) => {
            if (e.code === 'Space' && !isGameRunning) {
                startGame();
            }
        });
    </script>
</body>
</html>

 

게임 요소를 활용한 웹 기능

  • 타이머 기능
    • 예약 시스템
    • 경매 시스템
    • 퀴즈 애플리케이션
  • 점수 시스템
    • 사용자 평가 시스템
    • 게이미피케이션
    • 성과 측정 도구
  • 애니메이션 효과
    • 인터랙티브 웹사이트
    • 사용자 피드백
    • UI/UX 개선

시연 영상