import Bot from "../../Game/Bot"; import PIFS from "../../PIFS"; import MatchView from "../../Views/MatchView"; import { JCMGO } from "../Core/JCMGO"; /** * 游戏逻辑系统(游戏逻辑和显示分离) */ export default class GameSystem { public masterId: number = -1; public playerInfos: Map; public boys: BoyEntity[] = []; public countDown: number = 120 * 1000; public isGameStart: boolean = false; public isGameOver: boolean = false; public onRoomAddPlayer(e: JCMGO.RoomAddPlayerBst) { if (e.isSelf) { this.masterId = e.playerIndex; console.log("i join room, playerIndex:", e.playerIndex); } else { console.log("other join room, playerIndex:", e.playerIndex); } } public onRoomRemovePlayer(e: JCMGO.RoomRemovePlayerBst) { if (e.isSelf) { console.log("i leave room, playerIndex:", e.playerIndex); return; } console.log("other leave room, playerIndex:", e.playerIndex); let playerId = e.playerIndex; this.playerInfos[playerId] = null; //如果我现在是机器人支持者,将对(离开的玩家角色,机器人角色)检测并添加机器人脚本 if (this.isGameStart && this.isBotSupporter()) { window.gm.boys.forEach(boy => { if (!this.playerInfos[boy.index]) { if (!boy.getComponent(Bot)) boy.addComponent(Bot); } }); } } public completeMatching(e: JCMGO.RoomEndMatchingBst) { this.playerInfos = e.roomInfo.playerInfos; PIFS.setMatchPlayerInfos(e.roomInfo.playerInfos, e.timestamp); MatchView.handleMatchSuccess(); } public startGame() { this.isGameStart = true; this._createBoys(); window.gm.createBoys(); if (MatchView.Instance) MatchView.Instance.close(); cc.find("Canvas/BgMusic").getComponent(cc.AudioSource).enabled = true; } public handleFrame(frame: JCMGO.Frame) { if (frame.inputs instanceof Array) { for (let input of frame.inputs as any[]) { if (input.t === 1) { this._handleBoyState(input); continue; } if (input.t === 2) { this._handleBoyBeKilled(input); continue; } } } this._handleTimePass(frame.dt); } /**帧同步处理-角色状态 */ private _handleBoyState(input) { let id = input.id; let boy = this.boys.find(boy => boy.id === id); if (boy) { boy.position = cc.v2(parseFloat(input.x), parseFloat(input.y)); boy.angle = parseFloat(input.a); boy.scaleX = parseFloat(input.sx); } } /**帧同步处理-角色被杀 */ private _handleBoyBeKilled(input) { let id = input.id; let killerId = input.ki; let deadPosition = cc.v2(parseFloat(input.x), parseFloat(input.y)); let boy = this.boys.find(boy => boy.id === id); if (killerId === 100 && !boy.dead) { //被大锯子杀死 boy.dead = true; boy.deadPosition = deadPosition; if (this._isOnlyOneAlive()) this._setGameOver(); } else { //被其他角色杀死 let killer = this.boys.find(boy => boy.id === killerId); if (!killer.dead && !boy.dead) { boy.dead = true; boy.deadPosition = deadPosition; if (this._isOnlyOneAlive()) this._setGameOver(); } } } /**帧同步处理-时间流逝 */ private _handleTimePass(dt: number) { if (this.isGameOver) return; this.countDown -= dt; if (this.countDown <= 0) { this.countDown = 0; this._setGameOver(); } } /**我是不是机器人支持者 */ public isBotSupporter() { for (let i = 0; i < this.masterId; i++) { if (this.playerInfos[i]) return false; } //房间内没有id比我小的玩家时,我才会成为机器人支持者 return true; } /**创建游戏角色 */ private _createBoys() { for (let i = 0; i < 4; i++) { let boy = new BoyEntity(); boy.id = i; let box = window.gcr.boxs[i]; boy.position = box.position.add(cc.v2(0, box.height/2+10)); boy.angle = 0; boy.scaleX = 1.8; boy.dead = false; this.boys.push(boy); } } /**是不是只有一个人活着 */ private _isOnlyOneAlive() { let aliveCount = 0; this.boys.forEach(boy => { if (!boy.dead) aliveCount++; }); return aliveCount === 1; } /**设置游戏结束 */ private _setGameOver() { if (this.isGameOver) return; this.isGameOver = true; window.gm.gameOver(this.boys.find(v => !v.dead).id); } } class BoyEntity { id: number; position: cc.Vec2; angle: number; scaleX: number; dead: boolean; deadPosition: cc.Vec2; }