From 5a6ae0b679170c5933283df94c01af57d5dc6f59 Mon Sep 17 00:00:00 2001 From: k8w Date: Tue, 28 Dec 2021 22:45:50 +0800 Subject: [PATCH] GameStateManager --- .../backend/src/api/ApiLogin.ts | 6 +- .../backend/src/api/room/ApiJoinRoom.ts | 4 +- .../backend/src/models/Room.ts | 7 +- .../backend/src/shared/game/GameSystem.ts | 8 +- .../src/shared/game/GameSystemInput.ts | 14 +- .../backend/src/shared/protocols/PtlLogin.ts | 4 +- .../src/shared/protocols/room/PtlJoinRoom.ts | 3 +- .../room/server/MsgUpdateRoomState.ts | 2 +- .../src/shared/protocols/serviceProto.ts | 184 +-- .../backend/src/shared/types/RoomState.ts | 7 + .../frontend/assets/env.ts | 1 + .../{gameManager.ts => GameController.ts} | 1122 ++++++++--------- ...Manager.ts.meta => GameController.ts.meta} | 0 .../assets/script/GameStateManager.ts | 187 +++ .../frontend/assets/script/StateManager.ts | 133 -- .../assets/script/bullet/bulletManager.ts | 2 +- .../assets/script/bullet/fightIconBullet.ts | 2 +- .../assets/script/plane/enemyPlane.ts | 2 +- .../frontend/assets/script/plane/selfPlane.ts | 2 +- .../frontend/assets/script/ui/uiMain.ts | 2 +- .../frontend/package.json | 4 + .../frontend/tsconfig.json | 6 +- 22 files changed, 887 insertions(+), 815 deletions(-) create mode 100644 examples/cocos-creator-airplane/backend/src/shared/types/RoomState.ts create mode 100644 examples/cocos-creator-airplane/frontend/assets/env.ts rename examples/cocos-creator-airplane/frontend/assets/script/{gameManager.ts => GameController.ts} (97%) rename examples/cocos-creator-airplane/frontend/assets/script/{gameManager.ts.meta => GameController.ts.meta} (100%) create mode 100644 examples/cocos-creator-airplane/frontend/assets/script/GameStateManager.ts delete mode 100644 examples/cocos-creator-airplane/frontend/assets/script/StateManager.ts diff --git a/examples/cocos-creator-airplane/backend/src/api/ApiLogin.ts b/examples/cocos-creator-airplane/backend/src/api/ApiLogin.ts index fc69659..0da7d98 100644 --- a/examples/cocos-creator-airplane/backend/src/api/ApiLogin.ts +++ b/examples/cocos-creator-airplane/backend/src/api/ApiLogin.ts @@ -1,17 +1,17 @@ -import { ApiCall, ApiCallWs } from "tsrpc"; +import { ApiCallWs } from "tsrpc"; import { ReqLogin, ResLogin } from "../shared/protocols/PtlLogin"; let nextPlayerId = 1; export async function ApiLogin(call: ApiCallWs) { let playerId = nextPlayerId++; - + call.conn.currentUser = { id: playerId, nickname: call.req.nickname } call.succ({ - playerId: playerId + currentUser: call.conn.currentUser }) } \ No newline at end of file diff --git a/examples/cocos-creator-airplane/backend/src/api/room/ApiJoinRoom.ts b/examples/cocos-creator-airplane/backend/src/api/room/ApiJoinRoom.ts index 6c3977a..cd8808b 100644 --- a/examples/cocos-creator-airplane/backend/src/api/room/ApiJoinRoom.ts +++ b/examples/cocos-creator-airplane/backend/src/api/room/ApiJoinRoom.ts @@ -11,5 +11,7 @@ export async function ApiJoinRoom(call: ApiCallWs) { return call.error(op.errMsg); } - call.succ({}); + call.succ({ + roomState: room.state + }); } \ No newline at end of file diff --git a/examples/cocos-creator-airplane/backend/src/models/Room.ts b/examples/cocos-creator-airplane/backend/src/models/Room.ts index e5196e2..33172fa 100644 --- a/examples/cocos-creator-airplane/backend/src/models/Room.ts +++ b/examples/cocos-creator-airplane/backend/src/models/Room.ts @@ -7,15 +7,10 @@ import { GameSystemState } from "../shared/game/GameSystemState"; import { MsgGameInput } from "../shared/protocols/game/client/MsgGameInput"; import { ServiceType } from "../shared/protocols/serviceProto"; import { CurrentUser } from "../shared/types/CurrentUser"; +import { RoomState } from "../shared/types/RoomState"; const MAX_ROOM_USER = 2; -export interface RoomState { - id: uint; - players: { id: uint, nickname: string, isReady: boolean }[]; - status: 'wait' | 'ready' | 'start'; -} - /** * 服务端 - 房间 - 逻辑系统 */ diff --git a/examples/cocos-creator-airplane/backend/src/shared/game/GameSystem.ts b/examples/cocos-creator-airplane/backend/src/shared/game/GameSystem.ts index 05ad25c..55f6f2f 100644 --- a/examples/cocos-creator-airplane/backend/src/shared/game/GameSystem.ts +++ b/examples/cocos-creator-airplane/backend/src/shared/game/GameSystem.ts @@ -78,11 +78,11 @@ export class GameSystem { } // 子弹碰撞,抵消 case 'BulletHit': { - let player = this.state.players.find(v => v.id === input.player.id); - let enemy = this.state.enemies.find(v => v.id === input.enemy.id); + let player = this.state.players.find(v => v.id === input.playerId); + let enemy = this.state.enemies.find(v => v.id === input.enemyId); if (player && enemy) { - player.bullets.removeOne(v => v.id === input.player.bulletId); - enemy.bullets.removeOne(v => v.id === input.enemy.bulletId); + player.bullets.removeOne(v => v.id === input.playerBulletId); + enemy.bullets.removeOne(v => v.id === input.enemyBulletId); } break; } diff --git a/examples/cocos-creator-airplane/backend/src/shared/game/GameSystemInput.ts b/examples/cocos-creator-airplane/backend/src/shared/game/GameSystemInput.ts index c6fd08f..4de95fa 100644 --- a/examples/cocos-creator-airplane/backend/src/shared/game/GameSystemInput.ts +++ b/examples/cocos-creator-airplane/backend/src/shared/game/GameSystemInput.ts @@ -1,4 +1,4 @@ -import { uint } from "tsrpc"; +import { uint } from "tsrpc-proto"; import { PlayerState } from "./GameSystemState"; // 移动并攻击 @@ -34,14 +34,10 @@ export interface PlayerHurt { // 子弹互相碰撞,双双消失 export interface BulletHit { type: 'BulletHit', - player: { - id: uint, - bulletId: uint - }, - enemy: { - id: uint, - bulletId: uint - }, + playerId: uint, + playerBulletId: uint, + enemyId: uint, + enemyBulletId: uint } // 时间流逝 diff --git a/examples/cocos-creator-airplane/backend/src/shared/protocols/PtlLogin.ts b/examples/cocos-creator-airplane/backend/src/shared/protocols/PtlLogin.ts index 6b13b6f..b175f1d 100644 --- a/examples/cocos-creator-airplane/backend/src/shared/protocols/PtlLogin.ts +++ b/examples/cocos-creator-airplane/backend/src/shared/protocols/PtlLogin.ts @@ -1,4 +1,4 @@ -import { uint } from "tsrpc"; +import { CurrentUser } from "../types/CurrentUser"; import { BaseConf, BaseRequest, BaseResponse } from "./base"; export interface ReqLogin extends BaseRequest { @@ -6,7 +6,7 @@ export interface ReqLogin extends BaseRequest { } export interface ResLogin extends BaseResponse { - playerId: uint + currentUser: CurrentUser } export const conf: BaseConf = { diff --git a/examples/cocos-creator-airplane/backend/src/shared/protocols/room/PtlJoinRoom.ts b/examples/cocos-creator-airplane/backend/src/shared/protocols/room/PtlJoinRoom.ts index 2be24b1..49605a4 100644 --- a/examples/cocos-creator-airplane/backend/src/shared/protocols/room/PtlJoinRoom.ts +++ b/examples/cocos-creator-airplane/backend/src/shared/protocols/room/PtlJoinRoom.ts @@ -1,4 +1,5 @@ import { uint } from "tsrpc-proto"; +import { RoomState } from "../../types/RoomState"; import { BaseConf, BaseRequest, BaseResponse } from "../base"; export interface ReqJoinRoom extends BaseRequest { @@ -6,7 +7,7 @@ export interface ReqJoinRoom extends BaseRequest { } export interface ResJoinRoom extends BaseResponse { - + roomState: RoomState; } export const conf: BaseConf = { diff --git a/examples/cocos-creator-airplane/backend/src/shared/protocols/room/server/MsgUpdateRoomState.ts b/examples/cocos-creator-airplane/backend/src/shared/protocols/room/server/MsgUpdateRoomState.ts index ec6368e..9518414 100644 --- a/examples/cocos-creator-airplane/backend/src/shared/protocols/room/server/MsgUpdateRoomState.ts +++ b/examples/cocos-creator-airplane/backend/src/shared/protocols/room/server/MsgUpdateRoomState.ts @@ -1,4 +1,4 @@ -import { RoomState } from "../../../../models/Room"; +import { RoomState } from "../../../types/RoomState"; export interface MsgUpdateRoomState { state: RoomState diff --git a/examples/cocos-creator-airplane/backend/src/shared/protocols/serviceProto.ts b/examples/cocos-creator-airplane/backend/src/shared/protocols/serviceProto.ts index 4110e3e..e3d0261 100644 --- a/examples/cocos-creator-airplane/backend/src/shared/protocols/serviceProto.ts +++ b/examples/cocos-creator-airplane/backend/src/shared/protocols/serviceProto.ts @@ -570,53 +570,35 @@ export const serviceProto: ServiceProto = { } }, { - "id": 1, - "name": "player", + "id": 3, + "name": "playerId", "type": { - "type": "Interface", - "properties": [ - { - "id": 0, - "name": "id", - "type": { - "type": "Number", - "scalarType": "uint" - } - }, - { - "id": 1, - "name": "bulletId", - "type": { - "type": "Number", - "scalarType": "uint" - } - } - ] + "type": "Number", + "scalarType": "uint" } }, { - "id": 2, - "name": "enemy", + "id": 4, + "name": "playerBulletId", "type": { - "type": "Interface", - "properties": [ - { - "id": 0, - "name": "id", - "type": { - "type": "Number", - "scalarType": "uint" - } - }, - { - "id": 1, - "name": "bulletId", - "type": { - "type": "Number", - "scalarType": "uint" - } - } - ] + "type": "Number", + "scalarType": "uint" + } + }, + { + "id": 5, + "name": "enemyId", + "type": { + "type": "Number", + "scalarType": "uint" + } + }, + { + "id": 6, + "name": "enemyBulletId", + "type": { + "type": "Number", + "scalarType": "uint" } } ] @@ -1143,11 +1125,11 @@ export const serviceProto: ServiceProto = { ], "properties": [ { - "id": 0, - "name": "playerId", + "id": 1, + "name": "currentUser", "type": { - "type": "Number", - "scalarType": "uint" + "type": "Reference", + "target": "../types/CurrentUser/CurrentUser" } } ] @@ -1155,6 +1137,26 @@ export const serviceProto: ServiceProto = { "base/BaseResponse": { "type": "Interface" }, + "../types/CurrentUser/CurrentUser": { + "type": "Interface", + "properties": [ + { + "id": 0, + "name": "id", + "type": { + "type": "Number", + "scalarType": "uint" + } + }, + { + "id": 1, + "name": "nickname", + "type": { + "type": "String" + } + } + ] + }, "room/PtlCreateRoom/ReqCreateRoom": { "type": "Interface", "extends": [ @@ -1245,55 +1247,19 @@ export const serviceProto: ServiceProto = { "target": "base/BaseResponse" } } - ] - }, - "room/PtlSetReady/ReqSetReady": { - "type": "Interface", - "extends": [ - { - "id": 0, - "type": { - "type": "Reference", - "target": "base/BaseRequest" - } - } ], "properties": [ { "id": 0, - "name": "isReady", - "type": { - "type": "Boolean" - } - } - ] - }, - "room/PtlSetReady/ResSetReady": { - "type": "Interface", - "extends": [ - { - "id": 0, + "name": "roomState", "type": { "type": "Reference", - "target": "base/BaseResponse" + "target": "../types/RoomState/RoomState" } } ] }, - "room/server/MsgUpdateRoomState/MsgUpdateRoomState": { - "type": "Interface", - "properties": [ - { - "id": 0, - "name": "state", - "type": { - "type": "Reference", - "target": "../../models/Room/RoomState" - } - } - ] - }, - "../../models/Room/RoomState": { + "../types/RoomState/RoomState": { "type": "Interface", "properties": [ { @@ -1305,7 +1271,7 @@ export const serviceProto: ServiceProto = { } }, { - "id": 3, + "id": 1, "name": "players", "type": { "type": "Array", @@ -1369,6 +1335,52 @@ export const serviceProto: ServiceProto = { } } ] + }, + "room/PtlSetReady/ReqSetReady": { + "type": "Interface", + "extends": [ + { + "id": 0, + "type": { + "type": "Reference", + "target": "base/BaseRequest" + } + } + ], + "properties": [ + { + "id": 0, + "name": "isReady", + "type": { + "type": "Boolean" + } + } + ] + }, + "room/PtlSetReady/ResSetReady": { + "type": "Interface", + "extends": [ + { + "id": 0, + "type": { + "type": "Reference", + "target": "base/BaseResponse" + } + } + ] + }, + "room/server/MsgUpdateRoomState/MsgUpdateRoomState": { + "type": "Interface", + "properties": [ + { + "id": 0, + "name": "state", + "type": { + "type": "Reference", + "target": "../types/RoomState/RoomState" + } + } + ] } } }; \ No newline at end of file diff --git a/examples/cocos-creator-airplane/backend/src/shared/types/RoomState.ts b/examples/cocos-creator-airplane/backend/src/shared/types/RoomState.ts new file mode 100644 index 0000000..bffdbb8 --- /dev/null +++ b/examples/cocos-creator-airplane/backend/src/shared/types/RoomState.ts @@ -0,0 +1,7 @@ +import { uint } from "tsrpc-proto"; + +export interface RoomState { + id: uint; + players: { id: uint, nickname: string, isReady: boolean }[]; + status: 'wait' | 'ready' | 'start'; +} \ No newline at end of file diff --git a/examples/cocos-creator-airplane/frontend/assets/env.ts b/examples/cocos-creator-airplane/frontend/assets/env.ts new file mode 100644 index 0000000..4920adc --- /dev/null +++ b/examples/cocos-creator-airplane/frontend/assets/env.ts @@ -0,0 +1 @@ +import 'k8w-extend-native'; diff --git a/examples/cocos-creator-airplane/frontend/assets/script/gameManager.ts b/examples/cocos-creator-airplane/frontend/assets/script/GameController.ts similarity index 97% rename from examples/cocos-creator-airplane/frontend/assets/script/gameManager.ts rename to examples/cocos-creator-airplane/frontend/assets/script/GameController.ts index 8f4acb2..5f1121f 100644 --- a/examples/cocos-creator-airplane/frontend/assets/script/gameManager.ts +++ b/examples/cocos-creator-airplane/frontend/assets/script/GameController.ts @@ -1,561 +1,561 @@ -import { AudioManager } from './framework/audioManager'; - -import { _decorator, Component, Node, setDisplayStats, Prefab, instantiate, find, NodePool, Vec3, director, PhysicsSystem, game, Pool, Label, Socket, Quat, AudioSource, AudioClip } from 'cc'; -import { bulletManager } from './bullet/bulletManager'; -import { FightIconBullet } from './bullet/fightIconBullet'; -import { Constant } from './framework/constant'; -import { PoolManager } from './framework/poolManager'; -import { enemyPlane } from './plane/enemyPlane'; -import { selfPlane } from './plane/selfPlane'; -import { MovingSceneBg } from './ui/common/movingSceneBg'; - -const { ccclass, property } = _decorator; - - -let _temp_quat = new Quat; - - - -@ccclass('GameManager') -export class GameManager extends Component { - - @property(Node) - public playerPlane: Node = null; //玩家飞机节点 - @property(Prefab) - public bullet1: Prefab = null; //子弹类型1 - @property(Prefab) - public bullet2: Prefab = null; //子弹类型2 - @property(Prefab) - public bullet3: Prefab = null; //子弹类型3 - @property(Prefab) - public bullet4: Prefab = null; //子弹类型4 - @property(Prefab) - public bullet5: Prefab = null; //子弹类型5 - //道具图标预制物 - @property(Prefab) - public bulletIcon1: Prefab = null; //道具1 - @property(Prefab) - public bulletIcon2: Prefab = null; //道具2 - @property(Prefab) - public bulletIcon3: Prefab = null; //道具3 - //积分面板 - @property(Node) - public scorePanel: Node = null; - @property(Label) - public jifen: Label = null; //分数 - @property(Label) - public gameOverScore = null; //结束的分数界面 - //背景地图 - @property(Node) - public bgMap: Node = null; - //敌机的声明 - @property(Prefab) - public enemy1: Prefab = null; - @property(Prefab) - public enemy2: Prefab = null; - @property(Node) - public gameOverUi: Node = null; //结束界面ui - @property(Node) - public gameStartUi: Node = null; //开始界面ui - @property(Node) - public cocosUi: Node = null; //cocos图标 - @property(Node) - public ball: Node = null; //背景星球 - @property - public bulletSpeedTime: number = 12; //子弹射击间隔时间 - @property - public enemyTime: number = 60; //敌机生成时间 - - //bgm - @property(AudioSource) - public audio: AudioSource = null!; - //按钮点击音效 - @property(AudioSource) - public buttonAudio: AudioSource = null!; - - //道具掉落时间 - @property - public dropTime: number = 600; //现在是10s - - //敌机速度,在此处更改 - @property - public enemy1Speed: number = 0.5; //敌机1的速度 - @property - public enemy2Speed: number = 0.7; //敌机2的速度 - - //星球和标志移动速度 - @property - public cocosSpeed: number = 0.1; - //子弹速度 - @property - public bulletSpeed: number = 1; - //分数 - public score: number = 0; - //玩家飞机是否可以射击,操作开关在uiManin.ts中, - public shooting: boolean = false; - //游戏是否开始,操作开关在uiManin.ts中, - public starting: boolean = false; - - public selfPlaneIsDie: boolean = false; //判断玩家飞机是否死亡 - - public isWhichBullet: number; //判断是哪种子弹 - public conbinationInterval: number //组合间隔 - public timing: boolean = true; - private shootTime: number = 0; - private _enemyTime: number; //创建敌机的间隔时间 - private _combinationTime: number; //组合出现间隔时间 - - private _iconTime: number = 0; - private _cocosSpeed: number = this.cocosSpeed; //标志移动 - private _ballSpeed: number = this.cocosSpeed; //星球移动 - - - onLoad() { - //开启碰撞检测 - PhysicsSystem.instance.enable = true; - setDisplayStats(false); //关闭左下角的调试信息 - this.isWhichBullet = Constant.FIGHT_BULLET_GROUP.BULLET_M //一开始默认用m号子弹 - this.shootTime = 0; - this._enemyTime = 0; - this._combinationTime = 0; - this.conbinationInterval = 1 - this._iconTime = 0; - this.playerPlane.getComponent(selfPlane).show(this); - //开始时候分数置0 - this.score = 0; - this.timing = true; - - - - } - - update(deltaTime: number) { - - if(!this.audio.getComponent(AudioSource).playing) { - this.audio.getComponent(AudioSource).play(); - } - - //实时显示分数 - this.jifen.string = this.score.toString(); - this.gameOverScore.string = this.score.toString(); - if (!this.selfPlaneIsDie) { - //当玩家没有死亡的时候执行的代码 - //背景星球和标志移动 - if (this.cocosUi.position.x >= 18) { this._cocosSpeed = -this.cocosSpeed } - else if (this.cocosUi.position.x <= -18) { this._cocosSpeed = this.cocosSpeed } - this.cocosUi.setPosition(this.cocosUi.position.x + this._cocosSpeed, this.cocosUi.position.y, this.cocosUi.position.z); - - if (this.ball.position.x >= 18) { this._ballSpeed = -this.cocosSpeed } - else if (this.ball.position.x <= -18) { this._ballSpeed = this.cocosSpeed } - this.ball.setPosition(this.ball.position.x + this._ballSpeed, this.ball.position.y, this.ball.position.z); - - let rad = 1 * Math.PI / 180; - this.ball.getRotation(_temp_quat); - Quat.rotateZ(_temp_quat, _temp_quat, rad); - this.ball.setRotation(_temp_quat); - - //子弹射击,一开始子弹的类型为m,黄色单列 - this.shootTime++; - if (this.shooting && this.shootTime >= this.bulletSpeedTime) { - console.log(this.isWhichBullet, '子弹类型') - if (this.isWhichBullet == Constant.FIGHT_BULLET_GROUP.BULLET_M) { - //发射m型号的子弹 - this.creatorBullet1(this.bullet1); - } - else if (this.isWhichBullet == Constant.FIGHT_BULLET_GROUP.BULLET_S) { - //发射S型号的子弹 - this.creatorBullet2(this.bullet2); - } - else if (this.isWhichBullet == Constant.FIGHT_BULLET_GROUP.BULLET_H) { - //发射H型号的子弹 - this.creatorBullet3(this.bullet3); - } - this.shootTime = 0; - } - - //游戏每隔10随机出现一个道具 - if (this.starting) { - this._iconTime++; - if (this._iconTime >= this.dropTime) { - this._iconTime = 0; - let iconValue = this.getRandomNum(1, 3); - if (iconValue == 1) { this.creatorFightIcon(this.bulletIcon1); } - else if (iconValue == 2) { this.creatorFightIcon(this.bulletIcon2); } - else if (iconValue == 3) { this.creatorFightIcon(this.bulletIcon3); } - } - } - this._combinationTime++; - if (this.conbinationInterval == Constant.COMBINATION.COMBINATE1) { - //敌机 这里的生成时间设置成60 - this._enemyTime++; - if (this.starting && this._enemyTime >= this.enemyTime) { - let whichEnemy: number = this.getRandomNum(1, 2); //随机取两个值,代表不同的两个敌机 - if (whichEnemy == Constant.COMBINATION.COMBINATE1) { - this.creatorEnemy1(); - this._enemyTime = 0; - } - else if (whichEnemy == Constant.COMBINATION.COMBINATE2) { - this.creatorEnemy2(); - this._enemyTime = 0; - } - - } - - } - - else if (this.conbinationInterval == Constant.COMBINATION.COMBINATE2) { - - //来到时间段2,敌机出现时间间隔为原来的0.8倍 - if (this.starting && this._combinationTime >= this.enemyTime * 3) { - let combinate: number = this.getRandomNum(1, 2); - if (combinate == Constant.COMBINATION.COMBINATE1) { - this.creatorCombination1(this.enemy1); - this._combinationTime = 0; - } - else if (combinate == Constant.COMBINATION.COMBINATE2) { - this.creatorEnemy2(); - this._combinationTime = 0; - } - } - } - else { - - //来到时间段2,敌机出现时间间隔为原来的3倍 - if (this.starting && this._combinationTime >= this.enemyTime * 2) { - let combinate: number = this.getRandomNum(1, 3); - if (combinate == Constant.COMBINATION.COMBINATE1) { - this.creatorCombination1(this.enemy1); - this._combinationTime = 0; - } - else if (combinate == Constant.COMBINATION.COMBINATE2) { - this.creatorCombination2(this.enemy2); - this._combinationTime = 0; - } - else if (combinate == Constant.COMBINATION.COMBINATE3) { - this.creatorEnemy1(); - this.creatorEnemy2(); - this._combinationTime = 0; - } - } - } - - - - } - if (this.selfPlaneIsDie) { - this.gameOver(); //玩家死亡后执行游戏结束函数 - } - } - - //开启一个计时器,随时间改变游戏难度 - public glodeDifficulty() { - let callback = () => { - if (this.selfPlaneIsDie) { - this.unschedule(callback); - } - this.conbinationInterval++; - } - - this.schedule(callback, 10); - - } - - //游戏结束 - public gameOver() { - this.bgMap.getComponent(MovingSceneBg).bgSpeed = 0; //背景停止移动 - this.removeAllBullet(); //移除所有子弹 - this.conbinationInterval = 1;//组合变回1 - this.scorePanel.active = false; - } - - //游戏重新开始 - public gameRestart() { - this.buttonAudio.getComponent(AudioSource).play(); - this.bgMap.getComponent(MovingSceneBg).bgSpeed = 10; - this.dataReSet(); - - - } - - //游戏返回到主界面 - public gameMain() { - this.buttonAudio.getComponent(AudioSource).play(); - this.bgMap.getComponent(MovingSceneBg).bgSpeed = 0; - this.dataReSet(); - - this.starting = false; - this.gameStartUi.active = true; - - this.scorePanel.active = false; - - - } - - public dataReSet() { - this.removeAllEnemy(); - this.removeAllItem(); - this.selfPlaneIsDie = false; - this.playerPlane.getComponent(selfPlane).dieEffect.active = false; - this.playerPlane.getComponent(selfPlane).init(); - this.playerPlane.getComponent(selfPlane).lifeBloodBg.active = false; - this.playerPlane.getComponent(selfPlane).lifeBlood.active = false; - this.gameOverUi.active = false; - this.isWhichBullet = Constant.FIGHT_BULLET_GROUP.BULLET_M; - this.score = 0; - this.timing = true; - this.shooting = false; - this.playerPlane.setPosition(0, 0, 15); - } - - //创建道具 - public creatorFightIcon(prefebIcon: Prefab) { - let bulletIcon = null; - bulletIcon = PoolManager.instance.getNode(prefebIcon, this.node); - bulletIcon.parent = this.node; - bulletIcon.setScale(1.5, 1, 0.8); - bulletIcon.setPosition(0, 0, -50); - bulletIcon.getComponent(FightIconBullet).show(this); - - } - //移除道具 - public fightIconKill(prefebIcon) { - PoolManager.instance.putNode(prefebIcon); - //console.log('道具被销毁'); - } - - //创建我方飞机子弹对象1 - public creatorBullet1(prefebBullet: Prefab) { - let bullet = null; - - bullet = PoolManager.instance.getNode(prefebBullet, this.node); - //bullet.parent = this.node; - let pos: Vec3 = this.playerPlane.getPosition(); - //将子弹大小设置为于飞机同样大小 - bullet.setScale(8, 8, 8); - //将子弹位置设置在飞机前方 - bullet.setPosition(pos.x, pos.y, pos.z - this.playerPlane.getScale().z); - //console.log(bullet.getPosition()) - //将gameManger传入脚本bulletManager中 - bullet.getComponent(bulletManager).show(this, this.bulletSpeed); - bullet.getComponent(bulletManager).setBulletGroup(true); - bullet.getComponent(bulletManager).playerBullet = true; - bullet.getComponent(bulletManager).enemyBullet = false; - bullet.getComponent(bulletManager).bulletType = Constant.BULLET_DIRECTION.CENTRAL; - - } - //创建我放飞机子弹对象2 - public creatorBullet2(prefebBullet: Prefab) { - let bullet1 = null; - let bullet2 = null; - bullet1 = PoolManager.instance.getNode(prefebBullet, this.node); - bullet2 = PoolManager.instance.getNode(prefebBullet, this.node); - - let pos: Vec3 = this.playerPlane.getPosition(); - //将子弹大小设置为于飞机同样大小 - bullet1.setScale(8, 8, 8); - bullet2.setScale(8, 8, 8); - - //将子弹位置设置在飞机前方,该子弹位置应该放在飞机前方5,两边相差5 - bullet1.setPosition(pos.x + 2.5, pos.y, pos.z - 5); - bullet2.setPosition(pos.x - 2.5, pos.y, pos.z - 5); - - //console.log(bullet.getPosition()) - //将gameManger传入脚本bulletManager中 - bullet1.getComponent(bulletManager).show(this, this.bulletSpeed); - bullet2.getComponent(bulletManager).show(this, this.bulletSpeed); - bullet1.getComponent(bulletManager).setBulletGroup(true); - bullet2.getComponent(bulletManager).setBulletGroup(true); - bullet1.getComponent(bulletManager).playerBullet = true; - bullet2.getComponent(bulletManager).playerBullet = true; - bullet1.getComponent(bulletManager).enemyBullet = false; - bullet2.getComponent(bulletManager).enemyBullet = false; - bullet1.getComponent(bulletManager).bulletType = Constant.BULLET_DIRECTION.CENTRAL; - bullet2.getComponent(bulletManager).bulletType = Constant.BULLET_DIRECTION.CENTRAL; - } - - //创建我放飞机子弹对象3 - public creatorBullet3(prefebBullet: Prefab) { - let bullet1 = null; - let bullet2 = null; - let bullet3 = null; - bullet1 = PoolManager.instance.getNode(prefebBullet, this.node); - bullet2 = PoolManager.instance.getNode(prefebBullet, this.node); - bullet3 = PoolManager.instance.getNode(prefebBullet, this.node); - - let pos: Vec3 = this.playerPlane.getPosition(); - //将子弹大小设置为于飞机同样大小 - bullet1.setScale(8, 8, 8); - bullet2.setScale(8, 8, 8); - bullet3.setScale(8, 8, 8); - - //将子弹位置设置在飞机前方,该子弹位置应该放在飞机前方5,两边相差5 - bullet1.setPosition(pos.x + 2.5, pos.y, pos.z - 4); - bullet2.setPosition(pos.x - 2.5, pos.y, pos.z - 4); - bullet3.setPosition(pos.x, pos.y, pos.z - 8); - - //console.log(bullet.getPosition()) - //将gameManger传入脚本bulletManager中 - bullet1.getComponent(bulletManager).show(this, this.bulletSpeed); - bullet2.getComponent(bulletManager).show(this, this.bulletSpeed); - bullet3.getComponent(bulletManager).show(this, this.bulletSpeed); - bullet1.getComponent(bulletManager).setBulletGroup(true); - bullet2.getComponent(bulletManager).setBulletGroup(true); - bullet3.getComponent(bulletManager).setBulletGroup(true); - - bullet1.getComponent(bulletManager).playerBullet = true; - bullet2.getComponent(bulletManager).playerBullet = true; - bullet3.getComponent(bulletManager).playerBullet = true; - - bullet1.getComponent(bulletManager).enemyBullet = false; - bullet2.getComponent(bulletManager).enemyBullet = false; - bullet3.getComponent(bulletManager).enemyBullet = false; - - bullet1.getComponent(bulletManager).bulletType = Constant.BULLET_DIRECTION.RIGHT; - bullet2.getComponent(bulletManager).bulletType = Constant.BULLET_DIRECTION.LEFT; - bullet3.getComponent(bulletManager).bulletType = Constant.BULLET_DIRECTION.CENTRAL; - } - //创建敌机1对象 - public creatorEnemy1() { - let enemy = null; - enemy = PoolManager.instance.getNode(this.enemy1, this.node); - //将敌机1大小设置为5 - enemy.setScale(5, 5, 5); - //将敌机位置设置在屏幕最上方,位置为-60的位置 - enemy.getComponent(enemyPlane).show(this, this.enemy1Speed, true); - - //随机敌机在屏幕的x轴位置 - let enemyPos_x = this.getRandomNum(-20, 20); - enemy.setPosition(enemyPos_x, 0, -50); - - } - - //创建敌机2对象 - public creatorEnemy2() { - let enemy = null; - enemy = PoolManager.instance.getNode(this.enemy2, this.node); - //将敌机1大小设置为5 - enemy.setScale(5, 5, 5); - //将敌机位置设置在屏幕最上方,位置为-50的位置 - enemy.getComponent(enemyPlane).show(this, this.enemy2Speed, true); - - //随机敌机在屏幕的x轴位置 - let enemyPos_x = this.getRandomNum(-20, 20); - enemy.setPosition(enemyPos_x, 0, -50); - } - - //创建组合1,该组合为一字型 - public creatorCombination1(enemy: Prefab) { - let enemyArray = new Array(5); - - for (let index = 0; index < enemyArray.length; index++) { - enemyArray[index] = PoolManager.instance.getNode(enemy, this.node); - enemyArray[index].setScale(5, 5, 5); - enemyArray[index].getComponent(enemyPlane).show(this, this.enemy2Speed, false); - enemyArray[index].setPosition(-20 + index * 10, 0, -50) //位置放在-50处,在屏幕的上方出现 - } - - - - } - - //创建组合2,该组合为人字型 - public creatorCombination2(enemy: Prefab) { - let enemyArray = new Array(7); - for (let index = 0; index < enemyArray.length; index++) { - enemyArray[index] = PoolManager.instance.getNode(enemy, this.node); - enemyArray[index].setScale(5, 5, 5); - enemyArray[index].getComponent(enemyPlane).show(this, this.enemy2Speed, false); - //if(index) - } - enemyArray[0].setPosition(-21, 0, -60); - enemyArray[1].setPosition(-14, 0, -55); - enemyArray[2].setPosition(-7, 0, -50); - enemyArray[3].setPosition(0, 0, -45); - enemyArray[4].setPosition(7, 0, -50); - enemyArray[5].setPosition(14, 0, -55); - enemyArray[6].setPosition(21, 0, -60); - - - - - - } - - - //敌机子弹,localPos为要生成的位置,localNode为敌机节点 - public enemy1Bullet(localPos: Vec3, localNode: Node) { - let enemyBullet = null; - enemyBullet = PoolManager.instance.getNode(this.bullet1, this.node); - - //console.log('localPso',localPos.z,localPos.x) - enemyBullet.parent = this.node; - if (localNode.name == "plane02") { enemyBullet.getComponent(bulletManager).show(this, this.enemy1Speed * 2); } //将gameManager传入的同时传入敌机的速度--为设置敌机子弹速度 - if (localNode.name == "plane03") { enemyBullet.getComponent(bulletManager).show(this, this.enemy2Speed * 2); } - enemyBullet.getComponent(bulletManager).setBulletGroup(false); - enemyBullet.getComponent(bulletManager).playerBullet = false; - enemyBullet.getComponent(bulletManager).enemyBullet = true; - enemyBullet.setPosition(localPos.x, localPos.y, localPos.z + 6.5); - enemyBullet.setScale(5, 5, 5); - - } - - //获得随机数 - public getRandomNum(min: number, max: number): number { - let range = max - min; - let rand = Math.random(); - return (min + Math.round(rand * range)); - } - - //移除子弹 - public onBulletKilled(bullet) { - //此处的bullet应该是一个node - PoolManager.instance.putNode(bullet); - } - - - - //移除敌机 - public onEnemyKilled(enemy) { - //敌机死亡后将敌机回收到池子中 - PoolManager.instance.putNode(enemy); - } - - //移除所有子弹 - public removeAllBullet() { - let children: Node[] = this.node.children; - for (let i: number = children.length - 1; i >= 0; i--) { - let scriptBullet: Component = children[i].getComponent(bulletManager); - if (scriptBullet) { - this.onBulletKilled(children[i]); - } - } - - } - - //移除所有敌机 - public removeAllEnemy() { - let children: Node[] = this.node.children; - for (let i: number = children.length - 1; i >= 0; i--) { - let scriptEnemy: Component = children[i].getComponent(enemyPlane); - if (scriptEnemy) { - PoolManager.instance.putNode(children[i]); - } - } - } - - //移除所有道具 - public removeAllItem() { - let children: Node[] = this.node.children; - for (let i: number = children.length - 1; i >= 0; i--) { - let scriptEnemy: Component = children[i].getComponent(FightIconBullet); - if (scriptEnemy) { - PoolManager.instance.putNode(children[i]); - } - } - } - - -} - - - +import { AudioManager } from './framework/audioManager'; + +import { _decorator, Component, Node, setDisplayStats, Prefab, instantiate, find, NodePool, Vec3, director, PhysicsSystem, game, Pool, Label, Socket, Quat, AudioSource, AudioClip } from 'cc'; +import { bulletManager } from './bullet/bulletManager'; +import { FightIconBullet } from './bullet/fightIconBullet'; +import { Constant } from './framework/constant'; +import { PoolManager } from './framework/poolManager'; +import { enemyPlane } from './plane/enemyPlane'; +import { selfPlane } from './plane/selfPlane'; +import { MovingSceneBg } from './ui/common/movingSceneBg'; + +const { ccclass, property } = _decorator; + + +let _temp_quat = new Quat; + + + +@ccclass('GameController') +export class GameController extends Component { + + @property(Node) + public playerPlane: Node = null; //玩家飞机节点 + @property(Prefab) + public bullet1: Prefab = null; //子弹类型1 + @property(Prefab) + public bullet2: Prefab = null; //子弹类型2 + @property(Prefab) + public bullet3: Prefab = null; //子弹类型3 + @property(Prefab) + public bullet4: Prefab = null; //子弹类型4 + @property(Prefab) + public bullet5: Prefab = null; //子弹类型5 + //道具图标预制物 + @property(Prefab) + public bulletIcon1: Prefab = null; //道具1 + @property(Prefab) + public bulletIcon2: Prefab = null; //道具2 + @property(Prefab) + public bulletIcon3: Prefab = null; //道具3 + //积分面板 + @property(Node) + public scorePanel: Node = null; + @property(Label) + public jifen: Label = null; //分数 + @property(Label) + public gameOverScore = null; //结束的分数界面 + //背景地图 + @property(Node) + public bgMap: Node = null; + //敌机的声明 + @property(Prefab) + public enemy1: Prefab = null; + @property(Prefab) + public enemy2: Prefab = null; + @property(Node) + public gameOverUi: Node = null; //结束界面ui + @property(Node) + public gameStartUi: Node = null; //开始界面ui + @property(Node) + public cocosUi: Node = null; //cocos图标 + @property(Node) + public ball: Node = null; //背景星球 + @property + public bulletSpeedTime: number = 12; //子弹射击间隔时间 + @property + public enemyTime: number = 60; //敌机生成时间 + + //bgm + @property(AudioSource) + public audio: AudioSource = null!; + //按钮点击音效 + @property(AudioSource) + public buttonAudio: AudioSource = null!; + + //道具掉落时间 + @property + public dropTime: number = 600; //现在是10s + + //敌机速度,在此处更改 + @property + public enemy1Speed: number = 0.5; //敌机1的速度 + @property + public enemy2Speed: number = 0.7; //敌机2的速度 + + //星球和标志移动速度 + @property + public cocosSpeed: number = 0.1; + //子弹速度 + @property + public bulletSpeed: number = 1; + //分数 + public score: number = 0; + //玩家飞机是否可以射击,操作开关在uiManin.ts中, + public shooting: boolean = false; + //游戏是否开始,操作开关在uiManin.ts中, + public starting: boolean = false; + + public selfPlaneIsDie: boolean = false; //判断玩家飞机是否死亡 + + public isWhichBullet: number; //判断是哪种子弹 + public conbinationInterval: number //组合间隔 + public timing: boolean = true; + private shootTime: number = 0; + private _enemyTime: number; //创建敌机的间隔时间 + private _combinationTime: number; //组合出现间隔时间 + + private _iconTime: number = 0; + private _cocosSpeed: number = this.cocosSpeed; //标志移动 + private _ballSpeed: number = this.cocosSpeed; //星球移动 + + + onLoad() { + //开启碰撞检测 + PhysicsSystem.instance.enable = true; + setDisplayStats(false); //关闭左下角的调试信息 + this.isWhichBullet = Constant.FIGHT_BULLET_GROUP.BULLET_M //一开始默认用m号子弹 + this.shootTime = 0; + this._enemyTime = 0; + this._combinationTime = 0; + this.conbinationInterval = 1 + this._iconTime = 0; + this.playerPlane.getComponent(selfPlane).show(this); + //开始时候分数置0 + this.score = 0; + this.timing = true; + + + + } + + update(deltaTime: number) { + + if(!this.audio.getComponent(AudioSource).playing) { + this.audio.getComponent(AudioSource).play(); + } + + //实时显示分数 + this.jifen.string = this.score.toString(); + this.gameOverScore.string = this.score.toString(); + if (!this.selfPlaneIsDie) { + //当玩家没有死亡的时候执行的代码 + //背景星球和标志移动 + if (this.cocosUi.position.x >= 18) { this._cocosSpeed = -this.cocosSpeed } + else if (this.cocosUi.position.x <= -18) { this._cocosSpeed = this.cocosSpeed } + this.cocosUi.setPosition(this.cocosUi.position.x + this._cocosSpeed, this.cocosUi.position.y, this.cocosUi.position.z); + + if (this.ball.position.x >= 18) { this._ballSpeed = -this.cocosSpeed } + else if (this.ball.position.x <= -18) { this._ballSpeed = this.cocosSpeed } + this.ball.setPosition(this.ball.position.x + this._ballSpeed, this.ball.position.y, this.ball.position.z); + + let rad = 1 * Math.PI / 180; + this.ball.getRotation(_temp_quat); + Quat.rotateZ(_temp_quat, _temp_quat, rad); + this.ball.setRotation(_temp_quat); + + //子弹射击,一开始子弹的类型为m,黄色单列 + this.shootTime++; + if (this.shooting && this.shootTime >= this.bulletSpeedTime) { + console.log(this.isWhichBullet, '子弹类型') + if (this.isWhichBullet == Constant.FIGHT_BULLET_GROUP.BULLET_M) { + //发射m型号的子弹 + this.creatorBullet1(this.bullet1); + } + else if (this.isWhichBullet == Constant.FIGHT_BULLET_GROUP.BULLET_S) { + //发射S型号的子弹 + this.creatorBullet2(this.bullet2); + } + else if (this.isWhichBullet == Constant.FIGHT_BULLET_GROUP.BULLET_H) { + //发射H型号的子弹 + this.creatorBullet3(this.bullet3); + } + this.shootTime = 0; + } + + //游戏每隔10随机出现一个道具 + if (this.starting) { + this._iconTime++; + if (this._iconTime >= this.dropTime) { + this._iconTime = 0; + let iconValue = this.getRandomNum(1, 3); + if (iconValue == 1) { this.creatorFightIcon(this.bulletIcon1); } + else if (iconValue == 2) { this.creatorFightIcon(this.bulletIcon2); } + else if (iconValue == 3) { this.creatorFightIcon(this.bulletIcon3); } + } + } + this._combinationTime++; + if (this.conbinationInterval == Constant.COMBINATION.COMBINATE1) { + //敌机 这里的生成时间设置成60 + this._enemyTime++; + if (this.starting && this._enemyTime >= this.enemyTime) { + let whichEnemy: number = this.getRandomNum(1, 2); //随机取两个值,代表不同的两个敌机 + if (whichEnemy == Constant.COMBINATION.COMBINATE1) { + this.creatorEnemy1(); + this._enemyTime = 0; + } + else if (whichEnemy == Constant.COMBINATION.COMBINATE2) { + this.creatorEnemy2(); + this._enemyTime = 0; + } + + } + + } + + else if (this.conbinationInterval == Constant.COMBINATION.COMBINATE2) { + + //来到时间段2,敌机出现时间间隔为原来的0.8倍 + if (this.starting && this._combinationTime >= this.enemyTime * 3) { + let combinate: number = this.getRandomNum(1, 2); + if (combinate == Constant.COMBINATION.COMBINATE1) { + this.creatorCombination1(this.enemy1); + this._combinationTime = 0; + } + else if (combinate == Constant.COMBINATION.COMBINATE2) { + this.creatorEnemy2(); + this._combinationTime = 0; + } + } + } + else { + + //来到时间段2,敌机出现时间间隔为原来的3倍 + if (this.starting && this._combinationTime >= this.enemyTime * 2) { + let combinate: number = this.getRandomNum(1, 3); + if (combinate == Constant.COMBINATION.COMBINATE1) { + this.creatorCombination1(this.enemy1); + this._combinationTime = 0; + } + else if (combinate == Constant.COMBINATION.COMBINATE2) { + this.creatorCombination2(this.enemy2); + this._combinationTime = 0; + } + else if (combinate == Constant.COMBINATION.COMBINATE3) { + this.creatorEnemy1(); + this.creatorEnemy2(); + this._combinationTime = 0; + } + } + } + + + + } + if (this.selfPlaneIsDie) { + this.gameOver(); //玩家死亡后执行游戏结束函数 + } + } + + //开启一个计时器,随时间改变游戏难度 + public glodeDifficulty() { + let callback = () => { + if (this.selfPlaneIsDie) { + this.unschedule(callback); + } + this.conbinationInterval++; + } + + this.schedule(callback, 10); + + } + + //游戏结束 + public gameOver() { + this.bgMap.getComponent(MovingSceneBg).bgSpeed = 0; //背景停止移动 + this.removeAllBullet(); //移除所有子弹 + this.conbinationInterval = 1;//组合变回1 + this.scorePanel.active = false; + } + + //游戏重新开始 + public gameRestart() { + this.buttonAudio.getComponent(AudioSource).play(); + this.bgMap.getComponent(MovingSceneBg).bgSpeed = 10; + this.dataReSet(); + + + } + + //游戏返回到主界面 + public gameMain() { + this.buttonAudio.getComponent(AudioSource).play(); + this.bgMap.getComponent(MovingSceneBg).bgSpeed = 0; + this.dataReSet(); + + this.starting = false; + this.gameStartUi.active = true; + + this.scorePanel.active = false; + + + } + + public dataReSet() { + this.removeAllEnemy(); + this.removeAllItem(); + this.selfPlaneIsDie = false; + this.playerPlane.getComponent(selfPlane).dieEffect.active = false; + this.playerPlane.getComponent(selfPlane).init(); + this.playerPlane.getComponent(selfPlane).lifeBloodBg.active = false; + this.playerPlane.getComponent(selfPlane).lifeBlood.active = false; + this.gameOverUi.active = false; + this.isWhichBullet = Constant.FIGHT_BULLET_GROUP.BULLET_M; + this.score = 0; + this.timing = true; + this.shooting = false; + this.playerPlane.setPosition(0, 0, 15); + } + + //创建道具 + public creatorFightIcon(prefebIcon: Prefab) { + let bulletIcon = null; + bulletIcon = PoolManager.instance.getNode(prefebIcon, this.node); + bulletIcon.parent = this.node; + bulletIcon.setScale(1.5, 1, 0.8); + bulletIcon.setPosition(0, 0, -50); + bulletIcon.getComponent(FightIconBullet).show(this); + + } + //移除道具 + public fightIconKill(prefebIcon) { + PoolManager.instance.putNode(prefebIcon); + //console.log('道具被销毁'); + } + + //创建我方飞机子弹对象1 + public creatorBullet1(prefebBullet: Prefab) { + let bullet = null; + + bullet = PoolManager.instance.getNode(prefebBullet, this.node); + //bullet.parent = this.node; + let pos: Vec3 = this.playerPlane.getPosition(); + //将子弹大小设置为于飞机同样大小 + bullet.setScale(8, 8, 8); + //将子弹位置设置在飞机前方 + bullet.setPosition(pos.x, pos.y, pos.z - this.playerPlane.getScale().z); + //console.log(bullet.getPosition()) + //将gameManger传入脚本bulletManager中 + bullet.getComponent(bulletManager).show(this, this.bulletSpeed); + bullet.getComponent(bulletManager).setBulletGroup(true); + bullet.getComponent(bulletManager).playerBullet = true; + bullet.getComponent(bulletManager).enemyBullet = false; + bullet.getComponent(bulletManager).bulletType = Constant.BULLET_DIRECTION.CENTRAL; + + } + //创建我放飞机子弹对象2 + public creatorBullet2(prefebBullet: Prefab) { + let bullet1 = null; + let bullet2 = null; + bullet1 = PoolManager.instance.getNode(prefebBullet, this.node); + bullet2 = PoolManager.instance.getNode(prefebBullet, this.node); + + let pos: Vec3 = this.playerPlane.getPosition(); + //将子弹大小设置为于飞机同样大小 + bullet1.setScale(8, 8, 8); + bullet2.setScale(8, 8, 8); + + //将子弹位置设置在飞机前方,该子弹位置应该放在飞机前方5,两边相差5 + bullet1.setPosition(pos.x + 2.5, pos.y, pos.z - 5); + bullet2.setPosition(pos.x - 2.5, pos.y, pos.z - 5); + + //console.log(bullet.getPosition()) + //将gameManger传入脚本bulletManager中 + bullet1.getComponent(bulletManager).show(this, this.bulletSpeed); + bullet2.getComponent(bulletManager).show(this, this.bulletSpeed); + bullet1.getComponent(bulletManager).setBulletGroup(true); + bullet2.getComponent(bulletManager).setBulletGroup(true); + bullet1.getComponent(bulletManager).playerBullet = true; + bullet2.getComponent(bulletManager).playerBullet = true; + bullet1.getComponent(bulletManager).enemyBullet = false; + bullet2.getComponent(bulletManager).enemyBullet = false; + bullet1.getComponent(bulletManager).bulletType = Constant.BULLET_DIRECTION.CENTRAL; + bullet2.getComponent(bulletManager).bulletType = Constant.BULLET_DIRECTION.CENTRAL; + } + + //创建我放飞机子弹对象3 + public creatorBullet3(prefebBullet: Prefab) { + let bullet1 = null; + let bullet2 = null; + let bullet3 = null; + bullet1 = PoolManager.instance.getNode(prefebBullet, this.node); + bullet2 = PoolManager.instance.getNode(prefebBullet, this.node); + bullet3 = PoolManager.instance.getNode(prefebBullet, this.node); + + let pos: Vec3 = this.playerPlane.getPosition(); + //将子弹大小设置为于飞机同样大小 + bullet1.setScale(8, 8, 8); + bullet2.setScale(8, 8, 8); + bullet3.setScale(8, 8, 8); + + //将子弹位置设置在飞机前方,该子弹位置应该放在飞机前方5,两边相差5 + bullet1.setPosition(pos.x + 2.5, pos.y, pos.z - 4); + bullet2.setPosition(pos.x - 2.5, pos.y, pos.z - 4); + bullet3.setPosition(pos.x, pos.y, pos.z - 8); + + //console.log(bullet.getPosition()) + //将gameManger传入脚本bulletManager中 + bullet1.getComponent(bulletManager).show(this, this.bulletSpeed); + bullet2.getComponent(bulletManager).show(this, this.bulletSpeed); + bullet3.getComponent(bulletManager).show(this, this.bulletSpeed); + bullet1.getComponent(bulletManager).setBulletGroup(true); + bullet2.getComponent(bulletManager).setBulletGroup(true); + bullet3.getComponent(bulletManager).setBulletGroup(true); + + bullet1.getComponent(bulletManager).playerBullet = true; + bullet2.getComponent(bulletManager).playerBullet = true; + bullet3.getComponent(bulletManager).playerBullet = true; + + bullet1.getComponent(bulletManager).enemyBullet = false; + bullet2.getComponent(bulletManager).enemyBullet = false; + bullet3.getComponent(bulletManager).enemyBullet = false; + + bullet1.getComponent(bulletManager).bulletType = Constant.BULLET_DIRECTION.RIGHT; + bullet2.getComponent(bulletManager).bulletType = Constant.BULLET_DIRECTION.LEFT; + bullet3.getComponent(bulletManager).bulletType = Constant.BULLET_DIRECTION.CENTRAL; + } + //创建敌机1对象 + public creatorEnemy1() { + let enemy = null; + enemy = PoolManager.instance.getNode(this.enemy1, this.node); + //将敌机1大小设置为5 + enemy.setScale(5, 5, 5); + //将敌机位置设置在屏幕最上方,位置为-60的位置 + enemy.getComponent(enemyPlane).show(this, this.enemy1Speed, true); + + //随机敌机在屏幕的x轴位置 + let enemyPos_x = this.getRandomNum(-20, 20); + enemy.setPosition(enemyPos_x, 0, -50); + + } + + //创建敌机2对象 + public creatorEnemy2() { + let enemy = null; + enemy = PoolManager.instance.getNode(this.enemy2, this.node); + //将敌机1大小设置为5 + enemy.setScale(5, 5, 5); + //将敌机位置设置在屏幕最上方,位置为-50的位置 + enemy.getComponent(enemyPlane).show(this, this.enemy2Speed, true); + + //随机敌机在屏幕的x轴位置 + let enemyPos_x = this.getRandomNum(-20, 20); + enemy.setPosition(enemyPos_x, 0, -50); + } + + //创建组合1,该组合为一字型 + public creatorCombination1(enemy: Prefab) { + let enemyArray = new Array(5); + + for (let index = 0; index < enemyArray.length; index++) { + enemyArray[index] = PoolManager.instance.getNode(enemy, this.node); + enemyArray[index].setScale(5, 5, 5); + enemyArray[index].getComponent(enemyPlane).show(this, this.enemy2Speed, false); + enemyArray[index].setPosition(-20 + index * 10, 0, -50) //位置放在-50处,在屏幕的上方出现 + } + + + + } + + //创建组合2,该组合为人字型 + public creatorCombination2(enemy: Prefab) { + let enemyArray = new Array(7); + for (let index = 0; index < enemyArray.length; index++) { + enemyArray[index] = PoolManager.instance.getNode(enemy, this.node); + enemyArray[index].setScale(5, 5, 5); + enemyArray[index].getComponent(enemyPlane).show(this, this.enemy2Speed, false); + //if(index) + } + enemyArray[0].setPosition(-21, 0, -60); + enemyArray[1].setPosition(-14, 0, -55); + enemyArray[2].setPosition(-7, 0, -50); + enemyArray[3].setPosition(0, 0, -45); + enemyArray[4].setPosition(7, 0, -50); + enemyArray[5].setPosition(14, 0, -55); + enemyArray[6].setPosition(21, 0, -60); + + + + + + } + + + //敌机子弹,localPos为要生成的位置,localNode为敌机节点 + public enemy1Bullet(localPos: Vec3, localNode: Node) { + let enemyBullet = null; + enemyBullet = PoolManager.instance.getNode(this.bullet1, this.node); + + //console.log('localPso',localPos.z,localPos.x) + enemyBullet.parent = this.node; + if (localNode.name == "plane02") { enemyBullet.getComponent(bulletManager).show(this, this.enemy1Speed * 2); } //将gameManager传入的同时传入敌机的速度--为设置敌机子弹速度 + if (localNode.name == "plane03") { enemyBullet.getComponent(bulletManager).show(this, this.enemy2Speed * 2); } + enemyBullet.getComponent(bulletManager).setBulletGroup(false); + enemyBullet.getComponent(bulletManager).playerBullet = false; + enemyBullet.getComponent(bulletManager).enemyBullet = true; + enemyBullet.setPosition(localPos.x, localPos.y, localPos.z + 6.5); + enemyBullet.setScale(5, 5, 5); + + } + + //获得随机数 + public getRandomNum(min: number, max: number): number { + let range = max - min; + let rand = Math.random(); + return (min + Math.round(rand * range)); + } + + //移除子弹 + public onBulletKilled(bullet) { + //此处的bullet应该是一个node + PoolManager.instance.putNode(bullet); + } + + + + //移除敌机 + public onEnemyKilled(enemy) { + //敌机死亡后将敌机回收到池子中 + PoolManager.instance.putNode(enemy); + } + + //移除所有子弹 + public removeAllBullet() { + let children: Node[] = this.node.children; + for (let i: number = children.length - 1; i >= 0; i--) { + let scriptBullet: Component = children[i].getComponent(bulletManager); + if (scriptBullet) { + this.onBulletKilled(children[i]); + } + } + + } + + //移除所有敌机 + public removeAllEnemy() { + let children: Node[] = this.node.children; + for (let i: number = children.length - 1; i >= 0; i--) { + let scriptEnemy: Component = children[i].getComponent(enemyPlane); + if (scriptEnemy) { + PoolManager.instance.putNode(children[i]); + } + } + } + + //移除所有道具 + public removeAllItem() { + let children: Node[] = this.node.children; + for (let i: number = children.length - 1; i >= 0; i--) { + let scriptEnemy: Component = children[i].getComponent(FightIconBullet); + if (scriptEnemy) { + PoolManager.instance.putNode(children[i]); + } + } + } + + +} + + + diff --git a/examples/cocos-creator-airplane/frontend/assets/script/gameManager.ts.meta b/examples/cocos-creator-airplane/frontend/assets/script/GameController.ts.meta similarity index 100% rename from examples/cocos-creator-airplane/frontend/assets/script/gameManager.ts.meta rename to examples/cocos-creator-airplane/frontend/assets/script/GameController.ts.meta diff --git a/examples/cocos-creator-airplane/frontend/assets/script/GameStateManager.ts b/examples/cocos-creator-airplane/frontend/assets/script/GameStateManager.ts new file mode 100644 index 0000000..2ee72d1 --- /dev/null +++ b/examples/cocos-creator-airplane/frontend/assets/script/GameStateManager.ts @@ -0,0 +1,187 @@ +import { WsClient } from "tsrpc-browser"; +import { GameSystem } from "../scripts/shared/game/GameSystem"; +import { GameSystemState } from "../scripts/shared/game/GameSystemState"; +import { ClientInput, MsgGameInput } from "../scripts/shared/protocols/game/client/MsgGameInput"; +import { MsgGameStart } from "../scripts/shared/protocols/game/server/MsgGameStart"; +import { MsgServerFrame } from "../scripts/shared/protocols/game/server/MsgServerFrame"; +import { serviceProto, ServiceType } from "../scripts/shared/protocols/serviceProto"; +import { CurrentUser } from "../scripts/shared/types/CurrentUser"; +import { RoomState } from "../scripts/shared/types/RoomState"; + +/** + * 前端游戏状态管理 + * 主要用于实现前端的预测和和解 + */ +export class GameStateManager { + + client: WsClient; + + roomState: RoomState; + gameSystem!: GameSystem; + serverState!: GameSystemState; + lastSN = 0; + + get state() { + return this.gameSystem.state; + } + + currentUser?: CurrentUser; + constructor() { + let client = this.client = new WsClient(serviceProto, { + server: `ws://${location.hostname}:3000`, + json: true, + // logger: console + }); + + client.listenMsg('game/server/ServerFrame', msg => { this._onServerFrame(msg) }); + client.listenMsg('game/server/GameStart', msg => { + this._startGame(msg); + }); + client.listenMsg('room/server/UpdateRoomState', msg => { + this.roomState = msg.state; + }) + + // 模拟网络延迟 可通过 URL 参数 ?lag=200 设置延迟 + let networkLag = parseInt(new URLSearchParams(location.search).get('lag') || '0') || 0; + if (networkLag) { + client.flows.preRecvDataFlow.push(async v => { + await new Promise(rs => { setTimeout(rs, networkLag) }) + return v; + }); + client.flows.preSendDataFlow.push(async v => { + await new Promise(rs => { setTimeout(rs, networkLag) }) + return v; + }); + } + + (window as any).gm = this; + } + + private _promiseEnsureConnected?: Promise; + async ensureConnected() { + if (!this._promiseEnsureConnected) { + this._promiseEnsureConnected = this._doEnsureConnected().then(() => { + this._promiseEnsureConnected = undefined; + }); + } + return this._promiseEnsureConnected; + } + private async _doEnsureConnected() { + if (!this.client.isConnected) { + let resConnect = await this.client.connect(); + if (!resConnect.isSucc) { + await new Promise(rs => { setTimeout(rs, 2000) }) + return this._doEnsureConnected(); + } + } + } + + async login(): Promise { + if (this.currentUser) { + return true; + } + + let nickname: string; + while (!nickname) { + nickname = prompt('给自己取个名字:', ''); + } + + await this.ensureConnected(); + + let ret = await this.client.callApi('Login', { nickname: nickname }); + if (!ret.isSucc) { + alert(ret.err.message); + return false; + } + + this.currentUser = ret.res.currentUser; + return true; + } + + async join(): Promise { + await this.ensureConnected(); + let ret = await this.client.callApi('room/JoinRoom', { roomId: 123 }); + + if (!ret.isSucc) { + if (confirm(`加入房间失败\n${ret.err.message}\n是否重试 ?`)) { + return this.join(); + } + else { + return; + } + } + + this.roomState = ret.res.roomState; + } + + private _startGame(msg: MsgGameStart) { + this.gameSystem = new GameSystem(msg.gameState); + this.serverState = Object.merge({}, msg.gameState); + this._lastLocalTime = Date.now(); + } + + private _onServerFrame(frame: MsgServerFrame) { + if (!this.gameSystem) { + return; + } + + // 回滚至上一次的权威状态 + this.gameSystem.state = Object.merge({}, this.serverState); + // 计算最新的权威状态 + for (let input of frame.inputs) { + this.gameSystem.applyInput(input); + } + this.serverState = Object.merge({}, this.gameSystem.state); + this._lastLocalTime = Date.now(); + + // 和解 = 权威状态 + 本地输入 (最新的本地预测状态) + let lastSn = frame.lastSn ?? -1; + this.pendingInputMsgs.remove(v => v.sn <= lastSn); + this.pendingInputMsgs.forEach(m => { + m.inputs.forEach(v => { + this.gameSystem.applyInput({ + ...v, + playerId: this.currentUser.id + }); + }) + }) + } + + pendingInputMsgs: MsgGameInput[] = []; + sendClientInput(input: ClientInput) { + // 已掉线或暂未加入,忽略本地输入 + if (!this.currentUser || !this.client.isConnected) { + return; + } + + // 构造消息 + let msg: MsgGameInput = { + sn: ++this.lastSN, + inputs: [input] + } + + // 向服务端发送输入 + this.pendingInputMsgs.push(msg); + this.client.sendMsg('game/client/GameInput', msg); + + // 预测状态:本地立即应用输入 + this.predictTimePast(); + this.gameSystem.applyInput({ + ...input, + playerId: this.currentUser.id + }); + } + + // 本地预测时间流逝(但不提交,会以下一次服务器同步为准) + private _lastLocalTime!: number; + predictTimePast() { + const now = Date.now(); + let dt = now - this._lastLocalTime; + this.gameSystem.applyInput({ + type: 'TimePast', + dt: dt + }); + this._lastLocalTime = now; + } + +} \ No newline at end of file diff --git a/examples/cocos-creator-airplane/frontend/assets/script/StateManager.ts b/examples/cocos-creator-airplane/frontend/assets/script/StateManager.ts deleted file mode 100644 index 881918e..0000000 --- a/examples/cocos-creator-airplane/frontend/assets/script/StateManager.ts +++ /dev/null @@ -1,133 +0,0 @@ -import { WsClient } from "tsrpc-browser"; -import { GameSystem, GameSystemState } from "../shared/game/GameSystem"; -import { ClientInput, MsgClientInput } from "../shared/protocols/client/MsgClientInput"; -import { MsgFrame } from "../shared/protocols/server/MsgFrame"; -import { serviceProto, ServiceType } from "../shared/protocols/serviceProto"; - -/** - * 前端游戏状态管理 - * 主要用于实现前端的预测和和解 - */ -export class StateManager { - - client: WsClient; - - gameSystem = new GameSystem(); - - lastServerState: GameSystemState = this.gameSystem.state; - lastRecvSetverStateTime = 0; - selfPlayerId: number = -1; - lastSN = 0; - - get state() { - return this.gameSystem.state; - } - - constructor() { - let client = this.client = new WsClient(serviceProto, { - server: `ws://${location.hostname}:3000`, - json: true, - // logger: console - });; - client.listenMsg('server/Frame', msg => { this._onServerSync(msg) }); - - // 模拟网络延迟 可通过 URL 参数 ?lag=200 设置延迟 - let networkLag = parseInt(new URLSearchParams(location.search).get('lag') || '0') || 0; - if (networkLag) { - client.flows.preRecvDataFlow.push(async v => { - await new Promise(rs => { setTimeout(rs, networkLag) }) - return v; - }); - client.flows.preSendDataFlow.push(async v => { - await new Promise(rs => { setTimeout(rs, networkLag) }) - return v; - }); - } - - (window as any).gm = this; - } - - async join(): Promise { - if (!this.client.isConnected) { - let resConnect = await this.client.connect(); - if (!resConnect.isSucc) { - await new Promise(rs => { setTimeout(rs, 2000) }) - return this.join(); - } - } - - let ret = await this.client.callApi('Join', {}); - - if (!ret.isSucc) { - if (confirm(`加入房间失败\n${ret.err.message}\n是否重试 ?`)) { - return this.join(); - } - else { - return; - } - } - - this.gameSystem.reset(ret.res.gameState); - this.lastServerState = Object.merge(ret.res.gameState); - this.lastRecvSetverStateTime = Date.now(); - this.selfPlayerId = ret.res.playerId; - } - - private _onServerSync(frame: MsgFrame) { - // 回滚至上一次的权威状态 - this.gameSystem.reset(this.lastServerState); - - // 计算最新的权威状态 - for (let input of frame.inputs) { - this.gameSystem.applyInput(input); - } - this.lastServerState = Object.merge({}, this.gameSystem.state); - this.lastRecvSetverStateTime = Date.now(); - - // 和解 = 权威状态 + 本地输入 (最新的本地预测状态) - let lastSn = frame.lastSn ?? -1; - this.pendingInputMsgs.remove(v => v.sn <= lastSn); - this.pendingInputMsgs.forEach(m => { - m.inputs.forEach(v => { - this.gameSystem.applyInput({ - ...v, - playerId: this.selfPlayerId - }); - }) - }) - } - - pendingInputMsgs: MsgClientInput[] = []; - sendClientInput(input: ClientInput) { - // 已掉线或暂未加入,忽略本地输入 - if (!this.selfPlayerId || !this.client.isConnected) { - return; - } - - // 构造消息 - let msg: MsgClientInput = { - sn: ++this.lastSN, - inputs: [input] - } - - // 向服务端发送输入 - this.pendingInputMsgs.push(msg); - this.client.sendMsg('client/ClientInput', msg); - - // 预测状态:本地立即应用输入 - this.gameSystem.applyInput({ - ...input, - playerId: this.selfPlayerId - }); - } - - // 本地时间流逝(会被下一次服务器状态覆盖) - localTimePast() { - this.gameSystem.applyInput({ - type: 'TimePast', - dt: Date.now() - this.lastRecvSetverStateTime - }); - this.lastRecvSetverStateTime = Date.now(); - } - -} \ No newline at end of file diff --git a/examples/cocos-creator-airplane/frontend/assets/script/bullet/bulletManager.ts b/examples/cocos-creator-airplane/frontend/assets/script/bullet/bulletManager.ts index 9221148..c0d8cf5 100644 --- a/examples/cocos-creator-airplane/frontend/assets/script/bullet/bulletManager.ts +++ b/examples/cocos-creator-airplane/frontend/assets/script/bullet/bulletManager.ts @@ -1,7 +1,7 @@ import { _decorator, Component, Node, Collider, find, ITriggerEvent, Script } from 'cc'; import { Constant } from '../framework/constant'; -import { GameManager } from '../gameManager'; +import { GameManager } from '../GameController'; const { ccclass, property } = _decorator; diff --git a/examples/cocos-creator-airplane/frontend/assets/script/bullet/fightIconBullet.ts b/examples/cocos-creator-airplane/frontend/assets/script/bullet/fightIconBullet.ts index cc5b787..39c8890 100644 --- a/examples/cocos-creator-airplane/frontend/assets/script/bullet/fightIconBullet.ts +++ b/examples/cocos-creator-airplane/frontend/assets/script/bullet/fightIconBullet.ts @@ -1,7 +1,7 @@ import { _decorator, Component, Node, Collider, ITriggerEvent } from 'cc'; import { Constant } from '../framework/constant'; -import { GameManager } from '../gameManager'; +import { GameManager } from '../GameController'; const { ccclass, property } = _decorator; diff --git a/examples/cocos-creator-airplane/frontend/assets/script/plane/enemyPlane.ts b/examples/cocos-creator-airplane/frontend/assets/script/plane/enemyPlane.ts index edac60e..05585c2 100644 --- a/examples/cocos-creator-airplane/frontend/assets/script/plane/enemyPlane.ts +++ b/examples/cocos-creator-airplane/frontend/assets/script/plane/enemyPlane.ts @@ -2,7 +2,7 @@ import { _decorator, Component, Node, Collider, ITriggerEvent, physics, PhysicsSystem, find, Game, Prefab, NodePool, instantiate, Vec2, Vec3, AudioSource } from 'cc'; import { bulletManager } from '../bullet/bulletManager'; import { Constant } from '../framework/constant'; -import { GameManager } from '../gameManager'; +import { GameManager } from '../GameController'; const { ccclass, property } = _decorator; diff --git a/examples/cocos-creator-airplane/frontend/assets/script/plane/selfPlane.ts b/examples/cocos-creator-airplane/frontend/assets/script/plane/selfPlane.ts index ed3aeb9..e4b29e0 100644 --- a/examples/cocos-creator-airplane/frontend/assets/script/plane/selfPlane.ts +++ b/examples/cocos-creator-airplane/frontend/assets/script/plane/selfPlane.ts @@ -1,7 +1,7 @@ import { _decorator, Component, Node, Collider, ITriggerEvent } from 'cc'; import { Constant } from '../framework/constant'; -import { GameManager } from '../gameManager'; +import { GameManager } from '../GameController'; const { ccclass, property } = _decorator; diff --git a/examples/cocos-creator-airplane/frontend/assets/script/ui/uiMain.ts b/examples/cocos-creator-airplane/frontend/assets/script/ui/uiMain.ts index 16cde19..46119fb 100644 --- a/examples/cocos-creator-airplane/frontend/assets/script/ui/uiMain.ts +++ b/examples/cocos-creator-airplane/frontend/assets/script/ui/uiMain.ts @@ -1,6 +1,6 @@ import { _decorator, Component, Node, UITransform, Vec2, Vec3, find, Script, game, Label, CameraComponent, Camera, EventTouch, v3 } from 'cc'; -import { GameManager } from '../gameManager'; +import { GameManager } from '../GameController'; import { MovingSceneBg } from './common/movingSceneBg'; import { Tips } from './common/tips'; diff --git a/examples/cocos-creator-airplane/frontend/package.json b/examples/cocos-creator-airplane/frontend/package.json index bc4a62b..1308f7b 100755 --- a/examples/cocos-creator-airplane/frontend/package.json +++ b/examples/cocos-creator-airplane/frontend/package.json @@ -7,6 +7,10 @@ "uuid": "c794458c-05f6-4c9f-909b-20d54897d219", "version": "3.4.0", "dependencies": { + "seedrandom": "^3.0.5", "tsrpc-browser": "^3.1.4" + }, + "devDependencies": { + "@types/seedrandom": "^3.0.1" } } diff --git a/examples/cocos-creator-airplane/frontend/tsconfig.json b/examples/cocos-creator-airplane/frontend/tsconfig.json index 7dc649a..f94a2af 100644 --- a/examples/cocos-creator-airplane/frontend/tsconfig.json +++ b/examples/cocos-creator-airplane/frontend/tsconfig.json @@ -1,9 +1,9 @@ { /* Base configuration. Do not edit this field. */ "extends": "./temp/tsconfig.cocos.json", - /* Add your custom configuration here. */ "compilerOptions": { - "strict": false + "strict": false, + "allowSyntheticDefaultImports": true } -} +} \ No newline at end of file