Unity3D 小案例 像素贪吃蛇 01 蛇的移动
Unity3D 小案例 像素贪吃蛇 第一期 蛇的移动
像素贪吃蛇
今天来简单制作一个小案例,经典的像素贪吃蛇。
准备
首先调整一下相机的设置,这里使用灰色的纯色背景,正交视图。

接着,创建一个正方形,保存为预制体,一个蛇头,一个蛇身。蛇身稍微调成灰色。

初始生成
创建脚本 Snake.cs,挂到 Snake 预制体上。
这里先定义初始身体数量,身体预制体,身体列表。
在 Start 方法里,初始生成一定数量的身体。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Snake : MonoBehaviour
{public int initBodyCount = 3; // 初始身体数量public GameObject body; // 身体预制体List<GameObject> bodyList = new List<GameObject>(); // 身体列表void Start(){// 初始生成身体for (int i = 0; i < initBodyCount; i++){GenerateBody();}}/// <summary>/// 生成身体/// </summary>void GenerateBody(){GameObject obj = Instantiate(body);// 已有身体if (bodyList.Count > 0){// 获取最后一个身体,在它的位置生成GameObject lastBody = bodyList[bodyList.Count - 1];obj.transform.position = lastBody.transform.position;}// 没有身体else{// 以蛇头的位置生成身体obj.transform.position = transform.position;}bodyList.Add(obj);}
}
拖拽预制体引用,然后覆盖到预制体。
场景里面的 SnakeBody 可以删掉。

运行游戏,会在蛇头的位置生成三个身体,此时身体都是重叠的。
蛇的移动
定义移动方向和移动速度,在 Start 方法中,调用 InvokeRepeating 定时器,根据速度计算出定时器的调用时间间隔,每次调用 Move 方法往当前方向移动。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Snake : MonoBehaviour
{// ...public Vector2 direction = Vector2.right; // 移动方向public float speed = 1; // 移动速度void Start(){// ...float time = 1 / speed;InvokeRepeating(nameof(Move), time, time);}/// <summary>/// 移动/// </summary>void Move(){transform.Translate(direction);}
}
此时只有蛇头会移动,身体是不动的。
要让身体跟着蛇头移动,需要在蛇头移动前,标记位置,再把旧的位置赋值给第一个身体。
第一个身体移动前,也要先标记位置,然后赋值给第二个身体。
所以要使用两个 Vector2 变量,循环标记。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Snake : MonoBehaviour
{// ...Vector2 posMarkFirst; // 第一个标记位置Vector2 posMarkLast; // 第二个标记位置// .../// <summary>/// 移动/// </summary>void Move(){// 移动前,先标记旧的位置posMarkFirst = transform.position;transform.Translate(direction);for (int i = 0; i < bodyList.Count; i++){// 利用奇偶数,交替标记旧的位置if (i % 2 == 0){posMarkLast = bodyList[i].transform.position;bodyList[i].transform.position = posMarkFirst;}else{posMarkFirst = bodyList[i].transform.position;bodyList[i].transform.position = posMarkLast;}}}
}
运行游戏,可以看到,蛇开始移动了。

控制方向
在 Update 方法中,获取键盘输入,改变蛇头的移动方向。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Snake : MonoBehaviour
{// ...void Update(){float h = Input.GetAxisRaw("Horizontal");float v = Input.GetAxisRaw("Vertical");// 检测到按键输入if(h != 0 || v != 0){// 改变蛇头的方向direction.x = h;direction.y = v;}}
}
运行游戏,可以通过键盘方向键,改变蛇的移动方向。

但是问题来了,如上图所示,蛇头可以往反方向移动,还可以斜着移动,这些都是需要排除的情况。
简单分析一下,蛇头的移动方向,用二维向量来变量,有四种情况。
- 向上
(0, 1) - 向下
(0, -1) - 向左
(-1, 0) - 向右
(1, 0)
当蛇头向右移动时,如果按键输入向左,那么 X 坐标相加等于 0。
同理,向上移动时,如果按键输入向下,那么 Y 坐标相加等于 0。
所以在改变方向时,判断当前方向和按键输入方向的相加情况,进行排除。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Snake : MonoBehaviour
{// ...void Update(){float h = Input.GetAxisRaw("Horizontal");float v = Input.GetAxisRaw("Vertical");// 检测到按键输入if(h != 0 || v != 0){if (direction.x + h == 0 || direction.y + v == 0) return;// 改变蛇头的方向direction.x = h;direction.y = v;}}
}
斜着移动时,也有四种情况。
- 左上
(-1, 1) - 右上
(1, 1) - 左下
(-1, -1) - 右下
(1, -1)
它们的规律是,要么 X 坐标和 Y 坐标相等,要么 X 坐标和 Y 坐标相加等于 0。
所以在改变方向时,判断以上情况,进行排除。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Snake : MonoBehaviour
{// ...void Update(){float h = Input.GetAxisRaw("Horizontal");float v = Input.GetAxisRaw("Vertical");// 检测到按键输入if(h != 0 || v != 0){if (direction.x + h == 0 || direction.y + v == 0) return;if (h == v || h + v == 0) return;// 改变蛇头的方向direction.x = h;direction.y = v;}}
}
但是还没有完全解决问题,当蛇头向右移动时,如果快速按向上键,再按向左键,蛇头依然会往反方向移动,因为以上规则在二次按键时,可以顺利切换方向。
所以,每当定时器触发移动时,还需要再进行方向修正。
我们可以先记录第一次按键的方向,此时该方向是合理的。当触发移动时,如果当前方向和上次移动的方向正好相反,那么判定当前方向是进行了二次按键,把当前方向修正为第一次按键的合理方向。
using System.Collections;
using System.Collections.Generic;
using UnityEngine;public class Snake : MonoBehaviour
{// ...public Vector2 lastDirection = Vector2.right; // 上次的移动方向public Vector2 firstDirection = Vector2.right; // 第一次按键的移动方向public bool firstPress = true; // 是否记录第一次按键void Update(){float h = Input.GetAxisRaw("Horizontal");float v = Input.GetAxisRaw("Vertical");// 检测到按键输入if(h != 0 || v != 0){if (direction.x + h == 0 || direction.y + v == 0) return;if (h == v || h + v == 0) return;// 改变蛇头的方向direction.x = h;direction.y = v;// 仅记录第一次按键if (firstPress){firstPress = false;firstDirection.x = h;firstDirection.y = v;}}}/// <summary>/// 移动/// </summary>void Move(){// 当前移动方向和上次方向相反,修正为第一次按键的方向if (direction.x + lastDirection.x == 0 || direction.y + lastDirection.y == 0){direction.x = firstDirection.x;direction.y = firstDirection.y;}// 移动前,先标记旧的位置posMarkFirst = transform.position;transform.Translate(direction);// 记录上次的移动方向lastDirection = direction;// 可重新记录第一次按键的移动方向firstPress = true;// ...}
}
最终的移动效果。

相关文章:
Unity3D 小案例 像素贪吃蛇 01 蛇的移动
Unity3D 小案例 像素贪吃蛇 第一期 蛇的移动 像素贪吃蛇 今天来简单制作一个小案例,经典的像素贪吃蛇。 准备 首先调整一下相机的设置,这里使用灰色的纯色背景,正交视图。 接着,创建一个正方形,保存为预制体&#…...
【STM32 MCU】stm32MCUs 32-bit Arm Cortex-M
stm32MCUs 32-bit Arm Cortex-M...
html+css网页设计 旅游 雪花旅行社5个页面
htmlcss网页设计 旅游 雪花旅行社5个页面 网页作品代码简单,可使用任意HTML辑软件(如:Dreamweaver、HBuilder、Vscode 、Sublime 、Webstorm、Text 、Notepad 等任意html编辑软件进行运行及修改编辑等操作)。 获取源码 1&#…...
vue3中的实例
实例类型 Vue2:每个Vue应用都是new Vue创建的一个新实例,创建的时候将data作为property添加到响应式系统中 vue3:createApp创建一个Application Instance、应用实例用来注册全局内容,大多数方法支持链式调用,返回实例…...
9.测试计划(包含笔试/面试题)
一、软件测试计划介绍 1.测试计划就是一份测试文档,一份描述测试工作计划的文档,对测试计划进行统筹安排。 2.测试计划的编写者就是测试组长,测试主管。 3.测试计划的查阅者:测试人员,测试主管,产品&#x…...
这 7 款AI应用将让你全新的iPhone 16成为电影制作的强大工具
苹果公司在周一的Glowtime发布会上揭晓了新款的iPhone 16 Pro系列。除了新加入的苹果智能功能和令人印象深刻的硬件升级外,它还获得了一套视频制作工具,让用户能够在一个几乎可以放进口袋的设备上制作整部电影。 这些升级中有一个48MP融合相机。它具有2…...
自注意力机制(self-attention)
自注意力机制(self-attention) 之前听过吴恩达老师的课,吴恩达老师CNN那一块讲的特别好,但是后面RNN这一部分我听的不是很明白,今天有看了李宏毅老师attention这部分的课,总结一下笔记。 self-attention …...
Nuxt3入门:过渡效果(第5节)
你好同学,我是沐爸,欢迎点赞、收藏、评论和关注。 Nuxt 利用 Vue 的 <Transition> 组件在页面和布局之间应用过渡效果。 一、页面过渡效果 你可以启用页面过渡效果,以便对所有页面应用自动过渡效果。 nuxt.config.js export defaul…...
【开发工具】IntelliJ IDEA插件推荐:Json Helper——让JSON处理更高效
导语:在Java开发过程中,JSON作为一种轻量级的数据交换格式,被广泛应用于前后端数据交互。今天,我要为大家介绍一款IntelliJ IDEA插件——Json Helper,帮助开发者更高效地处理JSON数据。 一、什么是Json Helper&#x…...
Lua垃圾回收机制
Lua垃圾回收机制 在 Lua 中,一共只有8种数据类型,分别为 nil 、boolean 、userdata 、number 、string 、 table 、 function 、 userdata 和 thread 。其中,只有 string table function thread 四种是以引用方式共享,是需要被 G…...
Java学习路线:详细指引
Java学习路线可以分为几个阶段,每个阶段都有其重点和推荐学习的内容。下面我将按照初学者、进阶和高级三个阶段来举例说明: 初学者阶段 目标: 熟悉Java基础语法理解面向对象编程掌握基本数据类型和数据结构学会使用IDE(如Intel…...
商家转账到零钱如何开通-微信支付
商家转账到零钱是微信支付的一项实用功能,允许商户将资金从商户号余额直接转账到用户的微信零钱。我们以上万次成功申请的经验整理了本文的详细的步骤和建议以帮助商户可以快速开通该功能。 1. 准备工作 - 确认申请资格:只有公司性质的商户可以申请此功能…...
自研商家如何快速接入电商平台订单数据?
随着电子商务行业的快速发展,越来越多的商家开始寻求高效的订单管理和数据整合方案。对于那些自研系统的商家来说,如何实现与各大电商平台之间的无缝对接,成为了一项重要挑战。点三电商API正是为此类需求量身打造,为商家提供了一站…...
Win10下借助CMake编译OpenMVS
笔者在编译OpenMVS的过程十分曲折。刚开始借助CMake编译,能够把与库生成相关的工程编译出来,但是与可执行文件相关的工程会报错;后来参考官方教程借助VCPKG编译,发现VCPKG并没有想中强大、好用,最终也是遇到了各种问题没有编译成功。但是,笔者在解决问题的过程发现了问题…...
04_定时器与数码管基础
通过上节课的实验,大家会发现,我们逐渐进入比较实质性的学习了,需要记住的内容也更多了,个别地方可能会感觉吃力。但是大家不要担心,要有信心。这个跟小孩学走路一样,刚开始走得不太稳,没关系&a…...
Python 数学建模——方差分析
文章目录 前言单因素方差分析原理核心代码 双因素方差分析数学模型分析依据典型代码 前言 方差分析也是概率论中非常重要的内容,有时数学建模需要用到。方差分析是干什么的?如果说假设检验用于分析两个总体之间的均值 μ 1 , μ 2 \mu_1,\mu_2 μ1,μ…...
计算机视觉中,什么是上下文信息(contextual information)?
在计算机视觉中,上下文信息(contextual information)是指一个像素或一个小区域周围的环境或背景信息,它帮助模型理解图像中对象的相对位置、大小、形状,以及与其他对象的关系。上下文信息在图像中提供了全局的语义和结…...
YOLOv5改进 | 模块缝合 | C3 融合RVB + EMA注意力机制【二次融合】
秋招面试专栏推荐 :深度学习算法工程师面试问题总结【百面算法工程师】——点击即可跳转 💡💡💡本专栏所有程序均经过测试,可成功执行💡💡💡 专栏目录 :《YOLOv5入门 改…...
mysql 更改默认端口号 新增用户密码 赋予权限
默认情况下,mysql的端口是3306,超级用户是root,很多情况下会被黑客扫描到,成为肉鸡(作者以前就有过经理),数据库表直接丢失,勒索我。 所以我这里介绍下,更改默认端口&am…...
吐血整理nacos 作为springcloud的配置中心和注册中心
吐血整理nacos 作为配置中心和注册中心 环境版本nacos 版本 nacos启动单机模式启动配置数据库 Spring cloud 连接注册Nacos配置中心导入依赖 注册中心 环境版本 SpringBoot版本SpringCloud版本cloud Alibaba版本2.6.132021.0.52021.0.5.0 参照依据 spring-cloud-alibab 对应…...
铭豹扩展坞 USB转网口 突然无法识别解决方法
当 USB 转网口扩展坞在一台笔记本上无法识别,但在其他电脑上正常工作时,问题通常出在笔记本自身或其与扩展坞的兼容性上。以下是系统化的定位思路和排查步骤,帮助你快速找到故障原因: 背景: 一个M-pard(铭豹)扩展坞的网卡突然无法识别了,扩展出来的三个USB接口正常。…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
51c自动驾驶~合集58
我自己的原文哦~ https://blog.51cto.com/whaosoft/13967107 #CCA-Attention 全局池化局部保留,CCA-Attention为LLM长文本建模带来突破性进展 琶洲实验室、华南理工大学联合推出关键上下文感知注意力机制(CCA-Attention),…...
树莓派超全系列教程文档--(61)树莓派摄像头高级使用方法
树莓派摄像头高级使用方法 配置通过调谐文件来调整相机行为 使用多个摄像头安装 libcam 和 rpicam-apps依赖关系开发包 文章来源: http://raspberry.dns8844.cn/documentation 原文网址 配置 大多数用例自动工作,无需更改相机配置。但是,一…...
2025年能源电力系统与流体力学国际会议 (EPSFD 2025)
2025年能源电力系统与流体力学国际会议(EPSFD 2025)将于本年度在美丽的杭州盛大召开。作为全球能源、电力系统以及流体力学领域的顶级盛会,EPSFD 2025旨在为来自世界各地的科学家、工程师和研究人员提供一个展示最新研究成果、分享实践经验及…...
1688商品列表API与其他数据源的对接思路
将1688商品列表API与其他数据源对接时,需结合业务场景设计数据流转链路,重点关注数据格式兼容性、接口调用频率控制及数据一致性维护。以下是具体对接思路及关键技术点: 一、核心对接场景与目标 商品数据同步 场景:将1688商品信息…...
苍穹外卖--缓存菜品
1.问题说明 用户端小程序展示的菜品数据都是通过查询数据库获得,如果用户端访问量比较大,数据库访问压力随之增大 2.实现思路 通过Redis来缓存菜品数据,减少数据库查询操作。 缓存逻辑分析: ①每个分类下的菜品保持一份缓存数据…...
python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)
更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...
【git】把本地更改提交远程新分支feature_g
创建并切换新分支 git checkout -b feature_g 添加并提交更改 git add . git commit -m “实现图片上传功能” 推送到远程 git push -u origin feature_g...
html-<abbr> 缩写或首字母缩略词
定义与作用 <abbr> 标签用于表示缩写或首字母缩略词,它可以帮助用户更好地理解缩写的含义,尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时,会显示一个提示框。 示例&#x…...
