Unity小游戏——怪物出现模式的管理

news2024/10/11 8:24:30

摘要:游戏启动后不久,画面前方将出现怪物,游戏的目标是不停地看到怪物并持续前进

 

一、怪物出现的时间节点

我们首先来看如何来确定怪物出现的间隔。

  • 若是怪物相继出现的时间间隔很短,玩家就必须快速地点击按键,这样游戏就比较难。
  • 若是怪物出现的间隔较长,或者移动的速度比较慢,那么游戏就会比较简单

因此,我们首先考虑到怪物的运动速度和出现间隔=难易度,我们在每次成功攻击怪物后就增加游戏的难度(当然,要设置一个难度上限),并使食物后游戏会回到最初的状态。

每当武士前进了一段距离,怪物就将在其前方出现,正好位于画面之外即将进入画面的位置。如果这个距离过短,画面上会突然出现一个怪物。反之,则会导致在画面渲染区域之外存在许多怪物,增加不必要的开销。

在我们设计怪物出现模式的时候,需要算出武士从当前位置出发应当前进多远才让下一个怪物出现。如果玩家可以很顺利地斩杀怪物,就让这个距离越来越短,如果出现失误,则恢复到最初的长度。

这些时间间隔其实并不是一上来就得到的,都需要在玩的时候反复调整,最终得出合适的值。

 二、怪物出现模式的变化

虽然速度极快会导致游戏变难,不过反复是玩几次后我们就会发现完全能够适应。这主要是因为目前怪物出现的间隔是固定值的缘故。(究其原因是节奏一直不变,只要找到节奏就可以了)

其实原本为了是玩家能够体会到斩杀的爽快感,是要求游戏具备一定的节奏的。不过如果一直一成不变的节奏,太简单了,这样的游戏就有些无聊了。

也就是说,问题不在速度,而在于节奏。那么我们就可以尝试,每隔一段时间,就是用特别的出现模式。本游戏制作了以下几种和破铜模式不一样的特别模式

  • 连续:怪物短于正常时间的时间间隔涌上来
  • 缓慢:怪物移动的速度比一般模式的最低速度还慢,而且出现的时间间隔很长。我们在持续玩难度较大的关卡时会感到匹拉怕,因此可以插入这个模式来提供休息调整的机会
  • 赶超:后出现的怪物追赶并超越更早出现的怪物。后登场的怪物将会更早到达武士的位置,这会使玩家难于决定出手的时机,使其猝不及防。可以说这是比较难的一种模式
  • 加速->减速:登场的怪物到达画面中央附近为之后加速,快要接近武士时减速,然后再朝着五十前进。游戏的情景就好像伴随着“危险!快跑!”“不!这样不行!”这样的台词。相比用于控制游戏的难易度,这种模式更适合用于营造游戏的演示效果

我们把这四种特别模式和普通模式混在一起来控制怪物的出现。每经过若干次普通模式后,就随机选择一把特殊模式。普通模式的持续次数也通过随机决定

下面给出流程图

开始特别模式时,以及从特别模式恢复到普通模式时,必须确保画面中的怪物已经完全消失。这样可以防止特别模式和普通模式的怪物同时出现。

比如在“加速->减速”模式中怪物出现的情况。当一个怪物在画面右边加速前进时又出现了别的怪物,有时就会造成两个怪物以非常短的时间间隔到达武士的位置。

为了避免这种情况,需要在使用特别模式前后等待一段时间,直到画面上怪物的“编队”完全消失。

 下面展示具体代码(摘要)

	public void	oniAppearControl()
	{
//检查是否准备好了新生成的怪物
	if(this.can_dispatch) {

			// 已准备好生成下一个分组

		} else {

			// 未准备好生成下一个分组

			if(this.is_exclusive_group()) {     //检测现在是普通模式还是特别模式

				// 特别模式情况下,等待怪物从画面中消失

				if(GameObject.FindGameObjectsWithTag("OniGroup").Length == 0) {

					this.can_dispatch = true;
				}

			} else {

				// 普通模式下,马上产生
				this.can_dispatch = true;
			}
	if(this.can_dispatch) {

				// 准备好出现后,通过玩家的当前位置计算应该出现的位置

				if(this.group_type_next == GROUP_TYPE.NORMAL) {

					this.oni_generate_line = this.player.transform.position.x + this.next_line;

				} else if(this.group_type_next == GROUP_TYPE.SLOW) {

					this.oni_generate_line = this.player.transform.position.x + 50.0f;

				} else {

					this.oni_generate_line = this.player.transform.position.x + 10.0f;
				}
			}
		}
// 玩家前进了一定距离后,生成下一个分组

		do {

			if(this.scene_control.oni_group_num >= this.scene_control.oni_group_appear_max) {

				break;
			}
			if(!this.can_dispatch) {

				break;
			}
			if(this.player.transform.position.x <= this.oni_generate_line) {

				break;
			}

			//

			this.group_type = this.group_type_next;

			switch(this.group_type) {
	
				case GROUP_TYPE.SLOW:
				{
					this.dispatch_slow();
				}
				break;
	
				case GROUP_TYPE.DECELERATE:
				{
					this.dispatch_decelerate();
				}
				break;

				case GROUP_TYPE.PASSING:
				{
					this.dispatch_passing();
				}
				break;

				case GROUP_TYPE.RAPID:
				{
					this.dispatch_rapid();
				}
				break;

				case GROUP_TYPE.NORMAL:
				{
					this.dispatch_normal(this.next_speed);
				}
				break;
			}
	
			// 更新下次出现分组时的怪物数量
			// (逐渐增加)
			this.oni_appear_num++;
			this.oni_appear_num = Mathf.Min(this.oni_appear_num, SceneControl.ONI_APPEAR_NUM_MAX);

			this.can_dispatch = false;

			this.no_miss_count++;

			this.scene_control.oni_group_num++;
			
			if(this.is_random) {

				// 选择下次出现的分组
				this.select_next_group_type();
			}

		} while(false);
	}
  1. 首先,检查是否准备好了下一批怪物。
  2. 如果没做好生成怪物的准备,就检查现在和下一批怪物的出现模式使特别模式还是普通模式。如果现在或者下一批属于特别模式,那么this.is_exclusive_group()就会返回true,然后处于当前为普通模式当前为特别模式并且画面中已经没有怪物了的时候,可以生成下一批怪物
  3. 以现在的武士所在位置为基准,计算出怪物的生成位置。怪物从登场开始到消失为止武士前进的距离随各模式不同而不同。因此,需要再准备好生成怪物的时候,就定好怪物将要出现的位置
  4. 武士的位置超过oni_generate_line后生成新的怪物
  5. 最后,提前选择下一次将生成的怪物类型。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/789916.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

目前新能源汽车充电桩的发展受到哪些不利因素的影响?

目前新能源汽车充电桩的发展受到哪些不利因素的影响? 一是安装难&#xff0c;很多老旧小区没有充电桩配套施工规范&#xff0c;充电桩建设比较难&#xff0c;受到充电容量不足电表箱供电等局限性的制约&#xff0c;同时缺乏充电桩配套设施的统一规划&#xff0c;小区内只能安装…

元学习(小样本)-基本概念

机器学习 概述 以分类任务为例&#xff0c;机器学习可以看作是找一个猫狗的分类函数。 step1: 设计未知函数&#xff1b;其中&#xff0c;权重和偏置都是神经元中位置参数&#xff08;可学习的&#xff09;&#xff1b;step2: 定义损失函数&#xff1b;step3&#xff1a;训练…

SpringBoot----(1)基础

目录 1 SpringBoot简介1.1 入门案例&#xff08;IDEA构建&#xff09;1.2 官网构建工程1.3 SpringBoot程序快速启动1.4 SpringBoot概述1.5 起步依赖1.6 程序启动1.7 切换web服务器 2 配置2.1 配置文件格式&#xff08;3种&#xff09;2.2 yaml格式2.3 yaml数据读取方式&#xf…

Maven-----进阶

目录 1 分模块开发1.1 分模块开发的意义1.2 分模块开发实现 2 依赖管理2.1 依赖传递2.2 依赖传递冲突问题2.3 可选依赖和排除依赖 3 继承与聚合3.1 聚合3.2 继承3.2 聚合与继承的区别 4 属性4.1 属性4.2 资源文件引用属性4.3 版本管理 5 多环境配置与使用5.1 多环境开发5.2 跳过…

【JavaSE】类和对象的封装

目录 【1】封装 【1.1】封装的概念 【1.2】访问限定符 【1.3】封装扩展之包 【1.3.1】包的概念 【1.3.2】导入包中的类 【1.3.3】自定义包 【1.3.4】包的访问权限控制举例 【1.3.5】常见的包 【2】static成员 【2.1】再谈学生类 【2.2】static修饰成员变量 【2.3】…

量子力学的应用:量子计算

亲爱的读者&#xff0c; 欢迎回到我们的量子力学系列文章。在前面的几篇文章中&#xff0c;我们已经深入探讨了量子力学的起源、基本概念、实验验证以及解释问题。今天&#xff0c;我们将聚焦在量子力学的一个引人注目的应用领域&#xff1a;量子计算。 1. 传统计算机与量子计…

【雕爷学编程】Arduino动手做(86)---4*4位 WS2812 全彩模块2

37款传感器与执行器的提法&#xff0c;在网络上广泛流传&#xff0c;其实Arduino能够兼容的传感器模块肯定是不止这37种的。鉴于本人手头积累了一些传感器和执行器模块&#xff0c;依照实践出真知&#xff08;一定要动手做&#xff09;的理念&#xff0c;以学习和交流为目的&am…

【图解CAN总线】-9-详述经典CAN和CANFD报文是如何收发的

目录 1 经典CAN/CANFD网络拓扑分解 2 CAN收发器“前后端的电平” 3 图解MCU芯片与CAN物理总线之间CAN报文收发过程 3.1 TX&#xff0c;RX和CAN H/L电平变化&#xff1a;ECU接收一个报文 3.2 TX&#xff0c;RX和CAN H/L电平变化&#xff1a;ECU发送一个报文 END 推荐阅读&…

【LeetCode】48.旋转图像

题目 给定一个 n n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像&#xff0c;这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 示例 1&#xff1a; 输入&#xff1a;matrix [[1,2,3],[4,5,6],[7,8,9]…

OPC通信从入门到精通_1_OPC基础知识及简单C#程序编写(OPCDA,OPCUA简介;OPC通信数据流框架图;C#程序编写)

文章目录 1. OPC基础知识&#xff1a;OPCDA&#xff0c;OPCUA1.1 OPC基础知识1.2 OPC通信读写方式 2. OPC通信仿真2.1 上位机与PLC通过ModbusTCP直接通信2.2 OPC通信介绍及实例2.2.1 OPC通信与ModbusTCP比较2.2.2 OPC通信应用场景2.2.3 OPC DA通信仿真实例2.2.4 OPC UA通信仿真…

随手笔记——3D−3D:ICP理论

随手笔记——3D−3D&#xff1a;ICP理论 说明SVD 方法非线性优化方法 说明 ICP 的求解也分为两种方式&#xff1a;利用线性代数的求解&#xff08;主要是 SVD&#xff09;&#xff0c;以及利用非线性优化方式的求解&#xff08;类似于 Bundle Adjustment&#xff09;。 SVD 方…

Android平台GB28181设备接入模块之按需编码和双码流编码

技术背景 我们在做执法记录仪或指挥系统的时候&#xff0c;会遇到这样的情况&#xff0c;大多场景下&#xff0c;我们是不需要把设备端的数据&#xff0c;实时传给国标平台端的&#xff0c;默认只需要本地录像留底&#xff0c;如果指挥中心需要查看前端设备实时数据的时候&…

【LeetCode热题100】打卡第44天:倒数第30~25题

文章目录 【LeetCode热题100】打卡第44天&#xff1a;倒数第30~25题⛅前言 移动零&#x1f512;题目&#x1f511;题解 寻找重复数&#x1f512;题目&#x1f511;题解 二叉树的序列化与反序列化&#x1f512;题目&#x1f511;题解 最长递增子序列&#x1f512;题目&#x1f5…

力扣 763. 划分字母区间

题目来源&#xff1a;https://leetcode.cn/problems/partition-labels/description/ C题解1&#xff1a; 先遍历一遍使用哈希算法找到每个小写字母的最远的索引&#xff0c;再遍历一次&#xff0c;不断更新每个片段的最远距离。 class Solution { public:vector<int> pa…

Qt Core学习日记——第八天QMetaObject(下)

QMetaObject::normalizedType 将名称规范化。 例如&#xff1a; QByteArray normType QMetaObject::normalizedType(" int const *"); // normType is now "const int*" QMetaObject::connect(const QObject *sender, int signal_index, const QObject…

redis(12):springboot使用redis注解做缓存

1 新建springboot项目 2 相关注解 EnableCaching 在启动类上加上注解启动缓存 #作用在你要缓存的数据上 Cacheable(key"#id",cacheNames"com.sxt.service.impl.MenuServiceImpl") Cacheput 解决脏读 CachEvict&#xff08;解决脏读&#xff09; Cach…

01Mybatis报错日志 BindingException

01 Mybatis报错日志 BindingException Type interface com.zhnx.demo1.mapper.UserMapper is not known to the MapperRegistry. org.apache.ibatis.binding.BindingException: Type interface com.zhnx.demo1.mapper.UserMapper is not known to the MapperRegistry.at org…

腾讯云服务器公共镜像大全_Linux和Windows操作系统

腾讯云CVM服务器的公共镜像是由腾讯云官方提供的镜像&#xff0c;公共镜像包含基础操作系统和腾讯云提供的初始化组件&#xff0c;公共镜像分为Windows和Linux两大类操作系统&#xff0c;如TencentOS Server、Windows Server、OpenCloudOS、CentOS Stream、CentOS、Ubuntu、Deb…

LeetCode116. 填充每个节点的下一个右侧节点指针

116. 填充每个节点的下一个右侧节点指针 文章目录 [116. 填充每个节点的下一个右侧节点指针](https://leetcode.cn/problems/populating-next-right-pointers-in-each-node/)一、题目二、题解方法一&#xff1a;迭代方法二&#xff1a;递归 一、题目 给定一个 完美二叉树 &…

redis的并发安全问题:redis的事务VSLua脚本

redis为什么会发生并发安全问题&#xff1f; 在redis中&#xff0c;处理的数据都在内存中&#xff0c;数据操作效率极高&#xff0c;单线程的情况下&#xff0c;qps轻松破10w。反而在使用多线程时&#xff0c;为了保证线程安全&#xff0c;采用了一些同步机制&#xff0c;以及多…