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 对应…...
生成xcframework
打包 XCFramework 的方法 XCFramework 是苹果推出的一种多平台二进制分发格式,可以包含多个架构和平台的代码。打包 XCFramework 通常用于分发库或框架。 使用 Xcode 命令行工具打包 通过 xcodebuild 命令可以打包 XCFramework。确保项目已经配置好需要支持的平台…...
微软PowerBI考试 PL300-选择 Power BI 模型框架【附练习数据】
微软PowerBI考试 PL300-选择 Power BI 模型框架 20 多年来,Microsoft 持续对企业商业智能 (BI) 进行大量投资。 Azure Analysis Services (AAS) 和 SQL Server Analysis Services (SSAS) 基于无数企业使用的成熟的 BI 数据建模技术。 同样的技术也是 Power BI 数据…...
【大模型RAG】Docker 一键部署 Milvus 完整攻略
本文概要 Milvus 2.5 Stand-alone 版可通过 Docker 在几分钟内完成安装;只需暴露 19530(gRPC)与 9091(HTTP/WebUI)两个端口,即可让本地电脑通过 PyMilvus 或浏览器访问远程 Linux 服务器上的 Milvus。下面…...
Java多线程实现之Callable接口深度解析
Java多线程实现之Callable接口深度解析 一、Callable接口概述1.1 接口定义1.2 与Runnable接口的对比1.3 Future接口与FutureTask类 二、Callable接口的基本使用方法2.1 传统方式实现Callable接口2.2 使用Lambda表达式简化Callable实现2.3 使用FutureTask类执行Callable任务 三、…...
全面解析各类VPN技术:GRE、IPsec、L2TP、SSL与MPLS VPN对比
目录 引言 VPN技术概述 GRE VPN 3.1 GRE封装结构 3.2 GRE的应用场景 GRE over IPsec 4.1 GRE over IPsec封装结构 4.2 为什么使用GRE over IPsec? IPsec VPN 5.1 IPsec传输模式(Transport Mode) 5.2 IPsec隧道模式(Tunne…...
如何理解 IP 数据报中的 TTL?
目录 前言理解 前言 面试灵魂一问:说说对 IP 数据报中 TTL 的理解?我们都知道,IP 数据报由首部和数据两部分组成,首部又分为两部分:固定部分和可变部分,共占 20 字节,而即将讨论的 TTL 就位于首…...
HDFS分布式存储 zookeeper
hadoop介绍 狭义上hadoop是指apache的一款开源软件 用java语言实现开源框架,允许使用简单的变成模型跨计算机对大型集群进行分布式处理(1.海量的数据存储 2.海量数据的计算)Hadoop核心组件 hdfs(分布式文件存储系统)&a…...
Docker 本地安装 mysql 数据库
Docker: Accelerated Container Application Development 下载对应操作系统版本的 docker ;并安装。 基础操作不再赘述。 打开 macOS 终端,开始 docker 安装mysql之旅 第一步 docker search mysql 》〉docker search mysql NAME DE…...
MySQL 知识小结(一)
一、my.cnf配置详解 我们知道安装MySQL有两种方式来安装咱们的MySQL数据库,分别是二进制安装编译数据库或者使用三方yum来进行安装,第三方yum的安装相对于二进制压缩包的安装更快捷,但是文件存放起来数据比较冗余,用二进制能够更好管理咱们M…...
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的“no matching...“系列算法协商失败问题
【SSH疑难排查】轻松解决新版OpenSSH连接旧服务器的"no matching..."系列算法协商失败问题 摘要: 近期,在使用较新版本的OpenSSH客户端连接老旧SSH服务器时,会遇到 "no matching key exchange method found", "n…...
