>웹 프론트엔드 >View.js >Vue3+Canvas를 사용하여 간단한 스네이크 게임을 구현하는 방법

Vue3+Canvas를 사용하여 간단한 스네이크 게임을 구현하는 방법

王林
王林앞으로
2023-05-12 21:58:041389검색

    Vue3+Canvas를 사용하여 간단한 스네이크 게임을 구현하는 방법

    규칙

    플레이 방법: 플레이어는 방향 키를 사용하여 긴 뱀을 제어하여 지속적으로 콩을 삼키게 됩니다. 머리가 뱀의 몸에 닿거나 장벽 게임이 종료됩니다.

    Idea

    요소: 테두리, 뱀 머리, 뱀 몸, 음식

    테두리: 줄 수 입력 뱀 몸과 구분하여 음식을 먹을 때 뱀 몸의 꼬리에

    음식을 추가합니다. 위치는 무작위로 생성됩니다.

    Flowchart

    Vue3+Canvas를 사용하여 간단한 스네이크 게임을 구현하는 방법코드 구현

    기술 스택

    Choose

    기술은 dom에 비해 성능이 더 좋습니다.

    vue3、vite 基础架构; 视图选用 canvas기본 변수 정의

    <script setup lang="ts">
      import { ref, onMounted } from &#39;vue&#39;
      
      let width = ref(600) // 地图默认宽度
      let height = ref(400) // 地图默认高度
      let canvas: any = null // canvas 对象
      let ctx: any = null // canvas 渲染上下文对象
      let snakeList = [[0, 100], [10, 100],] // 蛇的点位坐标
      let direction = &#39;right&#39; // top | down | left | right // 当前方向
      let elementWidth = 10 // 元素尺寸
      let step = 10 // 速度
      let store = ref(0) // 分数
      let status = ref(&#39;start&#39;) // unStart | start | pause | over | success(通关) // 状态
      let foodCoordinate: any = [
        ((Math.random() * width.value) / 10) | 0,
        ((Math.random() * height.value) / 10) | 0,
      ] // 食物坐标
      let process: any = null // 定时器 Id
    </script>

    초기화

    는 onMoun에서 실행됩니다. 테드 , 주로 지도 그리기, 마우스 좌표 감지, 방향 모니터링, 음식 그리기, 타이머 활성화 및 기타 작업에 사용됩니다.

    function handleInit() {
      canvas = document.getElementById(&#39;canvas&#39;)
    
      if (canvas?.getContext) {
        ctx = canvas?.getContext(&#39;2d&#39;)
    
        canvas.addEventListener(&#39;mousemove&#39;, e => {
          ctx.clearRect(10, height.value - 20, 120, 40)
          ctx.fillText(`当前鼠标位置:${e.offsetX}, ${e.offsetY}`, 10, height.value - 10)
        })
    
        document.addEventListener(&#39;keydown&#39;, e => {
          e.preventDefault()
    
          if (Direction[e.keyCode]) {
            direction = Direction[e.keyCode]
          }
        })
    
        process = setInterval(handleRenderSnake, 150)
        handleRenderFood()
        // window.requestAnimationFrame(handleRenderSnake)
      } else {
        alert(&#39;您的浏览器不支持 canvas&#39;)
      }
    }

    음식 그리기

    음식을 먹으면 파괴되고 재생되어야 합니다

    // 绘制食物
    function handleRenderFood() {
      ctx.clearRect(foodCoordinate[0], foodCoordinate[1], 10, 10)
      foodCoordinate = [(Math.random() * width.value) | 0, (Math.random() * height.value) | 0]
      ctx.fillStyle = &#39;#eb2f96&#39;
      ctx.fillRect(foodCoordinate[0], foodCoordinate[1], 10, 10)
    }

    뱀 머리/뱀 몸통 그리기

    뱀은 2차원 배열로 표현되며 각 노드는 신체의 일부를 나타냅니다. 첫 번째 노드는 뱀의 머리를 나타냅니다. 꼬리 노드를 삭제하고 머리 노드를 추가하면 뱀의 움직임이 이루어집니다. 중간 노드는 이동할 필요가 없으며 네 방향의 처리가 약간 다릅니다. 음식을 먹으면 현재 프레임의 꼬리 노드가 더 이상 삭제되지 않고 뱀 몸체의 길이가 1만큼 늘어납니다.

    function handleRenderSnake() {
      switch (direction) {
        case &#39;top&#39;:
          if (snakeList.slice(-1)[0][1] <= 0) {
            status.value = &#39;over&#39;
            return
          }
    
          snakeList.push([
            snakeList[snakeList.length - 1][0],
            snakeList[snakeList.length - 1][1] - step,
          ])
          handleUpdateVerify()
          break
        case &#39;down&#39;:
          if (snakeList.slice(-1)[0][1] >= height.value - 1) {
            status.value = &#39;over&#39;
            return
          }
    
          snakeList.push([
            snakeList[snakeList.length - 1][0],
            snakeList[snakeList.length - 1][1] + step,
          ])
          handleUpdateVerify()
    
          break
          ...

    충돌 알고리즘, 경계 조건

    뱀 머리가 지도 가장자리에 닿으면 게임이 종료됩니다. 현재 좌표와 현재 방향을 기준으로 다음 좌표가 지도 크기를 초과할지 여부만 계산하면 됩니다. 뱀 머리.

    음식 섭취 계산 방법: 뱀 머리 좌표와 음식 좌표의 x, y축의 절대값을 각각 계산하여 요소 크기보다 작으면 접촉한 것으로 간주합니다.

    // 更新校验
    function handleUpdateVerify() {
      if (status.value === &#39;pause&#39;) {
        clearInterval(process)
      }
    
      if (store.value >= 100) {
        status.value = &#39;success&#39;
        return
      }
    
      for (let i of snakeList) {
        ctx.clearRect(i[0], i[1], elementWidth, elementWidth)
      }
    
      let currentSnake = snakeList.slice(-1)[0]
      if (
        Math.abs(currentSnake[0] - foodCoordinate[0]) < 10 &&
        Math.abs(currentSnake[1] - foodCoordinate[1]) < 10
      ) {
        store.value++
        handleRenderFood()
      } else {
        snakeList.shift()
      }
    }

    포인트 계산, 일시 정지, 계속 및 기타 기능

    전역 변수 status는 현재 상황의 상태를 나타냅니다. status === 'pause'이면 일시 정지 작업이 트리거되고 타이머 변수가 삭제되고 다시 시작됩니다. 버튼을 클릭하면 새로운 타이머 장치가 생성됩니다.

    음식을 먹으면 전역 변수 store++가 페이지에 양방향으로 바인딩되어 표시됩니다. 임시로 점수를 100을 초과하도록 설정하여 레벨을 통과합니다.

    위 내용은 Vue3+Canvas를 사용하여 간단한 스네이크 게임을 구현하는 방법의 상세 내용입니다. 자세한 내용은 PHP 중국어 웹사이트의 기타 관련 기사를 참조하세요!

    성명:
    이 기사는 yisu.com에서 복제됩니다. 침해가 있는 경우 admin@php.cn으로 문의하시기 바랍니다. 삭제