创造一个 Da○saba○ber(第 3 号)

由于内部培训和其他一些事情,我已经有一段时间没有更新了。
大家做得都很棒。
我是系统开发部的松山。

我们很高兴推出“创建 Da○saba○bar”的第三期,该期在上一期中突然开始。

第一期内容在此↓

创建 Da○saba○bar(第一期)

第二期在此 ↓

创建 Da○saba○ber(第 2 号)

在第二版中,我们加入了三种玩家可以使用的武器(最高等级3级)。
在第三版中,我们将加入僵尸生态系统(生成和移动)以及使用收集到的经验值升级系统。

僵尸创造

从游戏系统角度来看,这似乎是一款生存类游戏,所以我认为需要随着时间推移增加出现的僵尸数量。
因此,我准备了两种生成方式。

① 单个敌人定期出现(间隔短)
② 大量敌人定期出现(间隔长)(波次)

①旨在让玩家在初始武器等级较低时更容易逐步获取经验值。②
旨在让玩家在逃离大批敌人的同时提升武器等级,并在武器等级足够高时提供进入屠杀模式的刺激感。

这两个事件都应该在距离玩家一定距离处触发。
此外,应该使用协程来处理等待时间。

逐个生成的过程如下:

private IEnumerator spawnBase() { const int MAX_BASE_ENEMYS = 50; const float spawnRadiusMin = 8.0f; const float spawnRadiusMax = 10.0f; const float spawnInterval = 1f; var waitTime = new WaitForSeconds(spawnInterval); while(true) { // 生成敌人,确保敌人数量始终为 MAX if(enemies.Count < MAX_BASE_ENEMYS) { // 玩家位置 Vector2 playerPos = playerController.GetPlayer().Position; // 确定放置半径 float r = UnityEngine.Random.Range(spawnRadiusMin, spawnRadiusMax); // 确定放置角度 float angle = UnityEngine.Random.Range(0, 360); // 生成 spawn(playerPos, r, angle); } yield return waitTime; } else { yield return null; } }

- 每秒生成
- 最多 50 个单位
- 位于距离玩家 8.0 到 10.0 个单位的位置
- 以 0.0 到 360.0 个单位的角度随机生成 -
使用生成函数实例化
。这就是它们的生成方式。

第二波的基本实现方式与第一波相同。
坐标、角度和生成过程都会重复,以生成一定数量的僵尸。
生成的僵尸数量会逐渐增加,第二波生成的僵尸数量比第一波更多。这里
仅摘录了这部分内容。

// 确定每波敌人的生成数量(最多 100 个) float spawnNum = Mathf.Min(wave * 10, MaxSpawnNum); // 等距放置 float angleRange = 360 / spawnNum; // 玩家位置 Vector2 playerPos = playerController.GetPlayer().Position; // 生成 for(int i = 0; i < spawnNum; i++) { // 确定放置半径 float r = spawnRadiusMax + UnityEngine.Random.Range(-1.0f, 1.0f); // 确定放置角度 float angle = angleRange * i; // 生成 spawn(playerPos, r, angle); }

它长这样。

僵尸运动

这是我观看原版后得到的印象:
- 它比玩家慢
- 它向玩家移动 -
它的跟踪能力似乎很低
,所以处理过程应该
① 找到一个指向玩家的向量
② 朝该方向移动一段时间
③ 返回到 ①
是这样的:

private void walk() { // 行走 this.transform.localPosition += new Vector3(walkInfo.course.x * WalkSpeed * Time.deltaTime, walkInfo.course.y * WalkSpeed * Time.deltaTime, 0); // 更新计时器 walkInfo.timer -= Time.deltaTime; // 当计时器低于 0 时重置 if(walkInfo.timer < 0) { walkInfo.timer = walkInfo.interval; // 计时器 walkInfo.course = (walkInfo.player.Position - this.transform.localPosition).normalized; // 行走方向 } }

程序无法停止,所以你只需要每帧运行 Update() 函数即可。

它长这样。

经验值

我不确定“经验值”这个词是否准确,但它就是你用来获取武器和升级的那种东西。
当你击败僵尸时,经验值会被放置,当玩家靠近时,经验值就会被收集。
当僵尸死亡动画结束时,Enemy 类会通过 ExpController 类生成一个 Exp 对象。

生成过程

public void OnAnimationEnd() { // 死亡动画结束后销毁 if (status == Status.Dead) { expController.Spawn(this.transform.localPosition); Destroy(this.gameObject); } }

该收集过程通过使用 Vector2.Distance 函数计算到玩家的距离,并将阈值范围内的物体向玩家坐标移动来实现。此过程也在协程中处理。

收集过程

private IEnumerator move() { var elapsedTime = 0f; var startPosition = transform.localPosition; while (elapsedTime < 1f) { var targetPosition = playerController.GetPosition(); elapsedTime += Time.deltaTime * MoveSpeed; transform.localPosition = Vector2.Lerp(startPosition, targetPosition, elapsedTime); yield return null; } Destroy(gameObject); }

它长这样。

武器等级界面

就是那种积累一定经验值后就能获得武器或升级的机制。
我们已经在版本 2 中实现了每种武器的等级控制,所以我们会让它可以通过用户界面进行控制。

- 灰色背景:面板
- 武器图标:按钮
- 文字和星星:文字
通过组合这些元素,您可以创建出类似这样的效果。

这是成品

将此实现与第一个和第二个问题结合起来,它看起来会像这样。

看起来不错,你觉得呢?
接下来,
玩家生命值管理
、时间限制
和磁铁等元素
,让它更加完善。

整个项目和往常一样都已发布在 GitHub 上。
这篇博文包含大量源代码,所以如果您想查看完整内容,请前往 GitHub 查看。希望它能对您
有所帮助。BeBe
Survivor

好了,今天就到这里。

第一期内容请点击此处查看↓
https://beyondjapan.com/blog/2024/02/survivor/

第二期在这里 ↓
https://beyondjapan.com/blog/2024/03/survivor2/

如果您觉得这篇文章对您有帮助,请点个“赞”!
7
加载中...
7票,平均分:1.00/17
571
X Facebook Hatena书签 口袋

这篇文章的作者

关于作者

松山健翔

我曾在一家游戏开发公司工作多年,负责编程和项目管理等工作。
2019年,我加入Beyond Inc.,在横滨办公室工作。
我主要负责服务器端开发的项目管理(偶尔也参与编程)。
我的爱好是公路自行车赛和观看赛马。