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 对应…...

【秋招笔试】9.09阿里国际秋招(已改编)-三语言题解
🍭 大家好这里是 春秋招笔试突围,一起备战大厂笔试 💻 ACM金牌团队🏅️ | 多次AK大厂笔试 | 大厂实习经历 ✨ 本系列打算持续跟新 春秋招笔试题 👏 感谢大家的订阅➕ 和 喜欢💗 和 手里的小花花🌸 ✨ 笔试合集传送们 -> 🧷春秋招笔试合集 🍒 本专栏已收集…...

sql语句在sqlserver中能查询出结果,但是代码中查不出来
右键登录名,选择属性,勾选下面两张图片中的项,即可。...

【机器学习】决策树与随机森林:模型对比与应用案例分析
文章目录 一.引言 在现代数据科学的世界中,决策树和随机森林是两个非常重要且广泛使用的机器学习算法。它们不仅因其高效性和强大的表现力而受到青睐,而且在解决实际问题时也表现出了令人印象深刻的能力。本篇文章将深入探讨这两个算法,帮助读…...

Apache SeaTunnel基础介绍
一、什么是Apache SeaTunnel? Apache SeaTunnel(最初名为Waterdrop)是一个开源的分布式数据集成平台,专为大规模数据处理设计。SeaTunnel可以从多种数据源读取数据,进行实时流式处理或批处理,然后将处理后…...

阿里旗下土耳其电商Trendyol计划进军欧洲市场
阿里旗下土耳其电商Trendyol计划进军欧洲市场 近年来,阿里巴巴集团在全球电商领域的布局持续深化,其旗下土耳其电商巨头Trendyol更是凭借其出色的市场表现和强劲的增长势头,成为了备受瞩目的焦点。近日,Trendyol宣布了一项重要战…...

IBM中国研发裁员与AIGC浪潮下的中国IT产业新篇章:挑战、机遇与未来展望
文章目录 一、跨国公司战略调整与全球IT版图的重构1. 跨国公司的战略考量2. 中国IT产业的应对策略 二、人才市场的深刻变革与应对策略1. 人才流失与再就业压力2. 人才培养与引进策略3. 个人职业规划与发展 三、AIGC浪潮下的中国IT产业新机遇1. AIGC技术的潜力与前景2. 中国IT产…...

基于Python的影视推荐平台的设计与实现--附源码79147
摘要 本论文主要论述了如何基于Python和大数据开发一个影视推荐平台,本系统将严格按照软件开发流程进行各个阶段的工作,面向对象编程思想进行项目开发。在引言中,作者将论述影视推荐平台的当前背景以及系统开发的目的,后续章节将严…...

Baumer工业相机堡盟工业相机如何通过BGAPISDK使用短曝光功能(曝光可设置1微秒)(C语言)
Baumer工业相机堡盟工业相机如何通过BGAPISDK使用短曝光功能(曝光可设置1微秒)(C语言) Baumer工业相机Baumer工业相机BGAPISDK和短曝光功能的技术背景Baumer工业相机通过BGAPISDK使用短曝光功能1.引用合适的头文件2.通过BGAPISDK使…...

Ubuntu 安装PostgreSQL
安装 PostgreSQL 包: 使用 apt-get 命令安装 PostgreSQL 客户端和服务器包:sudo apt update sudo apt install postgresql postgresql-client启动 PostgreSQL 服务: 在 Ubuntu 中,PostgreSQL 服务默认会自动启动。你可以使用以下命…...

sqlalchemy FastAPI 前端实现数据库增删改查
sqlalchemy FastAPI 前端实现数据库增删改查 仅个人学习笔记,感谢点赞关注! 知识点 连接数据库sqlalchemy 创建表结构FastAPI get post put delete操作FastAPI 请求体 路径和修改参数 依赖项 代码 # -*- ecoding: utf-8 -*- # Author: SuperLong # Em…...