开发工具

  1. Cocos Dashboard 1.0.20
  2. Cocos Creator 3.4.0
  3. Visual Studio Code 1.63
  4. Microsoft Edge 97.0.1072.69

制作敌人飞机

  1. 资源管理器assets/script/ 创建名为 plane 的文件夹, 在 assets/script/plane/ 文件夹下创建脚本,命名为 EnemyPlane, 暂时不用编辑脚本内容。

  2. 资源管理器assets/res/model/plane02 文件夹添加 材质,命名为 plane02, 修改 Effect 属性为 bulitin-unlit, 选中 USE TEXTURE, MainTexture 拖入图片 plane02, 保存材质。

  1. 复制上一步的材质到 assets/res/model/plane03 文件夹, 更改材质名为:plane03, 修改其 MainTexture 为图片plane03, 保存材质。

  2. 层级管理器 中创建一个 空节点,命名为 plane02, 将 资源管理器 中的 FBX 模型 plane02 拖到该节点,将模型名称改名为 body, 展开 body, 选中下面的 plane02, 把 Materials 中的材质替换为 plane02

  1. 层级管理器 点击选中 plane02/body 节点, 修改属性 Rotation 的三个值改为 X:5, Y:5, Z:5, 放大 5倍
  1. 层级管理器 点击选中 plane02 节点, 在 属性检查器 选择 添加组件 -> 自定义脚本 -> EnemyPlane, 把敌人飞机的脚本挂载到 plane02 根节点上。
  1. 层级管理器 中的 plane02 节点拖动到 资源管理器assets/res/model/plane02 文件夹,做成 预制

  2. 重复上面的步骤,制作 plane03预制

  3. 层级管理器 中删除 plane02plane03 两个节点

敌机的管理

  1. 资源管理器assets/script/framework/ 文件夹添加脚本 Constant 用于存放游戏里常用的类型, 比如 飞机类型子弹类型 以及 飞机组合 等。Constant 类不需要继承自 Component, 编辑代码如以下所示:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
export class Constant {

// 敌机类型
public static EnemyType = {
TYPE1: 1,
TYPE2: 2,
}

// 敌机组合类型
public static Combination = {
PLAN1: 1, // 组合1, 每次随机1架敌机, 发射子弹
PLAN2: 2, // 组合2, 每次5架敌机,一 字型, 不发射子弹
PLAN3: 3, // 组合3, 每次7架敌机,V 字型, 不发射子弹
}
}
  1. 编辑敌机脚本 EnemyPlane, 内容如以下代码所示:
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

import { _decorator, Component, Node } from 'cc';
import { GameManager } from '../framework/GameManager';
const { ccclass, property } = _decorator;

// 敌机被销毁的位置(超出屏幕下边沿后的Z轴坐标值)
const OUTOFBOUNCE = 50;

@ccclass('EnemyPlane')
export class EnemyPlane extends Component {

private _enemySpeed = 0;
private _gameManager: GameManager = null;

update(deltaTime: number) {
const pos = this.node.position;
// 敌机向下飞 pos.z 值要增加
let movePos = pos.z + this._enemySpeed;

this.node.setPosition(pos.x, pos.y, movePos);
if (movePos > OUTOFBOUNCE) {
this.node.destroy();
}
}

show(gameManager: GameManager, speed: number) {
this._gameManager = gameManager;
this._enemySpeed = speed;
}
}

  1. 修改 GameManager 脚本, 添加用于管理敌机的属性, 以及控制敌机 第一阶段 (前10秒)的出现。
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136

import { _decorator, Component, Node, Prefab, instantiate, math } from 'cc';
import { Bullet } from '../bullet/Bullet';
import { EnemyPlane } from '../plane/EnemyPlane';
import { Constant } from './Constant';
const { ccclass, property } = _decorator;


@ccclass('GameManager')
export class GameManager extends Component {
@property(Node)
public playerPlane: Node = null; // 玩家飞机

@property(Prefab)
public bullet01: Prefab = null; // 子弹1
@property(Prefab)
public bullet02: Prefab = null; // 子弹2
@property(Prefab)
public bullet03: Prefab = null; // 子弹3
@property(Prefab)
public bullet04: Prefab = null; // 子弹4
@property(Prefab)
public bullet05: Prefab = null; // 子弹5

@property
public shootTime = 0.3; // 射击周期(间隔时间)
@property
public bulletSpeed = 1; // 子弹速度

@property(Node)
public bulletRoot: Node = null; // 子弹管理节点

// 敌机
@property(Prefab)
public enemy01: Prefab = null; // 敌机1
@property(Prefab)
public enemy02: Prefab = null; // 敌机2
@property
public createEnemyTime = 1; // 敌机生成时间
@property
public enemy01Speed = 0.5; // 敌机1速度
@property
public enemy02Speed = 0.7; // 敌机2速度

private _currShootTime = 0;
private _isShooting = false;
private _currCreateEnemyTiime = 0; // 当前敌机的生成时间
private _combinationInterval = Constant.Combination.PLAN1; // 组合的间隔状态

start() {
this._init();
}

update(deltaTime: number) {
this._currShootTime += deltaTime;
if (this._isShooting && this._currShootTime > this.shootTime) {
this.createPlayerBullet();
this._currShootTime = 0;
}
this._currCreateEnemyTiime += deltaTime;

// 判断组合方式创建相应的敌机
if (this._combinationInterval === Constant.Combination.PLAN1) {
if (this._currCreateEnemyTiime > this.createEnemyTime) {
this.createEnemyPlane();
this._currCreateEnemyTiime = 0;
}
} else if (this._combinationInterval === Constant.Combination.PLAN2) {

} else {

}
}

//创建玩家飞机的子弹
public createPlayerBullet() {
// 实例材质类型的子弹, 实例出来的对象不在场景中
const bullet = instantiate(this.bullet01);
bullet.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中

let pos = this.playerPlane.position; // 获取玩家飞机位置
// 子弹出现的位置为飞机 Z轴 -7
bullet.setPosition(pos.x, pos.y, pos.z - 7);
// 获取 Bullet类 (子弹预制根节点添加 Bullet 脚本)
const bulletComp = bullet.getComponent(Bullet);
bulletComp.bulletSpeed = this.bulletSpeed; // 设置子弹速度
}

// 是否处理触摸状态,触摸才发射子弹
public isShooting(value: boolean) {
this._isShooting = value;
}

public createEnemyPlane() {
// math 是 cc 带的数字模块
const whichEnemy = math.randomRangeInt(1, 3);
let prefab: Prefab = null;
let speed = 0;
if (whichEnemy === Constant.EnemyType.TYPE1) {
prefab = this.enemy01;
speed = this.enemy01Speed;
} else {
prefab = this.enemy02;
speed = this.enemy02Speed;
}

// 实例化预制
const enemy = instantiate(prefab);
enemy.setParent(this.node); // 预制挂载到组件中
const enemyComp = enemy.getComponent(EnemyPlane);
enemyComp.show(this, speed);

// 敌机随机出现的X轴(左右)坐标范围
const randomPos = math.randomRangeInt(-25, 26);
enemy.setPosition(randomPos, 0, -50);

}

private _init() {
// 用于按下的时候即发射第一颗子弹
this._currShootTime = this.shootTime;
this._changePlaneModel();
}

// 定时器函数
private _changePlaneModel() {
// this.schedule()四个参数:回调, 间隔时间,重复次数, 延迟时间
this.schedule(this._modeChanged, 10, 3);
}

// 改变组合状态
private _modeChanged() {
this._combinationInterval ++;
}
}

  1. 资源管理器 中的两个预制 plane02plane03 分别挂载到 层级管理器gameManager 节点对应的位置。
  1. 保存场景, 预览,可以看到单架敌机出现。
  1. 继续编辑 GameManager 脚本, 控制敌机 第二阶段 (10-20秒) 组合1组合2 随机出机 和 第三阶段 (20秒后)组合1组合2组合3 随机出现。
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198

import { _decorator, Component, Node, Prefab, instantiate, math } from 'cc';
import { Bullet } from '../bullet/Bullet';
import { EnemyPlane } from '../plane/EnemyPlane';
import { Constant } from './Constant';
const { ccclass, property } = _decorator;


@ccclass('GameManager')
export class GameManager extends Component {
@property(Node)
public playerPlane: Node = null; // 玩家飞机

@property(Prefab)
public bullet01: Prefab = null; // 子弹1
@property(Prefab)
public bullet02: Prefab = null; // 子弹2
@property(Prefab)
public bullet03: Prefab = null; // 子弹3
@property(Prefab)
public bullet04: Prefab = null; // 子弹4
@property(Prefab)
public bullet05: Prefab = null; // 子弹5

@property
public shootTime = 0.3; // 射击周期(间隔时间)
@property
public bulletSpeed = 1; // 子弹速度

@property(Node)
public bulletRoot: Node = null; // 子弹管理节点

// 敌机
@property(Prefab)
public enemy01: Prefab = null; // 敌机1
@property(Prefab)
public enemy02: Prefab = null; // 敌机2
@property
public createEnemyTime = 1; // 敌机生成时间
@property
public enemy01Speed = 0.5; // 敌机1速度
@property
public enemy02Speed = 0.7; // 敌机2速度

private _currShootTime = 0;
private _isShooting = false;
private _currCreateEnemyTiime = 0; // 当前敌机的生成时间
private _combinationInterval = Constant.Combination.PLAN1; // 组合的间隔状态

start() {
this._init();
}

update(deltaTime: number) {
this._currShootTime += deltaTime;
if (this._isShooting && this._currShootTime > this.shootTime) {
this.createPlayerBullet();
this._currShootTime = 0;
}
this._currCreateEnemyTiime += deltaTime;

// 判断组合方式创建相应的敌机
if (this._combinationInterval === Constant.Combination.PLAN1) {
if (this._currCreateEnemyTiime > this.createEnemyTime) {
this.createEnemyPlane();
this._currCreateEnemyTiime = 0;
}
} else if (this._combinationInterval === Constant.Combination.PLAN2) {
// 第二阶段,前两种组合随机出现
// 这里乘以 0.9 是缩短敌机出现的间隔时间
if (this._currCreateEnemyTiime > this.createEnemyTime * 0.9) {
// 用于随机出现组合1或组合2
const randomCombination = math.randomRangeInt(1, 6);
if (randomCombination === Constant.Combination.PLAN2) {
this.createCombination01();
} else {
this.createEnemyPlane();
}
this._currCreateEnemyTiime = 0;
}
} else {
// 第三阶段,三个组合随机出现
// 这里乘以 0.9 是缩短敌机出现的间隔时间
if (this._currCreateEnemyTiime > this.createEnemyTime * 0.8) {
// 用于随机出现组合1或组合2
const randomCombination = math.randomRangeInt(1, 7);
if (randomCombination === Constant.Combination.PLAN2) {
this.createCombination01();
} else if (randomCombination === Constant.Combination.PLAN3) {
this.createCombination02();
} else {
this.createEnemyPlane();
}
this._currCreateEnemyTiime = 0;
}
}
}

//创建玩家飞机的子弹
public createPlayerBullet() {
// 实例材质类型的子弹, 实例出来的对象不在场景中
const bullet = instantiate(this.bullet01);
bullet.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中

let pos = this.playerPlane.position; // 获取玩家飞机位置
// 子弹出现的位置为飞机 Z轴 -7
bullet.setPosition(pos.x, pos.y, pos.z - 7);
// 获取 Bullet类 (子弹预制根节点添加 Bullet 脚本)
const bulletComp = bullet.getComponent(Bullet);
bulletComp.bulletSpeed = this.bulletSpeed; // 设置子弹速度
}

// 是否处理触摸状态,触摸才发射子弹
public isShooting(value: boolean) {
this._isShooting = value;
}

public createEnemyPlane() {
// math 是 cc 带的数字模块
const whichEnemy = math.randomRangeInt(1, 3);
let prefab: Prefab = null;
let speed = 0;
if (whichEnemy === Constant.EnemyType.TYPE1) {
prefab = this.enemy01;
speed = this.enemy01Speed;
} else {
prefab = this.enemy02;
speed = this.enemy02Speed;
}

// 实例化预制
const enemy = instantiate(prefab);
enemy.setParent(this.node); // 预制挂载到组件中
const enemyComp = enemy.getComponent(EnemyPlane);
enemyComp.show(this, speed);

// 敌机随机出现的X轴(左右)坐标范围
const randomPos = math.randomRangeInt(-25, 26);
enemy.setPosition(randomPos, 0, -50);
}

// 敌机出现组合1:5架飞机一字型同时出现
public createCombination01() {
const enemyArray = new Array<Node>(5);
for (let i = 0; i < enemyArray.length; i++) {
enemyArray[i] = instantiate(this.enemy01);
const element = enemyArray[i];
element.parent = this.node;
element.setPosition(-20 + i * 10, 0, -50);
const enemyComp = element.getComponent(EnemyPlane);
enemyComp.show(this, this.enemy01Speed);
}
}

// 敌机出现组合1, 7架飞机V字型出现
public createCombination02() {
const enemyArray = new Array<Node>(7);
// 7 架敌机的初始坐标
const combinationPos = [
-21, 0, -60,
-14, 0, -55,
-7, 0, -50,
0, 0, -45,
7, 0, -50,
14, 0, -55,
21, 0, -60,
];
for (let i = 0; i < enemyArray.length; i++) {
enemyArray[i] = instantiate(this.enemy02);
const element = enemyArray[i];
element.parent = this.node;
const startIndex = i * 3;
element.setPosition(combinationPos[startIndex],
combinationPos[startIndex + 1],
combinationPos[startIndex + 2]);
const enemyComp = element.getComponent(EnemyPlane);
enemyComp.show(this, this.enemy02Speed);
}
}

private _init() {
// 用于按下的时候即发射第一颗子弹
this._currShootTime = this.shootTime;
this._changePlaneModel();
}

// 定时器函数
private _changePlaneModel() {
// this.schedule()四个参数:回调, 间隔时间,重复次数, 延迟时间
this.schedule(this._modeChanged, 10, 3);
}

// 改变组合状态
private _modeChanged() {
this._combinationInterval++;
}
}

  1. 保存场景, 预览,20秒 后可以看到三种组合的敌机出现。

敌机发射子弹

  1. 修改 Bullet 脚本, 增加判断 敌机子弹 的逻辑。
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

import { _decorator, Component, Node } from 'cc';
const { ccclass, property } = _decorator;

@ccclass('Bullet')
export class Bullet extends Component {

// @property
// public bulletSpeed = 0;

private _bulletSpeed = 0; //子弹速度改为私有变量
private _isEnemyBullet = false; // 判断是否为敌机子弹

update(deltaTime: number) {
let pos = this.node.position; // 获取子弹的位置
let moveLength = pos.z - this._bulletSpeed; // 计算每一帧子弹要移动的位置
// 计算每一帧子弹要移动的位置, 玩家和敌机子弹方向不同
if (this._isEnemyBullet) {
moveLength = pos.z + this._bulletSpeed;
this.node.setPosition(pos.x, pos.y, moveLength);
if (moveLength > 50) {
this.node.destroy();
console.log(`enemy bullet destory`);
}
} else {
moveLength = pos.z - this._bulletSpeed;
this.node.setPosition(pos.x, pos.y, moveLength);
if (moveLength < -50) {
this.node.destroy();
console.log(`player bullet destory`);
}
}
}

// 从 GameManager 脚本接收子弹速度和是否为敌机子弹
show(speed: number, isEnemyBullet: boolean = false) {
this._bulletSpeed = speed;
this._isEnemyBullet = isEnemyBullet;
}
}

  1. 修改 EnemyPlane 脚本,增加 敌机发射子弹 逻辑。
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

import { _decorator, Component, Node } from 'cc';
import { GameManager } from '../framework/GameManager';
const { ccclass, property } = _decorator;

// 敌机被销毁的位置(超出屏幕下边沿后的Z轴坐标值)
const OUTOFBOUNCE = 50;

@ccclass('EnemyPlane')
export class EnemyPlane extends Component {

@property
public createBulletTime = 0.5; // 敌机子弹发射周期

private _enemySpeed = 0;
private _needBullet = false; // 敌机是否发射子弹
private _currCreateBulletTime = 0; // 敌机当前子弹发射周期
private _gameManager: GameManager = null;

update(deltaTime: number) {
const pos = this.node.position;
// 敌机向下飞 pos.z 值要增加
let movePos = pos.z + this._enemySpeed;

// 增加用于判断是否要发射子弹
if (this._needBullet) {
this._currCreateBulletTime += deltaTime;
if (this._currCreateBulletTime > this.createBulletTime) {
// 敌机发射子弹,需要在 GameManager 添加相应函数
// this.node.position 是发射子弹时敌机的位置
this._gameManager.createEnemyBullet(this.node.position);
this._currCreateBulletTime = 0;
}
}

this.node.setPosition(pos.x, pos.y, movePos);
if (movePos > OUTOFBOUNCE) {
this.node.destroy();
}
}

show(gameManager: GameManager, speed: number, needBullet: boolean = false) {
this._gameManager = gameManager;
this._enemySpeed = speed;
this._needBullet = needBullet;
}
}

  1. 修改 GameManager 脚本控制敌机子弹发射, 添加 createEnemyBullet 方法, 修改所有 show 方法, 调整参数个数 。
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
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211

import { _decorator, Component, Node, Prefab, instantiate, math, Vec3 } from 'cc';
import { Bullet } from '../bullet/Bullet';
import { EnemyPlane } from '../plane/EnemyPlane';
import { Constant } from './Constant';
const { ccclass, property } = _decorator;


@ccclass('GameManager')
export class GameManager extends Component {
@property(Node)
public playerPlane: Node = null; // 玩家飞机

@property(Prefab)
public bullet01: Prefab = null; // 子弹1
@property(Prefab)
public bullet02: Prefab = null; // 子弹2
@property(Prefab)
public bullet03: Prefab = null; // 子弹3
@property(Prefab)
public bullet04: Prefab = null; // 子弹4
@property(Prefab)
public bullet05: Prefab = null; // 子弹5

@property
public shootTime = 0.3; // 射击周期(间隔时间)
@property
public bulletSpeed = 1; // 子弹速度

@property(Node)
public bulletRoot: Node = null; // 子弹管理节点

// 敌机
@property(Prefab)
public enemy01: Prefab = null; // 敌机1
@property(Prefab)
public enemy02: Prefab = null; // 敌机2
@property
public createEnemyTime = 1; // 敌机生成时间
@property
public enemy01Speed = 0.5; // 敌机1速度
@property
public enemy02Speed = 0.7; // 敌机2速度

private _currShootTime = 0;
private _isShooting = false;
private _currCreateEnemyTiime = 0; // 当前敌机的生成时间
private _combinationInterval = Constant.Combination.PLAN1; // 组合的间隔状态

start() {
this._init();
}

update(deltaTime: number) {
this._currShootTime += deltaTime;
if (this._isShooting && this._currShootTime > this.shootTime) {
this.createPlayerBullet();
this._currShootTime = 0;
}
this._currCreateEnemyTiime += deltaTime;

// 判断组合方式创建相应的敌机
if (this._combinationInterval === Constant.Combination.PLAN1) {
if (this._currCreateEnemyTiime > this.createEnemyTime) {
this.createEnemyPlane();
this._currCreateEnemyTiime = 0;
}
} else if (this._combinationInterval === Constant.Combination.PLAN2) {
// 第二阶段,前两种组合随机出现
// 这里乘以 0.9 是缩短敌机出现的间隔时间
if (this._currCreateEnemyTiime > this.createEnemyTime * 0.9) {
// 用于随机出现组合1或组合2
const randomCombination = math.randomRangeInt(1, 6);
if (randomCombination === Constant.Combination.PLAN2) {
this.createCombination01();
} else {
this.createEnemyPlane();
}
this._currCreateEnemyTiime = 0;
}
} else {
// 第三阶段,三个组合随机出现
// 这里乘以 0.9 是缩短敌机出现的间隔时间
if (this._currCreateEnemyTiime > this.createEnemyTime * 0.8) {
// 用于随机出现组合1或组合2
const randomCombination = math.randomRangeInt(1, 7);
if (randomCombination === Constant.Combination.PLAN2) {
this.createCombination01();
} else if (randomCombination === Constant.Combination.PLAN3) {
this.createCombination02();
} else {
this.createEnemyPlane();
}
this._currCreateEnemyTiime = 0;
}
}
}

//创建玩家飞机的子弹
public createPlayerBullet() {
// 实例材质类型的子弹, 实例出来的对象不在场景中
const bullet = instantiate(this.bullet01);
bullet.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中

let pos = this.playerPlane.position; // 获取玩家飞机位置
// 子弹出现的位置为飞机 Z轴 -7
bullet.setPosition(pos.x, pos.y, pos.z - 7);
// 获取 Bullet类 (子弹预制根节点添加 Bullet 脚本)
const bulletComp = bullet.getComponent(Bullet);
bulletComp.show(this.bulletSpeed, false); // 设置子弹速度
}

// 是否处理触摸状态,触摸才发射子弹
public isShooting(value: boolean) {
this._isShooting = value;
}

public createEnemyPlane() {
// math 是 cc 带的数字模块
const whichEnemy = math.randomRangeInt(1, 3);
let prefab: Prefab = null;
let speed = 0;
if (whichEnemy === Constant.EnemyType.TYPE1) {
prefab = this.enemy01;
speed = this.enemy01Speed;
} else {
prefab = this.enemy02;
speed = this.enemy02Speed;
}

// 实例化预制
const enemy = instantiate(prefab);
enemy.setParent(this.node); // 预制挂载到组件中
const enemyComp = enemy.getComponent(EnemyPlane);
enemyComp.show(this, speed, true);

// 敌机随机出现的X轴(左右)坐标范围
const randomPos = math.randomRangeInt(-25, 26);
enemy.setPosition(randomPos, 0, -50);
}

// 敌机出现组合1:5架飞机一字型同时出现
public createCombination01() {
const enemyArray = new Array<Node>(5);
for (let i = 0; i < enemyArray.length; i++) {
enemyArray[i] = instantiate(this.enemy01);
const element = enemyArray[i];
element.parent = this.node;
element.setPosition(-20 + i * 10, 0, -50);
const enemyComp = element.getComponent(EnemyPlane);
enemyComp.show(this, this.enemy01Speed, false);
}
}

// 敌机出现组合1, 7架飞机V字型出现
public createCombination02() {
const enemyArray = new Array<Node>(7);
// 7 架敌机的初始坐标
const combinationPos = [
-21, 0, -60,
-14, 0, -55,
-7, 0, -50,
0, 0, -45,
7, 0, -50,
14, 0, -55,
21, 0, -60,
];
for (let i = 0; i < enemyArray.length; i++) {
enemyArray[i] = instantiate(this.enemy02);
const element = enemyArray[i];
element.parent = this.node;
const startIndex = i * 3;
element.setPosition(combinationPos[startIndex],
combinationPos[startIndex + 1],
combinationPos[startIndex + 2]);
const enemyComp = element.getComponent(EnemyPlane);
enemyComp.show(this, this.enemy02Speed, false);
}
}

// 敌机发射子弹
public createEnemyBullet(targetPos: Vec3) {
// 实例材质类型的子弹, 实例出来的对象不在场景中
const bullet = instantiate(this.bullet01);
bullet.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中

// 子弹出现的位置为飞机 Z轴 -7
bullet.setPosition(targetPos.x, targetPos.y, targetPos.z + 6);
const bulletComp = bullet.getComponent(Bullet);
// 敌机的子弹速度 要比敌机大一些
bulletComp.show(1, true);
}

private _init() {
// 用于按下的时候即发射第一颗子弹
this._currShootTime = this.shootTime;
this._changePlaneModel();
}

// 定时器函数
private _changePlaneModel() {
// this.schedule()四个参数:回调, 间隔时间,重复次数, 延迟时间
this.schedule(this._modeChanged, 10, 3);
}

// 改变组合状态
private _modeChanged() {
this._combinationInterval++;
}
}

  1. 重新预览, 单架出现的敌机向玩家方向发射子弹

===END===