자바스크립트를 이용하여 간단한 게임 구현하기

woori kim·2023년 6월 10일
0

이번엔 간단한 토이프로젝트로 자바스크립트를 이용하여 간단한 게임을 구현해보았습니다.

해당 게임은 html, css, 바닐라자바스크립트로 구성되었습니다.

캔버스(Canvas)는 HTML5에서 제공하는 요소로, 그래픽을 그리기 위한 도화지와 같은 역할을 합니다. JavaScript와 함께 사용하여 동적이고 상호작용적인 그래픽 및 게임을 만들 수 있습니다. 해당 프로젝트에서는 2d만 사용하였으나 3d의 사용도 가능합니다.

간단한 캔버스 사용법

다음은 캔버스를 사용하여 간단하게 게임을 만드는 방법에 대해 설명해보도록 하겠습니다.

  • HTML 문서에서 <canvas> 태그를 추가하여 캔버스 엘리먼트를 생성
    <canvas id="game-canvas"></canvas>

  • JavaScript 코드에서 캔버스에 접근하고 그래픽을 그릴 수 있는 2D 컨텍스트 취득

    		const canvas = document.getElementById("game-canvas");
    		const ctx = canvas.getContext("2d");
  • 게임의 상태와 변수를 초기화합니다.

  • 게임 루프를 생성

    • requestAnimationFrame을 사용하여 반복적으로 화면을 업데이트하고 애니메이션 효과를 생성
      const gameLoop = () => {
        // 게임 로직 작성
    
        // 그래픽 그리기
        render();
    
        // 다음 프레임 요청
        requestAnimationFrame(gameLoop);
      }
    
      // 게임 루프 시작
      gameLoop();
  • 그래픽을 그리는 함수인 render()을 작성


  const render = (cat, dog, ball, background) => {
    // 캔버스 지우기
  	ctx.clearRect(0, 0, canvas.width, canvas.height);
    // 게임 요소 그리기
  	// 예: 공, 고양이, 배경 등을 캔버스에 그립니다.
  };
  • 이벤트 처리 함수를 작성

      const handleInput = (event) => {
        // 사용자 입력 처리 로직 작성
      }
    
      // 이벤트 리스너 등록
      document.addEventListener("keydown", handleInput);

Dodgeball-Dash

위의 내용을 이용하여 이번에 구현한 샘플코드를 간략하게 설명하겠습니다.
이번 토이 프로젝트에서 구현한 게임은 "Dodgeball-Dash"라는 이름의 간단한 게임입니다. 이 게임에서 플레이어는 강아지로서 화면에 나타난 공에 부딪히면 공이 움직이며, 동시에 고양이와 경쟁하여 점수를 획득합니다.

게임에는 다양한 버튼 이벤트가 있습니다:

  • "중단" 버튼은 게임을 일시정지하고 재개할 수 있습니다.
  • "음악" 버튼을 클릭하여 배경 음악을 재생하거나 정지할 수 있습니다.
  • "재시작" 버튼을 클릭하여 게임을 초기화하고 다시 시작할 수 있습니다.
  • "난이도" 버튼을 클릭하여 게임의 난이도를 변경할 수 있습니다.
  • "이동" 버튼을 사용하여 플레이어(강아지)를 상하좌우로 이동시킬 수 있습니다.
  • 충돌 계산을 위한 isBallCollision 함수도 구현되어 있습니다. 이 함수는 공과 다른 객체(고양이 또는 강아지)의 충돌을 감지합니다. 함수 내에서는 객체와 공의 좌표와 크기를 비교하여 충돌 여부를 판단합니다.
  • 버튼이벤트

    • 중단
      - 게임을 중단하고 다시 누르면 그 자리에서 재시작됩니다.

        const handlePauseEvent = () => {
          const stopBtn = document.querySelector(".stop-btn");
      
          const gamePausedEvent = () => {
            if (!isGamePaused) {
              // 게임이 진행 중인 상태에서 버튼을 터치하면 일시정지
              backUpBallXSpeed = ballXSpeed;
              backUpBallYSpeed = ballYSpeed;
              ballXSpeed = 0;
              ballYSpeed = 0;
              isGamePaused = true;
              isStart = false;
            } else {
              ballXSpeed = backUpBallXSpeed;
              ballYSpeed = backUpBallYSpeed;
              isGamePaused = false;
              isStart = true;
            }
          };
          stopBtn.addEventListener("mouseup", function () {
            gamePausedEvent();
          });
          stopBtn.addEventListener("touchend", function () {
            gamePausedEvent();
          });
        };
      		```
    • 음악

      • music버튼을 통해 음악을 재생하고 중단합니다.
        const handleMusicEvent = () => {
          const audio = new Audio("music/bgm.mp3");
          const musicBtn = document.querySelector(".music-btn");
          const playMusic = () => {
            audio.play();
            isMusicPlaying = true;
          };
          const stopMusic = () => {
            audio.pause();
            audio.currentTime = 0;
            isMusicPlaying = false;
          };
      
          musicBtn.addEventListener("mousedown", function () {
            if (isMusicPlaying) {
              stopMusic();
            } else {
              playMusic();
            }
          });
      
          musicBtn.addEventListener("touchend", function () {
            if (isMusicPlaying) {
              stopMusic();
            } else {
              playMusic();
            }
          });
        };
      			```
    • 재시작

      • 플레이어와 컴퓨터의 점수를 초기화하고 원래 초기 위치로 이동
        const handleResetEvent = () => {
          const resetData = () => {
            dogScore = 0;
            catScore = 0;
            resetPositions();
            isStart = false;
          };
          const resetBtn = document.querySelector(".reset-btn");
          resetBtn.addEventListener("mousedown", function () {
            resetData();
          });
          // 버튼을 클릭하면 게임을 재시작하거나 난이도를 변경
          resetBtn.addEventListener("touchstart", function () {
            resetData();
          });
        };
      		```
    • 난이도

      • 고양이의 스피드를 조정합니다.
        const handleDifficulty = () => {
          const difficultyBtn = document.querySelector(".difficulty-btn");
      
          difficultyBtn.addEventListener("mouseup", function () {
            difficulty++;
      
            if (difficulty > 2) {
              difficulty = 0;
            }
          });
          difficultyBtn.addEventListener("touchend", function () {
            difficulty++;
      
            if (difficulty > 2) {
              difficulty = 0;
            }
          });
        };
      		```
    • 이동버튼

      • 버튼을 누르면 플레이어(강아지)가 상하좌우로 이동합니다.
      • 이때 강아지의 좌표를 변경되므로 캔버스에서 강아지의 위치는 업데이트됩니다.
        const setupMoveEvent = () => {
          const moveButtons = {
            up: document.querySelector(".up-button"),
            down: document.querySelector(".down-button"),
            left: document.querySelector(".left-button"),
            right: document.querySelector(".right-button"),
          };
      
          const directions = ["Up", "Down", "Left", "Right"];
      
          const handleMoveStart = (direction) => () => {
            handleMove(direction, true);
          };
      
          const handleMoveEnd = (direction) => () => {
            handleMove(direction, false);
          };
      
          const handleMove = (direction, isMoving) => {
            const moveFlag = `isMoving${direction}`;
            moveState[moveFlag] = isMoving;
            isStart = true;
          };
      
          directions.forEach((direction) => {
            moveButtons[direction.toLowerCase()].addEventListener(
              "mousedown",
              handleMoveStart(direction)
            );
            moveButtons[direction.toLowerCase()].addEventListener(
              "mouseup",
              handleMoveEnd(direction)
            );
            moveButtons[direction.toLowerCase()].addEventListener(
              "touchstart",
              handleMoveStart(direction)
            );
            moveButtons[direction.toLowerCase()].addEventListener(
              "touchend",
              handleMoveEnd(direction)
            );
          });
        };
      		```
  • 볼과 물체의 충돌계산

    • objectX, objectY, objectSize: 주어진 객체의 위치와 크기입니다.

    • objectLeft, objectRight, objectTop, objectBottom: 객체의 좌우상하 경계를 계산합니다.

    • ballLeft, ballRight, ballTop, ballBottom: 공의 좌우상하 경계를 계산합니다.

    • distanceThreshold: 충돌 판정을 위한 거리 임계값입니다.

    • 조건문을 사용하여 충돌 판정을 수행합니다.

        const isBallCollision = (objectX, objectY, objectSize) => {
          if (!isStart) {
            return;
          }
          const objectLeft = objectX;
          const objectRight = objectX + objectSize;
          const objectTop = objectY;
          const objectBottom = objectY + objectSize;
      
          const ballLeft = ballX;
          const ballRight = ballX + ballSize;
          const ballTop = ballY;
          const ballBottom = ballY + ballSize;
      
          const distanceThreshold = 5;
          if (
            ballLeft < objectRight - distanceThreshold &&
            ballRight > objectLeft + distanceThreshold &&
            ballTop < objectBottom - distanceThreshold &&
            ballBottom > objectTop + distanceThreshold
          ) {
      
            isEffectActive = true;
            // 충돌 감지를 위한 계산을 최소화할 수 있도록 수정
            return true; // 충돌 발생
          } else {
            isEffectActive = false;
            return false; // 충돌 없음
          }
        };
      		```

해당코드는
https://github.com/woori3104/Dodgeball-Dash.github.io
에서 참고하실수있습니다.

0개의 댓글