开发工具

  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

提供给玩家飞机的子弹道具

玩家飞家可以发射的子弹类型分为三种:

  • M型:直线发射 1发 白色小子弹(默认)
  • H型:直线发射 2发 红色小子弹
  • S型:扇形发射 3发 月牙型子弹,夹角为45度(或根据实际情况调整)

更换子弹的道具类型和出现方式:

  • 道具每10秒出现一个,类型为 HSM 其中一种
  • 收集到与当前不一样的道具时切换子弹类型
  • 使用S型道具时玩家飞机比敌人飞机速度慢

创建子弹切换道具材质

  1. 资源管理器assets/res/model/fightIconBullet/ 文件夹创建 材质, 命名为 bulletS。材质 Effect 属性的值设为 builltin-unlit, Technique 属性的值设为 03-alpha-blendUSE-TEXTURE 打勾, 将图片 assets/res/model/fightIconBullet/fightIconBullet01 拖动到 MainTexture, 在 属性检查器 右上角点击 图标的按钮 保存 材质。
  1. 资源管理器 中选中 bulletS 材质, 按两次 Ctrl+D 快速复制材质,并分别重命名为 bulletHbulletM

  2. 将材质 bulletH 的图片分别修改为 fightIconBullet02, 保存材质。

  3. 将材质 bulletM 的图片分别修改为 fightIconBullet03, 保存材质。

添加子弹切换道具

  1. 主菜单 上选择 项目 -> 项目设置, 在弹出对话框的左侧列表选择 物理, 在其 碰撞矩阵 添加分组 BULLET_PROP, 设置掩码: PLAYER_PLANE - BULLET_PROP
  1. 资源管理器assets/script/bullet/ 文件夹 右键 -> 创建 -> 脚本(TypeScript), 命名为 BulletProp(暂时不用编辑脚本)。

  2. 层级管理器 中添加 空节点,命名为 bulletM; 点击选中 bulletM 节点, 右键 -> 创建 -> 3D对象 -> Quad四方形, 命名为 body;

  3. 资源管理器 中的材质 bulletM 拖动到 bodyMaterials 属性; 将 bulletM 节点 body 属性 Rotation 的值修改为 X:-90, Y:0, Z:0, 使其旋转为图案向上; 将 Scale 的值修改为 X:10, Y:6, Z:1, 将它放大。

  1. 层级管理器 中点击选中 bulletM 节点, 在 属性检查器 中点击 添加组件 -> Physics -> BoxCollider, 将属性 Size 的值修改为 x:7, Y:1, Z:3, isTrigger 属性 打勾

  2. 继续在 bulletM 节点的 属性检查器 中点击 添加组件 -> Physics -> RigidBody, cc.RigidBodyGroup 属性值选为 BULLET_PROP (如果没有这一项,则重选一次 bulletM 节点刷新 属性检查器 面板即可), Type 属性的值改为 KINEMATIC, 保存场景。

  1. 层级管理器 中点击选中 bulletM 节点,添加组件 -> 自定义脚本 -> BulletProp。保存场景。
  1. 层级管理器 中点击选中 bulletM 节点, 拖动到 资源管理器assets/res/model/fightIconBullet/ 文件夹,添加为 预制
  1. 重复以上步骤 3-8 ,使用材质 bulletHbulletS 制作 另外两个 道具的 预制

  2. 完成 三个子弹道具 预制的制作, 在 层级管理器 中删除 bulletMbulletHbulletS 三个节点。

编辑子弹道具脚本

  1. 修改 Constant, 添加 子弹道具类型, 并添加一个 碰撞类型
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
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 字型, 不发射子弹
}

// 碰撞组合类型, 要和碰撞矩阵的顺序一致
public static CollistionType = {
// 使用左移符号设置为二进制值, 右边数字与碰撞矩阵序号一致
PLAYER_PLANE: 1 << 1,
ENEMY_PLANE: 1 << 2,
PLAYER_BULLET: 1 << 3,
ENEMY_BULLET: 1 << 4,
}

// 子弹道具类型
public static BulletPropType = {
BULLET_M: 1,
BULLET_H: 2,
BULLET_S: 3,
}
}
  1. 修改 GameManager, 增加用于更换玩家子弹类型的公共属性, 私有变量和方法, (以下代码只包含添加及修改的部分)
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

// 子弹类型道具
@property(Prefab)
public bulletPropM: Prefab = null;
@property(Prefab)
public bulletPropH: Prefab = null;
@property(Prefab)
public bulletPropS: Prefab = null;
@property
public bulletPropSpeed = 0.3; // 子弹类型道具速度

private _bulletType = Constant.BulletPropType.BULLET_M; // 子弹道具类型

// 更换玩家子弹类型
public changeBulletType(type: number) {
this._bulletType = type;
}

// 创建子弹道具
public createBulletProp() {
const randomProp = math.randomRangeInt(1, 4);
console.log('create bullet prop:', randomProp);
let prefab: Prefab = null;
if (randomProp === Constant.BulletPropType.BULLET_H) {
prefab = this.bulletPropH;
} else if (randomProp === Constant.BulletPropType.BULLET_S) {
prefab = this.bulletPropS;
} else {
prefab = this.bulletPropM;
}

// 实例化子弹道具预览
const prop = instantiate(prefab);
prop.setParent(this.node);

// const prop = PoolManager.instance().getNode(prefab, this.node);

prop.setPosition(15, 0, -50); // 道具的起始位置
const propComp = prop.getComponent(BulletProp);
propComp.show(this, -this.bulletPropSpeed);
}

// 改变组合状态
private _modeChanged() {
this._combinationInterval++;
this.createBulletProp(); // 增加这一行用于创建子弹道具
}
  1. 编辑子弹道具脚本 BulletProp
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

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


@ccclass('BulletProp')
export class BulletProp extends Component {
private _propSpeed = 0.3; // 道具移动速度
// 用于控制道具 S 型在屏幕上移动,从左往右正值,从右往右负值
private _propXSpeed = 0.3;
private _gameManager: GameManager = null;

onEnable() {
// 获取碰撞组件
const collider = this.getComponent(Collider);
// 监听触发事件
collider.on('onTriggerEnter', this._onTriggerEnter, this);
}

onDisable() {
// 获取碰撞组件
const collider = this.getComponent(Collider);
// 停止监听触发事件
collider.off('onTriggerEnter', this._onTriggerEnter, this);
}

update(deltaTime: number) {
let pos = this.node.position;
if (pos.x >= 15) {
this._propXSpeed = this._propSpeed;
} else if (pos.x <= -15) {
this._propXSpeed = -this._propSpeed;
}
this.node.setPosition(
pos.x + this._propXSpeed,
pos.y,
pos.z - this._propSpeed);

pos = this.node.position; // 移动后重新获取道具位置
if (pos.z > 50) {
this.node.destroy();
}
}

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

private _onTriggerEnter(event: ITriggerEvent) {
// 获取道具的名字
const name = event.selfCollider.node.name;
if (name === 'bulletH') {
this._gameManager.changeBulletType(Constant.BulletPropType.BULLET_H);
console.log('bullet type changed');
} else if (name === 'bulletS') {
this._gameManager.changeBulletType(Constant.BulletPropType.BULLET_S);
console.log('bullet type changed');
} else {
this._gameManager.changeBulletType(Constant.BulletPropType.BULLET_M);
}
this.node.destroy(); // 销毁道具
}
}

  1. 层级管理器 中点击选中 gameManager 节点, 将三个 子弹道具预制 挂载到对应的属性。
  1. 保存场景,运行、预览效果(10秒后出现第一个子弹类型道具)。

玩家飞机切换子弹类型

  1. 打开 GameManager 脚本, 将 createPlayerBullet 重命名为 createPlayerBulletM, 可以在 VS Code 选中 createPlayerBullet, 右键 -> 重命名符号, 在弹出的重命名框中输入新名字 createPlayerBulletM, 则原来所有引用 createPlayerBullet 的地方都会改为 createPlayerBulletM (不要手动修改)。
  1. GameManager 脚本中将 createPlayerBulletM 方法复制为 createPlayerBulletHcreatePlayerBulletS

  2. 修改 createPlayerBulletH 方法:

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

// H型子弹为前方同时发射两颗
public createPlayerBulletH() {
let pos = this.playerPlane.position; // 获取玩家飞机位置

// 左边的子弹
const bullet1 = instantiate(this.bullet03);
bullet1.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中
// 子弹出现的位置为飞机 Z轴 -7
bullet1.setPosition(pos.x - 2.5, pos.y, pos.z - 7);
// 获取 Bullet 组件 (脚本类)
const bulletComp1 = bullet1.getComponent(Bullet);
// bulletComp.bulletSpeed = this.bulletSpeed; // 设置子弹速度
bulletComp1.show(this.bulletSpeed, false); // 玩家飞机的子弹速度

// 右边的子弹
const bullet2 = instantiate(this.bullet03);
bullet2.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中
// 子弹出现的位置为飞机 Z轴 -7
bullet2.setPosition(pos.x + 2.5, pos.y, pos.z - 7);
// 获取 Bullet 组件 (脚本类)
const bulletComp2 = bullet2.getComponent(Bullet);
// bulletComp.bulletSpeed = this.bulletSpeed; // 设置子弹速度
bulletComp2.show(this.bulletSpeed, false); // 玩家飞机的子弹速度
}
  1. 修改 createPlayerBulletS 方法:
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

// S型子弹为三发扇形
public createPlayerBulletS() {
let pos = this.playerPlane.position; // 获取玩家飞机位置
// 中间子弹
const bullet1 = instantiate(this.bullet05);
bullet1.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中
// 子弹出现的位置为飞机 Z轴 -7
bullet1.setPosition(pos.x, pos.y, pos.z - 7);
// 获取 Bullet 组件 (脚本类)
const bulletComp1 = bullet1.getComponent(Bullet);
// bulletComp.bulletSpeed = this.bulletSpeed; // 设置子弹速度
bulletComp1.show(this.bulletSpeed, false); // 玩家飞机的子弹速度

// 左边子弹
const bullet2 = instantiate(this.bullet05);
bullet2.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中
// 子弹出现的位置为飞机 Z轴 -7
bullet2.setPosition(pos.x - 4, pos.y, pos.z - 7);
// 获取 Bullet 组件 (脚本类)
const bulletComp2 = bullet2.getComponent(Bullet);
// bulletComp.bulletSpeed = this.bulletSpeed; // 设置子弹速度
bulletComp2.show(this.bulletSpeed, false); // 玩家飞机的子弹速度

// 右边子弹
const bullet3 = instantiate(this.bullet05);
bullet3.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中
// 子弹出现的位置为飞机 Z轴 -7
bullet3.setPosition(pos.x + 4, pos.y, pos.z - 7);
// 获取 Bullet 组件 (脚本类)
const bulletComp3 = bullet3.getComponent(Bullet);
// bulletComp.bulletSpeed = this.bulletSpeed; // 设置子弹速度
bulletComp3.show(this.bulletSpeed, false); // 玩家飞机的子弹速度
}
  1. 编辑 Constant 脚本,添加不同类型子弹的运动方向:
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
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 字型, 不发射子弹
}

// 碰撞组合类型, 要和碰撞矩阵的顺序一致
public static CollistionType = {
// 使用左移符号设置为二进制值, 右边数字与碰撞矩阵序号一致
PLAYER_PLANE: 1 << 1,
ENEMY_PLANE: 1 << 2,
PLAYER_BULLET: 1 << 3,
ENEMY_BULLET: 1 << 4,
}

// 子弹道具类型
public static BulletPropType = {
BULLET_M: 1,
BULLET_H: 2,
BULLET_S: 3,
}

// 子弹运动方向
public static Direction = {
LEFT: 1,
MIDDLE: 2,
RIGHT: 3,
}
}
  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
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

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

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

private _bulletSpeed = 0; //子弹速度改为私有变量
private _isEnemyBullet = false; // 判断是否为敌机子弹
private _direction = Constant.Direction.MIDDLE; // 子弹运行方向

update(deltaTime: number) {
let pos = this.node.position; // 获取子弹的位置
let moveLength = 0; // 计算每一帧子弹要移动的位置
// 计算每一帧子弹要移动的位置, 玩家和敌机子弹方向不同
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;

// 判断子弹运动方向, 只有扇形子弹才需要左右方向
if (this._direction === Constant.Direction.LEFT) {
// 乘以 0.2 用于缩小扇形的角度
this.node.setPosition(pos.x - this._bulletSpeed * 0.2,
pos.y,
moveLength);
} else if (this._direction === Constant.Direction.RIGHT) {
this.node.setPosition(pos.x + this._bulletSpeed * 0.2,
pos.y,
moveLength);
} else {
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,
direction: number = Constant.Direction.MIDDLE) {
this._bulletSpeed = speed;
this._isEnemyBullet = isEnemyBullet;
this._direction = direction;
}

onEnable() {
// 获取碰撞组件
const collider = this.getComponent(Collider);
// 监听触发事件
collider.on('onTriggerEnter', this._onTriggerEnter, this);
}

onDisable() {
// 获取碰撞组件
const collider = this.getComponent(Collider);
// 停止监听触发事件
collider.off('onTriggerEnter', this._onTriggerEnter, this);
}

private _onTriggerEnter(event: ITriggerEvent) {
console.log('trigger bullet destroy');
// 子弹碰到玩家飞机都销毁
this.node.destroy();
}
}

  1. 编辑 GameManager 脚本, 更改 createPlayerBulletS()update(deltaTime: number) 方法, 控制子弹发射的方向。GameManager 脚本 完整代码如下:
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
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333

import { _decorator, Component, Node, Prefab, instantiate, math, Vec3, BoxCollider } from 'cc';
import { Bullet } from '../bullet/Bullet';
import { BulletProp } from '../bullet/BulletProp';
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速度

// 子弹类型道具
@property(Prefab)
public bulletPropM: Prefab = null;
@property(Prefab)
public bulletPropH: Prefab = null;
@property(Prefab)
public bulletPropS: Prefab = null;
@property
public bulletPropSpeed = 0.3; // 子弹类型道具速度

private _currShootTime = 0;
private _isShooting = false;
private _currCreateEnemyTiime = 0; // 当前敌机的生成时间
private _combinationInterval = Constant.Combination.PLAN1; // 组合的间隔状态
private _bulletType = Constant.BulletPropType.BULLET_M; // 子弹道具类型

start() {
this._init();
}

update(deltaTime: number) {
this._currShootTime += deltaTime;
if (this._isShooting && this._currShootTime > this.shootTime) {
// 判断子弹道具的类型
if (this._bulletType === Constant.BulletPropType.BULLET_H) {
this.createPlayerBulletH();
} else if (this._bulletType === Constant.BulletPropType.BULLET_S) {
this.createPlayerBulletS();
} else {
this.createPlayerBulletM();
}
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 createPlayerBulletM() {
// 实例材质类型的子弹, 实例出来的对象不在场景中
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); // 设置子弹速度
}

// S型子弹为前方同时发射两颗
public createPlayerBulletH() {
let pos = this.playerPlane.position; // 获取玩家飞机位置

// 左边的子弹
const bullet1 = instantiate(this.bullet03);
bullet1.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中
// 子弹出现的位置为飞机 Z轴 -7
bullet1.setPosition(pos.x - 2.5, pos.y, pos.z - 7);
// 获取 Bullet 组件 (脚本类)
const bulletComp1 = bullet1.getComponent(Bullet);
// bulletComp.bulletSpeed = this.bulletSpeed; // 设置子弹速度
bulletComp1.show(this.bulletSpeed, false); // 玩家飞机的子弹速度

// 右边的子弹
const bullet2 = instantiate(this.bullet03);
bullet2.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中
// 子弹出现的位置为飞机 Z轴 -7
bullet2.setPosition(pos.x + 2.5, pos.y, pos.z - 7);
// 获取 Bullet 组件 (脚本类)
const bulletComp2 = bullet2.getComponent(Bullet);
// bulletComp.bulletSpeed = this.bulletSpeed; // 设置子弹速度
bulletComp2.show(this.bulletSpeed, false); // 玩家飞机的子弹速度
}

// S型子弹为三发
public createPlayerBulletS() {
let pos = this.playerPlane.position; // 获取玩家飞机位置
// 中间子弹
const bullet1 = instantiate(this.bullet05);
bullet1.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中
// 子弹出现的位置为飞机 Z轴 -7
bullet1.setPosition(pos.x, pos.y, pos.z - 7);
// 获取 Bullet 组件 (脚本类)
const bulletComp1 = bullet1.getComponent(Bullet);
// bulletComp.bulletSpeed = this.bulletSpeed; // 设置子弹速度
bulletComp1.show(this.bulletSpeed, false); // 玩家飞机的子弹速度

// 左边子弹
const bullet2 = instantiate(this.bullet05);
bullet2.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中
// 子弹出现的位置为飞机 Z轴 -7
bullet2.setPosition(pos.x - 4, pos.y, pos.z - 7);
// 获取 Bullet 组件 (脚本类)
const bulletComp2 = bullet2.getComponent(Bullet);
// bulletComp.bulletSpeed = this.bulletSpeed; // 设置子弹速度
bulletComp2.show(this.bulletSpeed, false, Constant.Direction.LEFT); // 玩家飞机的子弹速度

// 右边子弹
const bullet3 = instantiate(this.bullet05);
bullet3.setParent(this.bulletRoot); // 子弹挂载到子弹管理节点中
// 子弹出现的位置为飞机 Z轴 -7
bullet3.setPosition(pos.x + 4, pos.y, pos.z - 7);
// 获取 Bullet 组件 (脚本类)
const bulletComp3 = bullet3.getComponent(Bullet);
// bulletComp.bulletSpeed = this.bulletSpeed; // 设置子弹速度
bulletComp3.show(this.bulletSpeed, false, Constant.Direction.RIGHT); // 玩家飞机的子弹速度
}

// 是否处理触摸状态,触摸才发射子弹
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);

// 获取子弹的碰撞器组件
const colliderComp = bullet.getComponent(BoxCollider);
// 设置敌机子弹的碰撞矩阵
colliderComp.setGroup(Constant.CollistionType.ENEMY_BULLET);
// 设置碰撞掩码 与 玩家飞机 碰撞
colliderComp.setMask(Constant.CollistionType.PLAYER_PLANE);

}

// 计分
public addScore() {

}

// 更换玩家子弹类型
public changeBulletType(type: number) {
this._bulletType = type;
}

// 创建子弹道具
public createBulletProp() {
const randomProp = math.randomRangeInt(1, 4);
console.log('create bullet prop:', randomProp);
let prefab: Prefab = null;
if (randomProp === Constant.BulletPropType.BULLET_H) {
prefab = this.bulletPropH;
} else if (randomProp === Constant.BulletPropType.BULLET_S) {
prefab = this.bulletPropS;
} else {
prefab = this.bulletPropM;
}

// 实例化子弹道具预览
const prop = instantiate(prefab);
prop.setParent(this.node);

// const prop = PoolManager.instance().getNode(prefab, this.node);

prop.setPosition(15, 0, -50); // 道具的起始位置
const propComp = prop.getComponent(BulletProp);
propComp.show(this, -this.bulletPropSpeed);
}


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

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

// 改变组合状态
private _modeChanged() {
this._combinationInterval++;
this.createBulletProp(); // 创建子弹道具
}
}

  1. 保存场景,运行预览。

===END===