\像模像样/
本篇讲述了如何使敌方坦克的进攻更加智能,以及如何生成随机的地图
敌人AI的编写
计划中敌人(银色坦克)出现在游戏的上方,通过一系列的走位最终到达基地旁并击倒心脏
。所以敌人是自动走位的,不需要人为的干涉,为了实现这个设计,我们修改了原player
脚本的move
方法:
1 | //敌人的移动 |
现在的AI看起来笨笨的,经常撞墙,下一天应该会有更新
想到魂类游戏的boss们通过识别玩家与自身的距离,位置来放不同的技能,甚至还有虚晃一招,让人捉摸不透就觉得设计一个智能的boss工程量可谓很大了。
地图的生成
在hierarchy
新建一个GameObject
起名为MapCreation
,在编写完成后就可以随机生成地图,敌人了。hierarchy
中只留下了MapCreation
,其他都可以删除了,看起来非常整洁。
这是一张生成好之后的地图:
在不知道具体坐标的时候,可以移动玩家的坦克,并在Game
界面里找到临界点。这里是(10,8), (10,-8), (-10,8), (-10,-8)
。
地图的生成分为:
- 固定的基地和基地旁的砖墙生成
- 随机的砖墙,铁墙,草,河流生成
- 固定的玩家和敌人生成
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122using System.Collections;
using System.Collections.Generic;
using UnityEngine;
public class MapCreation : MonoBehaviour
{
//用来装饰初始化地图所需物体的数组
//0.基地,1.墙,2.障碍,3.出生效果,4.河流, 5.草, 6.空气墙
//在"hierarchy“界面中依次拖入GameObject中
public GameObject[] item;
//将所有生成的位置添加进列表
//注意List的L要大写
private List<Vector3> itemPoistionList = new List<Vector3>();
//在awake()中实例化,让地图的生成先于其他所有物体
private void Awake(){
//实例化基地
//Quaternion.identity:当前实例化的物体无旋转角度,预制体的旋转角度是多少,实例化得到的就是多少
CreateItem(item[0], new Vector3(0,-8,0), Quaternion.identity);
//用墙把基地围起来
CreateItem(item[1], new Vector3(-1,-8,0), Quaternion.identity);
CreateItem(item[1], new Vector3(1,-8,0), Quaternion.identity);
//懒人用for循环建造三个砖墙
for (int i = -1; i<2; i++){
CreateItem(item[1], new Vector3(i,-7,0), Quaternion.identity);
}
//实例化空气墙,防止坦克乱跑,回收子弹
for (int i = -11; i<12; i++){
CreateItem(item[6], new Vector3(i,9,0), Quaternion.identity);}
for (int i = -11; i<12; i++){
CreateItem(item[6], new Vector3(i,-9,0), Quaternion.identity);}
for (int i = -8; i<9; i++){
CreateItem(item[6], new Vector3(-11,i,0), Quaternion.identity);}
for (int i = -8; i<9; i++){
CreateItem(item[6], new Vector3(11,i,0), Quaternion.identity);}
//初始化玩家
GameObject go = Instantiate(item[3], new Vector3(-2, -8, 0), Quaternion.identity);
//得到组件,并把创建玩家设置成true,即创建玩家
go.GetComponent<Born>().createPlayer = true;
//产生敌人
CreateItem(item[3], new Vector3(-10, 8, 0), Quaternion.identity);
CreateItem(item[3], new Vector3(0, 8, 0), Quaternion.identity);
CreateItem(item[3], new Vector3(10, 8, 0), Quaternion.identity);
//重复调用(方法名,延时几秒后调用这个方法,每隔多久调用一次)
InvokeRepeating("CreateEnemy", 4, 5);
//实例化地图
for(int i = 0; i<60;i++){
CreateItem(item[1], createRandomPosition(), Quaternion.identity);
}
for(int i = 0; i<20;i++){
CreateItem(item[2], createRandomPosition(), Quaternion.identity);
}
for(int i = 0; i<20;i++){
CreateItem(item[4], createRandomPosition(), Quaternion.identity);
}
for(int i = 0; i<20;i++){
CreateItem(item[5], createRandomPosition(), Quaternion.identity);
}
}
//让实例化物体作为MapCreation的组件出现,而不是散落在Hierarchy上
private void CreateItem(GameObject createGameObject,Vector3 createPosition, Quaternion createRotation){
//实例化物体
GameObject itemGo = Instantiate(createGameObject, createPosition,createRotation);
//将MapCreation设定为父集层
itemGo.transform.SetParent(gameObject.transform);
//添加进位置列表
itemPoistionList.Add(createPosition);
}
//产生随机位置的方法
public Vector3 createRandomPosition(){
//不生成x=-10和10两列;y=-8和8两行的位置,否则坦克会被卡住(小概率)
while (true)
{//int类型的Random.Range()方法包括第一个数,不包括第二个数
Vector3 createPosition = new Vector3(Random.Range(-9,10), Random.Range(-7,8), 0);
//如果这个位置没有被生成过,则返回一个可用的随机位置,跳出循环
if(hasThePosition(createPosition) == false){
return createPosition;
}
}
}
//判断位置列表中是否有这个位置
private bool hasThePosition(Vector3 createPos){
//列表长度用.Count来表示
for (int i=0; i < itemPoistionList.Count; i++)
{
if (createPos == itemPoistionList[i]){
return true;
}
}
//如果遍历完发现没有相同的位置,则返回false表示可以建立新的位置
return false;
}
//产生敌人的方法
private void CreateEnemy(){
//敌人随机产生的位置
int num = Random.Range(0,3);
Vector3 enemyPos = new Vector3();
if (num == 0){
enemyPos = new Vector3(-10, 8, 0);
}
else if (num == 1){
enemyPos = new Vector3(0, 8, 0);
}
else{
enemyPos = new Vector3(10, 8, 0);
}
CreateItem(item[3], enemyPos, Quaternion.identity);
}
}
还剩下AI的更新,UI和游戏的判定就要完成了。