讲师中心 微信公众号
AI工具推荐 视频效率加速

怎么使用Vue3+Canvas实现简易的贪吃蛇游戏

轻磊同学_3654

轻磊同学_3654

发布时间:2023-05-12 21:58:04

|

1582人浏览过

|

来源于亿速云

转载

    怎么使用vue3+canvas实现简易的贪吃蛇游戏

    规则

    玩法:玩家使用方向键操控一条长长的蛇不断吞下豆子,同时蛇身随着吞下的豆子不断变长,当蛇头撞到蛇身或障壁时游戏结束。

    思路

    元素:边界、蛇头、蛇身、食物

    边界:输入 行数 x, 列数 y 生成边界地图,用二维坐标标识每个点的位置;

    蛇头、蛇身:蛇头和蛇身分离,当吃到食物后,蛇身尾部加一

    立即学习“前端免费学习笔记(深入)”;

    食物:位置随机生成;

    流程图

    怎么使用Vue3+Canvas实现简易的贪吃蛇游戏

    代码实现

    技术栈

    选择 vue3、vite 基础架构; 视图选用 canvas 技术来实现,相比 dom 来说性能更好;

    vue3-ant-design-vue-component-skill
    vue3-ant-design-vue-component-skill

    封装基于 Vue 3 + Ant Design Vue 的通用业务组件,提供标准化模板与最佳实践。

    下载

    基本变量定义

    <script setup lang="ts">
      import { ref, onMounted } from 'vue'
      
      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 = 'right' // top | down | left | right // 当前方向
      let elementWidth = 10 // 元素尺寸
      let step = 10 // 速度
      let store = ref(0) // 分数
      let status = ref('start') // 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>

    初始化

    在 onMounted 里执行,主要做 地图绘制、鼠标坐标检测、方向监测、食物绘制、定时器启用等操作。

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

    食物绘制

    当食物被吃掉后,需要销毁和重新生成

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

    蛇头/蛇身绘制

    蛇是通过二维数组来表示的,每个节点代表身体的一部分,第一个节点代表蛇头,蛇的移动是通过 删除尾部节点,添加头部节点来实现,中间节点不用动,在四个方向上的处理略有不同。 注意当吃到食物时,当前帧尾部节点不再删除,即可实现蛇身长度加 1。

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

    碰撞算法、边界条件

    当蛇头触碰到地图边缘,将 game over, 只需根据蛇头当前坐标、当前方向,计算下一步的坐标是否会超出地图尺寸即可。

    吃到食物的计算方法:分别对蛇头坐标和食物坐标的 x、y 轴进行绝对值计算,小于元素尺寸时认为已接触。

    // 更新校验
    function handleUpdateVerify() {
      if (status.value === 'pause') {
        clearInterval(process)
      }
    
      if (store.value >= 100) {
        status.value = 'success'
        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 即可通关。

    相关文章

    在线游戏
    在线游戏

    海量精品小游戏合集,无需安装即点即玩,休闲益智、动作闯关应有尽有,秒开即玩,轻松解压,快乐停不下来

    下载

    相关标签:

    本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

    热门AI工具

    更多
    切问学术

    切问学术是一款AI论文写作工具,复旦大学NLP团队推出的AI学术智能体。

    Lovart
    Lovart Hot

    一款面向视觉设计创作的AI设计平台,可通过智能体和画布工作流辅助制作海报、Logo、网页、PPT及其他视觉内容。

    UpDream
    UpDream Hot

    一款AI视频创作工具,主要用于哔哩哔哩推出的自研AI视频创作工具,适合需要提升相关任务效率的用户。

    Laper
    Laper Hot

    Laper是专为编剧、导演和制片人推出的 AI 原生剧本创作工具。

    豆包大模型

    豆包大模型是一款由字节跳动推出的企业级大语言模型服务平台。

    咔片AIPPT

    一款在线AI演示文稿制作工具,可根据主题和内容需求辅助生成PPT结构与页面,提高演示材料制作效率。

    WorkBuddy

    一款AI办公效率工具,主要用于腾讯云推出的AI原生桌面智能体工作台,适合需要提升相关任务效率的用户。

    花生AI
    花生AI Hot

    一款AI视频创作工具,主要用于B站推出的AI视频创作工具,适合需要提升相关任务效率的用户。

    DeepSeek

    DeepSeek是一款面向对话、写作、编程和推理场景的AI大模型工具。

    相关专题

    更多
    全局变量怎么定义
    全局变量怎么定义

    本专题整合了全局变量相关内容,阅读专题下面的文章了解更多详细内容。

    4945

    2025.09.18

    python 全局变量
    python 全局变量

    本专题整合了python中全局变量定义相关教程,阅读专题下面的文章了解更多详细内容。

    2090

    2025.09.18

    c++ 全局变量
    c++ 全局变量

    本专题整合了c++全局变量的使用、定义、作用域等等内容,阅读专题下面的文章了解更多详细内容。

    199

    2026.03.17

    堆和栈的区别
    堆和栈的区别

    堆和栈的区别:1、内存分配方式不同;2、大小不同;3、数据访问方式不同;4、数据的生命周期。本专题为大家提供堆和栈的区别的相关的文章、下载、课程内容,供大家免费下载体验。

    6447

    2023.07.18

    堆和栈区别
    堆和栈区别

    堆(Heap)和栈(Stack)是计算机中两种常见的内存分配机制。它们在内存管理的方式、分配方式以及使用场景上有很大的区别。本文将详细介绍堆和栈的特点、区别以及各自的使用场景。php中文网给大家带来了相关的教程以及文章欢迎大家前来学习阅读。

    2688

    2023.08.10

    DOM是什么意思
    DOM是什么意思

    dom的英文全称是documentobjectmodel,表示文件对象模型,是w3c组织推荐的处理可扩展置标语言的标准编程接口;dom是html文档的内存中对象表示,它提供了使用javascript与网页交互的方式。想了解更多的相关内容,可以阅读本专题下面的文章。

    6541

    2024.08.14

    html5动画制作有哪些制作方法
    html5动画制作有哪些制作方法

    html5动画制作方法有使用CSS3动画、使用JavaScript动画库、使用HTML5 Canvas等。想了解更多html5动画制作方法相关内容,可以阅读本专题下面的文章。

    4551

    2023.10.23

    canva可画使用技巧汇总
    canva可画使用技巧汇总

    本专题汇集了PHP中文网精心整理的Canva可画新手使用技巧大全,专为零基础用户打造。无论你是想制作精美海报、PPT还是社交媒体配图,这里都有从注册登录、模板搜索到AI辅助设计、导出分享的全流程保姆级教程。通过深入浅出的图文指南,帮助你快速跨越设计门槛,轻松掌握Canva可画的实用操作,让每个人都能成为设计达人!

    284

    2026.05.19

    Uvicorn 报错与问题解决教程
    Uvicorn 报错与问题解决教程

    本专题汇总了Uvicorn服务器常见问题与报错解决的教程合集,涵盖启动失败、端口占用、模块导入错误、事件循环冲突及热重载失效等典型故障的排查思路。同时整理了多进程与Worker配置、SSL/HTTPS证书报错、跨域与代理配置等实战解决方案,助你快速定位并解决Uvicorn运行中的各类问题。

    0

    2026.11.02

    热门下载

    更多
    网站特效
    /
    网站源码
    /
    网站素材
    /
    前端模板

    精品课程

    更多
    相关推荐
    /
    热门推荐
    /
    最新课程
    Canvas 绘制时钟
    Canvas 绘制时钟

    共7课时 | 1.7万人学习

    HTML5新特性基础视频教程
    HTML5新特性基础视频教程

    共18课时 | 3.8万人学习

    HTML5 Canvas 动画实战教程
    HTML5 Canvas 动画实战教程

    共28课时 | 7.2万人学习

    关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
    php中文网:公益在线php培训,帮助PHP学习者快速成长!
    关注服务号
    PHP中文网订阅号
    每天精选资源文章推送

    Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn