开发工具

  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. 层级管理器 创建名为 audio空节点, 然后在 audio 节点上再创建一个 空节点,命名为 bgm(backgroundmusic), 点击选中 bgm 节点, 在 属性检查器 点击 添加组件 按钮, 选择 Audio -> AudioSource, 将 资源管理器 中的 assets/res/audio/music/bgm 拖动到 bgm 节点的 Clip 属性中, 选中 LoopPlayOnAwake 两个属性, Volume 属性的值改为 0.8
  1. 层级管理器 点击选中 plane01 节点, 在其 属性检查器 点击 添加组件 按钮, 选择 Audio -> AudioSource, 将 资源管理器 中的 assets/res/audio/sound/player 拖动到其 Clip 属性中, 取消 选中 LoopPlayOnAwake 两个属性。
  1. 资源管理器 点击选中 assets/script/framework 文件夹,右键 -> 创建 -> 脚本(TypeScript), 命名为 AudioManager, 脚本文件暂时不用编辑内容。

  2. 层级管理器 点击选中 audio 节点, 右键 -> 创建 -> 空节点, 命名为 effect, 在其 属性检查器 点击 添加组件 按钮, 选择 Audio -> AudioSource; 再点击一次 添加组件 按钮, 选择 自定义脚本 -> AudioManager

  1. 编辑脚本 AudioManager
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
import { _decorator, Component, Node, AudioClip, AudioSource } from 'cc';
const { ccclass, property } = _decorator;

interface IAudioMap {
[name: string]: AudioClip;
}

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

@property([AudioClip])
public audioList: AudioClip[] = [];

private _dict: IAudioMap = {};
private _audioSource: AudioSource = null;

start() {
for (let i = 0; i < this.audioList.length; i++) {
const element = this.audioList[i];
this._dict[element.name] = element;
}

console.log('sound: ', this._dict);
this._audioSource = this.getComponent(AudioSource)!;
}


public play(name: string) {
let audioClip = this._dict[name];
if (audioClip !== undefined) {
console.log('play audio:', audioClip.name);
this._audioSource.playOneShot(audioClip);
}
}
}
  1. 编辑 GameManager 脚本, 添加对 AudioManager 进行管理的代码:
  • 添加属性

  • 添加方法 playAudioEffect()

  • 更新方法: update()

完整代码如下:

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
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432

import { _decorator, Component, Node, Prefab, instantiate, math, Vec3, BoxCollider, Label, Animation, macro } from 'cc';
import { Bullet } from '../bullet/Bullet';
import { BulletProp } from '../bullet/BulletProp';
import { EnemyPlane } from '../plane/EnemyPlane';
import { PlayerPlane } from '../plane/PlayerPlane';
import { AudioManager } from './AudioManager';
import { Constant } from './Constant';
const { ccclass, property } = _decorator;


@ccclass('GameManager')
export class GameManager extends Component {
@property(PlayerPlane)
public playerPlane: PlayerPlane = 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; // 子弹类型道具速度

// ui
@property(Node)
public gamePage: Node = null;
@property(Node)
public gameOverPage: Node = null;
@property(Label)
public gameScore: Label = null;
@property(Label)
public gameOverScore: Label = null;
@property(Animation)
public overAnimation: Animation = null; // Animation 要手工添加导入

// audio
@property(AudioManager)
public audioEffect: AudioManager = null;

public isGameStart = false;

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

private _score: number = 0;

start() {
this._init();
}

update(deltaTime: number) {
if (!this.isGameStart) {
return;
}

if (this.playerPlane.isDie) {
this.gameOver();
return;
}

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();
}

// 子弹的音效,用除2的余数得到名字后面的数字字符
let name = 'bullet' + (this._bulletType % 2 + 1);
console.log('player shooting: ',name);
this.playAudioEffect(name);

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.node.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.node.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.node.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 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);
}


public returnMain() {
this._currShootTime = 0;
this._currCreateEnemyTiime = 0; // 当前敌机的生成时间
this._combinationInterval = Constant.Combination.PLAN1; // 组合的间隔状态
this._bulletType = Constant.BulletPropType.BULLET_M;
this.playerPlane.node.setPosition(0, 0, 15);
this._score = 0;
}

public gameReStart() {
this.gameStart();
this._currShootTime = 0;
this._currCreateEnemyTiime = 0; // 当前敌机的生成时间
this._combinationInterval = Constant.Combination.PLAN1; // 组合的间隔状态
this._bulletType = Constant.BulletPropType.BULLET_M;
this.playerPlane.node.setPosition(0, 0, 15);
}

public gameStart() {
this.isGameStart = true;
this.playerPlane.init();
this._changePlaneModel();
this._score = 0;
this.gameScore.string = this._score.toString();
}

public gameOver() {
this._isShooting = false;
this.isGameStart = false;
this.gamePage.active = false;
this.gameOverPage.active = true;
this.gameOverScore.string = this._score.toString();
this.overAnimation.play(); // 播放游戏结束的动画
this.gameScore.string = "0";
// this.playerPlane.init();
this.unschedule(this._modeChanged); // 取消定时器
this._destoryAll();
}

public addScore() {
this._score++;
this.gameScore.string = this._score.toString();
}

public playAudioEffect(name: string) {
this.audioEffect.play(name);
}


private _destoryAll() {
let children = this.node.children;
let length = children.length;
// 销毁对象时要从后往前,不能从前往后
for (let index = length - 1; index >= 0; index--) {
const child = children[index];
child.destroy();
}

children = this.bulletRoot.children;
length = children.length;
// 销毁对象时要从后往前,不能从前往后
for (let index = length - 1; index >= 0; index--) {
const child = children[index];
child.destroy();
}
}

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

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

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

  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
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

import { _decorator, Component, Node, Collider, ITriggerEvent } from 'cc';
import { Constant } from '../framework/Constant';
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;

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) {
// 获取分组
const collisionGroup = event.otherCollider.getGroup();
// 遇到玩家飞机或子弹,敌人飞机销毁
if (collisionGroup === Constant.CollistionType.PLAYER_PLANE
|| collisionGroup === Constant.CollistionType.PLAYER_BULLET) {
console.log('trigger enemy destroy');
this._gameManager.playAudioEffect('enemy'); // 播放声音
this.node.destroy();
this._gameManager.addScore(); // 分数增加
}
}

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. 编辑 PlayerPlane 脚本, 添加玩家飞机的音效
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
import { _decorator, Component, Node, Collider, ITriggerEvent, AudioSource } from 'cc';
import { Constant } from '../framework/Constant';
const { ccclass, property } = _decorator;

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

public lifeValue = 5; //玩家飞机生命
public isDie = false;

private _currLife = 0;
private _audioSource: AudioSource = 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);
}

start() {
this._audioSource = this.getComponent(AudioSource);
}

public init() {
this._currLife = this.lifeValue;
this.isDie = false;
}

private _onTriggerEnter(event: ITriggerEvent) {
// 获取分组
const collisionGroup = event.otherCollider.getGroup();
// 遇到敌方飞机或敌方子弹,玩家飞机掉血
if (collisionGroup === Constant.CollistionType.ENEMY_PLANE
|| collisionGroup === Constant.CollistionType.ENEMY_BULLET) {
// 现在玩家飞机发生碰撞只在控制台输出文件
this._currLife--;
console.log('player plane reduce blood:', this._currLife);
if (this._currLife <= 0) {
this.isDie = true;
this._audioSource.play();
}
}
}
}

  1. 编辑 UIManager 脚本,添加按钮音效
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

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

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

@property
public playerPlaneSpeed = 1;
@property(Node)
public playerPlane: Node = null;

// 添加游戏控制脚本
@property(GameManager)
public gameManager: GameManager = null;

@property(Node)
public gameStart: Node = null;
@property(Node)
public game: Node = null;
@property(Node)
public gameOver: Node = null;

start() {
this.node.on(Input.EventType.TOUCH_START, this._touchStart, this);
this.node.on(Input.EventType.TOUCH_MOVE, this._touchMove, this);
this.node.on(Input.EventType.TOUCH_END, this._touchEnd, this);
this.gameStart.active = true; // 显示开始界面
}

// 重新开始按钮对应代码
public reStart() {
this.gameOver.active = false;
this.game.active = true;
this.gameManager.audioEffect.play('button');
this.gameManager.gameReStart();
}

// 返回主页按钮代码
public returnMain() {
this.gameOver.active = false;
this.gameStart.active = true;
this.gameManager.audioEffect.play('button');
this.gameManager.returnMain();
}

private _touchMove(touch: Touch, event: EventTouch) {
if(!this.gameManager.isGameStart){
return;
}

// touch.getDelta() 获取当前触点值与上一次触点值的差值
let delta = touch.getDelta();
let pos = this.playerPlane.position; // 获取当前节点的位置
// 在速度前乘以 0.01 是用于调整移动的速度
this.playerPlane.setPosition(
pos.x + 0.01 * this.playerPlaneSpeed * delta.x,
pos.y,
pos.z - 0.01 * this.playerPlaneSpeed * delta.y);
}

// 开始触摸屏幕的回调方法
private _touchStart(touch: Touch, event: EventTouch) {
if (this.gameManager.isGameStart) {
this.gameManager.isShooting(true); // 触摸屏幕时玩家飞机开始射击
} else {
this.gameStart.active = false;
this.game.active = true;
this.gameManager.audioEffect.play('button');
this.gameManager.gameStart();
}
}

private _touchEnd(touch: Touch, event: EventTouch) {
if (!this.gameManager.isGameStart) {
return;
}
// 停止触摸时玩家飞机结束射击
this.gameManager.isShooting(false);
}
}

  1. 层级管理器 点击选中 audio/effect 节点, 其 AudioList 属性的值改为 4, 点击名字左边的 三角符号, 依次将 bullet1bullet2buttonenemy 四个音效拖进去。
  1. 层级管理器 中将 audio/effect 节点关联到 gameManager 节点的属性 AudioEfect
  1. 保存场景, 运行预览。

===END===