4. 프론트엔드 개발(지렁이 온라인 게임)

안녕하세요. 온라인 Snake 게임 개발 교육과정의 네 번째 시간입니다. 오늘은 프론트엔드를 배워 볼 시감입니다. Canvas를 이용한 게임 렌더링과 사용자 인터페이스 디자인에 대해 알아보겠습니다.

1. HTML 구조 설정

먼저 기본적인 HTML 구조를 만들어 봅시다.

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Multiplayer Snake Game</title>
    <link rel="stylesheet" href="styles.css">
</head>
<body>
    <div id="gameContainer">
        <div id="menu">
            <button id="createRoom">Create Room</button>
            <input type="text" id="roomCodeInput" placeholder="Enter Room Code">
            <button id="joinRoom">Join Room</button>
        </div>
        <canvas id="gameCanvas"></canvas>
        <div id="playerInfo"></div>
    </div>
    <script src="/socket.io/socket.io.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/p5.js/1.4.0/p5.js"></script>
    <script src="game.js"></script>
</body>
</html>

2. CSS 스타일링

게임의 외관을 개선하기 위해 CSS를 적용합니다.

body {
    font-family: Arial, sans-serif;
    display: flex;
    justify-content: center;
    align-items: center;
    height: 100vh;
    margin: 0;
    background-color: #f0f0f0;
}

#gameContainer {
    text-align: center;
}

#menu {
    margin-bottom: 20px;
}

button {
    padding: 10px 20px;
    font-size: 16px;
    cursor: pointer;
}

input {
    padding: 10px;
    font-size: 16px;
}

#gameCanvas {
    border: 2px solid #333;
}

#playerInfo {
    margin-top: 20px;
    font-size: 18px;
}

3. Canvas 설정 및 게임 렌더링

p5.js 라이브러리를 사용하여 게임을 렌더링합니다.

let canvas;
const canvasSize = 400;
const gridSize = 20;

function setup() {
    canvas = createCanvas(canvasSize, canvasSize);
    canvas.parent('gameCanvas');
    frameRate(10);
}

function draw() {
    background(51);
    if (gameState) {
        drawFood();
        drawPlayers();
    }
}

function drawFood() {
    fill(255, 0, 0);
    for (let food of gameState.foods) {
        rect(food.x * gridSize, food.y * gridSize, gridSize, gridSize);
    }
}

function drawPlayers() {
    for (let player of gameState.players) {
        if (player.alive) {
            fill(player.color);
            for (let segment of player.segments) {
                rect(segment.x * gridSize, segment.y * gridSize, gridSize, gridSize);
            }
        }
    }
}

4. 사용자 인터페이스 및 게임 상태 표시

게임 상태와 플레이어 정보를 표시하는 기능을 추가합니다.

function updatePlayerInfo() {
    const playerInfoDiv = document.getElementById('playerInfo');
    playerInfoDiv.innerHTML = '';

    if (gameState) {
        gameState.players.forEach((player, index) => {
            const playerDiv = document.createElement('div');
            playerDiv.textContent = `Player ${index + 1}: ${player.score}`;
            playerDiv.style.color = player.color;
            playerInfoDiv.appendChild(playerDiv);
        });
    }
}

socket.on('gameState', (newGameState) => {
    gameState = newGameState;
    updatePlayerInfo();
});

5. 반응형 디자인 적용

다양한 화면 크기에 대응할 수 있도록 반응형 디자인을 적용합니다.

@media (max-width: 600px) {
    #gameContainer {
        width: 100%;
    }

    #gameCanvas {
        width: 100%;
        height: auto;
    }

    button, input {
        width: 100%;
        margin-bottom: 10px;
    }
}

6. 터치 컨트롤 추가

모바일 기기에서도 게임을 즐길 수 있도록 터치 컨트롤을 추가합니다.

let touchStartX = 0;
let touchStartY = 0;

function touchStarted() {
    touchStartX = mouseX;
    touchStartY = mouseY;
    return false;
}

function touchEnded() {
    const diffX = mouseX - touchStartX;
    const diffY = mouseY - touchStartY;

    if (Math.abs(diffX) > Math.abs(diffY)) {
        if (diffX > 0) {
            changeDirection('RIGHT');
        } else {
            changeDirection('LEFT');
        }
    } else {
        if (diffY > 0) {
            changeDirection('DOWN');
        } else {
            changeDirection('UP');
        }
    }
    return false;
}

function changeDirection(direction) {
    socket.emit('changeDirection', { roomCode, direction });
}

7. 게임 오버 화면 구현

게임이 종료되었을 때 결과를 표시하는 화면을 추가합니다.

function showGameOver(winners) {
    const gameOverDiv = document.createElement('div');
    gameOverDiv.id = 'gameOver';
    gameOverDiv.innerHTML = `
        <h2>Game Over</h2>
        <p>Winner: Player ${winners[0].number}</p>
        <button onclick="restartGame()">Play Again</button>
    `;
    document.body.appendChild(gameOverDiv);
}

function restartGame() {
    document.getElementById('gameOver').remove();
    socket.emit('restartGame', roomCode);
}

socket.on('gameOver', (winners) => {
    showGameOver(winners);
});

결론

이번 포스팅에서는 프론트엔드 개발에 초점을 맞추어 Canvas를 이용한 게임 렌더링, 사용자 인터페이스 디자인, 반응형 웹 디자인, 그리고 터치 컨트롤 구현 등을 다뤘습니다. 이러한 요소들은 사용자 경험을 크게 향상시키고, 다양한 디바이스에서 게임을 즐길 수 있게 해줍니다.

다음 포스팅에서는 백엔드 서버 구축에 대해 더 자세히 알아보겠습니다. Express.js를 이용한 서버 설정과 RESTful API 구현에 대해 다루겠습니다. 감사합니다!

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다