服務端的請求流程走完了一遍,下面就該看一下,在目前的服務端中,各服務端所提供的功能了。session
Gate:game-server/app/servers/gate/handler/gateHandler.jsapp
queryEntry(msg,session,next):註冊服務端,返回分配的connector服務端地址
Connector:game-server/app/servers/connector/handler/entryHandler.jssocket
entry(msg, session, next):服務端註冊session信息 返回玩家playerId
onUserLeave(app, session, reason):用戶離開或關閉連接
Area:game-server/app/servers/area/handler/playerHandler.jside
enterScene(msg, session, next):玩家申請加入遊戲場景
getAnimation(msg, session, next):獲取玩家動畫數據
changeStage(msg, session, next):更改玩家狀態
move(msg, session, next):玩家移動
這裏還涉及到一個玩家離開場景事的調用game-server/app/servers/area/remote/playerRemote.js函數
目前服務端的使用已經很清晰了,要開始摒棄示例,能夠開始本身的遊戲邏輯了。第一步要作的,就是藉助pomelo的撿寶項目,讓多個玩家站在同一個場景中並顯示。學習
整理egret代碼動畫
根據當前的服務端結構,建立服務器信息管理類network.Servers
module network { /** * 服務端信息 */ export class Servers { public constructor() { } /** * 服務端事件 * currServerDisConnect:當前服務端關閉 */ public static events = { currServerDisConnect: "DISCONNECT_SUCCEED" } /** * Gate模塊 */ public static GATE = { KEY: "Server_GATE", info: { ip: "", port: "" }, handler: { queryEntry: "gate.gateHandler.queryEntry" }, events: { succeed: "CONNECTION_GATE_SUCCEED", error: "CONNECTION_GATE_ERROR" } }; /** * Connect 模塊操做 */ public static CONNECTION = { KEY: "Server_CONNECTION", info: { ip: "", port: "" }, handler: { entry: "connector.entryHandler.entry", onUserLeave: "connector.entryHandler.onUserLeave" }, events: { succeed: "CONNECTION_CONNECT_SUCCEED", error: "CONNECTION_CONNECT_ERROR" } }; /** * 遊戲場景服務器 */ public static AREA = { KEY: "Server_AREA", info: { ip: "", port: "" }, handler: { enterScene: "area.playerHandler.enterScene", getAnimation: "area.playerHandler.getAnimation", changeStage: "area.playerHandler.changeStage", move: "area.playerHandler.move" }, events: { succeed: "CONNECTION_AREA_SUCCEED", error: "CONNECTION_AREA_ERROR" } }; /** * 獲取模塊 * targetName:模塊的名稱 info/handler/events * key:模塊的key */ public static GetTargetByKey(targetName: string, key: string) { var target; switch (key) { case Servers.GATE.KEY: target = Servers.GATE; break; case Servers.CONNECTION.KEY: target = Servers.CONNECTION; break; case Servers.AREA.KEY: target = Servers.AREA; break; default: console.log("發現未知服務端[network/servers/]"); break; } if (target) { switch (targetName) { case "info": return target.info; case "handler": return target.handler; case "events": return target.events; default: console.log("發現未知服務數據[network/servers/]"); break; } } } } }
完善socket連接類 network.GameSocket
module network { /** * webSocket for pomelo */ export class GameSocket { public constructor() { } static instance: GameSocket = new GameSocket(); /** * 單例模式 */ static getInstance(): GameSocket { return GameSocket.instance; } private pomelo: Pomelo; /** * 當前正在操做的是服務端 */ private currServer: Object; /** * 服務端狀態 是否開啓 */ private running: boolean = false; /** * 初始化 */ init() { if (this.pomelo == null) { this.pomelo = new Pomelo(); this.pomelo.on('server_push_message', (msg) => { var route = msg["route"]; //根據服務端返回派發事件 Global.dispatchEvent("PomeloServerEvents_" + route, msg); }); this.pomelo.on('onKick', (msg) => { trace("onKick"); }); this.pomelo.on('heartbeat_timeout', () => { trace("heartbeat_timeout"); }); this.pomelo.on('close', (e: CloseEvent) => { trace(e.currentTarget["url"] + "的連接被斷開"); }); } } /** * 打開服務端 * @param server:須要打開的服務端 * @param host:ip * @param port:端口 * @param callback:回調函數 * @param log:是否啓用日誌 */ open(server, callback?: Function, log: boolean = true) { //獲取服務端的設置 var targetEventsInfo = Servers.GetTargetByKey("events", server.KEY); //初始化服務端 this.pomelo.init({ host: server.info.ip, port: server.info.port, log: log }, false, (succeedRes) => { this.currServer = server; this.running = true; //派發服務端啓動成功事件 Global.dispatchEvent(targetEventsInfo.succeed); }, (errRES) => { //派發服務端發生錯誤事件 Global.dispatchEvent(targetEventsInfo.error); }, (closeRes) => { trace("一個服務端關閉完成。"); }, null); } /** * 發起請求 * @param route: 路由 (服務端處理函數) * @param msg:內容 * @param callback:回調函數 * @param thisArg:參數 */ request(route: string, msg: any, callback: Function, thisArg?: any): void { this.pomelo.request(route, msg, (response) => { callback.call(thisArg, response); }); } /** * 通知 */ notify(route: string, msg: any): void { this.pomelo.notify(route, msg); } /** * 關閉當前服務 */ disconnect() { this.pomelo.disconnect(); this.running = false; Global.dispatchEvent(Servers.events.currServerDisConnect, { currServer: this.currServer }); } /** * 獲取當前的服務端 */ getCurrServer() { return this.currServer; } /** * 獲取當前的服務端狀態 */ isRunning(): boolean { return this.running; } } }
以前例子中的PomeloTest變成
class PomeloTest { public constructor() { Global.addEventListener(network.Servers.GATE.events.succeed, this.onGateSucceed, this); Global.addEventListener(network.Servers.GATE.events.error, this.onGateError, this); Global.addEventListener(network.Servers.CONNECTION.events.succeed, this.onConnectSucceed, this); Global.addEventListener(network.Servers.CONNECTION.events.error, this.onConnectError, this); } connectGate() { network.GameSocket.getInstance().init(); network.GameSocket.getInstance().open(network.Servers.GATE); } private onGateSucceed() { Global.addEventListener(network.Servers.events.currServerDisConnect, this.onGateClosed, this); network.GameSocket.getInstance().request("gate.gateHandler.queryEntry", { uid: "" }, this.onGateMsg); trace("Gate服務端連接成功"); } private onGateError() { trace("Gate服務端連接失敗"); } private onGateMsg(gate_data) { network.Servers.CONNECTION.info.ip=gate_data.host; network.Servers.CONNECTION.info.port=gate_data.port; network.GameSocket.getInstance().disconnect(); trace("正在嘗試連接connect服務端..."); network.GameSocket.getInstance().open(network.Servers.CONNECTION); } private onGateClosed() { trace("Gate服務端成功斷開連接"); // trace("正在嘗試連接connect服務端..."); // config.global.pomelo.open(network.PomeloService.CONNECTION, this.connectIp, this.connectPort); } private onConnectSucceed() { trace("CONNECT服務端連接成功"); trace("開始註冊服務端信息..."); network.GameSocket.getInstance().request('connector.entryHandler.entry', { name: "" }, this.onEntryMsg); } private onConnectError() { trace("CONNECT服務端連接失敗..."); } private onEntryMsg(entry_data) { if (entry_data.code === 200) { trace("註冊信息成功"); trace("開始申請進入遊戲..."); network.GameSocket.getInstance().request('area.playerHandler.enterScene', { name: "", playerId: entry_data.playerId }, (respose) => { //Global.dispatchEvent(events.PomeloServerEvents.MAPMSG, respose); trace("進入遊戲成功"); trace("開始解析地圖信息"); }); } else { trace("註冊服務端信息出現問題,請檢查提交信息"); } } move(x: number, y: number, targetId: string) { network.GameSocket.getInstance().notify('area.playerHandler.move', { targetPos: { x: x, y: y }, target: targetId }); } changeStage(s: string) { network.GameSocket.getInstance().notify('area.playerHandler.changeStage', { S: s }); } }
由於服務端中多玩家的功能已經實現,這裏再也不繼續贅述。只要找到對應的服務端方法 就能夠進行服務端的邏輯代碼修改。
例子中已經實現遊戲的登陸和進入服務端,下面來看一下服務端中關於遊戲數據的返回值處理。
首先在遊戲場景中申請遊戲場景數據
network.GameSocket.getInstance().request(network.Servers.AREA.handler.enterScene, { name: this.txt_playerName.text, playerId: entry_data.playerId }, (respose) => { self.lbl_info.text = "進入遊戲成功"; self.lbl_info.text = "開始解析地圖信息"; console.log(respose); });
在服務端通過
在客戶端console出來的結果 即是散落在地上的裝備 數據
客戶端的顯示和玩家的移動通知處理,暫時不去作,由於和本身想要作的邏輯未必相同。至此已經大致瞭解pomelo的工做流程,和使用哪些處理器處理相關的業務邏輯,下節就要根據本身的需求設計遊戲,碰見什麼問題解決什麼問題。