2020年3月8日游戏研发日志
程序员文章站
2024-01-01 17:28:52
...
简单塔防游戏的设计与实现(三)
在上一篇文章中,游戏的主控器和基本函数都已实现(传送门:https://blog.csdn.net/qq_40606433/article/details/104702048)
这里开始进行下一步的设计与实现,实现EnemySpawn的控制脚本。
对于基础的功能,假设只有一波敌人的话,可以这样编写EnemySpawnController
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawnController : MonoBehaviour
{
//敌人生成器
//分析:
// 生成一个敌人: CreateEnemy,认为出生点就是本身
// 计数:生成的敌人个数和要生成的敌人总数
// 保存可用路径:可用路径坐标和总数
GameController gameController;
Vector3[] route = new Vector3[5]
{
new Vector3(5.15f, 0, 6.35f),
new Vector3(5.15f, 0, 1f),
new Vector3(-5.82f, 0, 1f),
new Vector3(-5.82f, 0, -6.0f),
new Vector3(9.5f, 0, -6.0f)
};
//每个敌人生成的间隔
public float interval = 0.3f;
public float current_interval = 0;
//敌人的最大数量和当前数量,应该如何处理多波敌人?
public int enemy_max_count = 10;
public int enemy_count = 0;
public bool isCreating = false;
void Update()
{
if(isCreating)
{
current_interval += Time.deltaTime;
if(current_interval >= interval)
{
CreateEnemy();
current_interval -= interval;
}
}
}
public void Begin()
{
enemy_count = 0;
current_interval = 0;
isCreating = true;
this.gameController.SetEnemy(enemy_max_count);
}
public void CreateEnemy()
{
Object enemy = Resources.Load("Enemy");
if(enemy == null)
{
Debug.Log("未能正确加载预设体");
return;
}
GameObject enemy_go = enemy as GameObject;
if(enemy_go == null)
{
Debug.Log("未能将预设体转换为游戏对象");
}
enemy_go = Instantiate(enemy_go, this.transform.position, Quaternion.identity);
Enemy enemyController = enemy_go.GetComponent<Enemy>();
enemyController.setGameController(gameController);
enemyController.StartMove(route);
//控制生成的敌人的数量,全部生成完毕时停止再生成敌人
enemy_count++;
if(enemy_count >= enemy_max_count)
{
isCreating = false;
}
}
public void setGameController(GameController gameController)
{
this.gameController = gameController;
}
}
里面的Enemy预设体大改长这个样子:
这里开始已经出现难题了:
1.波次的控制应该交给谁?
2.敌人的移动有没有更好的解决方法(现在使用的是标记几个拐弯点,敌人走到后向下一个拐弯点移动,但是之前的GUI开发时使用的网格来给敌人定位导航)
由于Unity刚入门,还不熟悉各种操作,因此敌人移动就先使用这样简单粗暴的方法解决,等后续能力足够了再回来想想有什么解决方法。
下面尝试解决波次的控制
分析:波次的控制涉及GameController中的敌人计数器(当敌人为0时开始下一波)和EnemySpawnController(是否正在一波,下一波的内容是什么,按什么顺序造什么兵等等)。
所以这里决定由EnemySpawnController控制波次。
对GameController的改动:
public bool allClear() //封装一下场上是否还有敌人的函数
{
return enemy == 0;
}
public void Win()
{
Debug.Log("YOU WIN");
}
public void Lose()
{
Debug.Log("GAME OVER");
}
对EnemySpawnController的改动:
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class EnemySpawnController : MonoBehaviour
{
//敌人生成器
//分析:
// 生成一个敌人: CreateEnemy,认为出生点就是本身
// 计数:生成的敌人个数和要生成的敌人总数
// 保存可用路径:可用路径坐标和总数
GameController gameController;
Vector3[] route = new Vector3[5]
{
new Vector3(5.15f, 0, 6.35f),
new Vector3(5.15f, 0, 1f),
new Vector3(-5.82f, 0, 1f),
new Vector3(-5.82f, 0, -6.0f),
new Vector3(9.5f, 0, -6.0f)
};
//每个敌人生成的间隔
public float interval = 0.3f;
public float current_interval = 0;
//敌人的最大数量和当前数量,应该如何处理多波敌人?
public List<int> enemy_counts = new List<int>()
{ 10, 15, 20 };
public int current_wave = 0;
public int current_enemy_max_counts;
public int enemy_count = 0;
//一波敌人的准备时间
public bool isComing = false;
public float wave_interval = 5;
public float current_wave_interval = 0;
public bool isCreating = false;
void Update()
{
if (isCreating)
{
current_interval += Time.deltaTime;
if (current_interval >= interval)
{
CreateEnemy();
current_interval -= interval;
}
}
else if(isComing)
{
current_wave_interval += Time.deltaTime;
if(current_wave_interval >= wave_interval)
{
isComing = false;
Next();
current_wave_interval = 0;
}
}
else
{
if(gameController.allClear())
{
isComing = true;
}
}
}
public void Begin()
{
isComing = true;
}
public void Next()
{
if(current_wave >= enemy_counts.Count)
{
this.gameController.Win();
return;
}
enemy_count = 0;
current_interval = 0;
isCreating = true;
this.gameController.SetEnemy(enemy_counts[current_wave]);
}
public void CreateEnemy()
{
Object enemy = Resources.Load("Enemy");
if(enemy == null)
{
Debug.Log("未能正确加载预设体");
return;
}
GameObject enemy_go = enemy as GameObject;
if(enemy_go == null)
{
Debug.Log("未能将预设体转换为游戏对象");
}
enemy_go = Instantiate(enemy_go, this.transform.position, Quaternion.identity);
Enemy enemyController = enemy_go.GetComponent<Enemy>();
enemyController.setGameController(gameController);
enemyController.StartMove(route);
//控制生成的敌人的数量,全部生成完毕时停止再生成敌人
enemy_count++;
if(enemy_count >= enemy_counts[current_wave])
{
isCreating = false;
current_wave++;
}
}
public void setGameController(GameController gameController)
{
this.gameController = gameController;
}
}
至此敌人生成器已经完成。效率可能较低,游戏性能优化问题待日后自己又能力了再说(突然出现了Flag
推荐阅读