[egret+pomelo]学习笔记(1)

[egret+pomelo]学习笔记(2)

[egret+pomelo]学习笔记(3)

服务端的请求流程走完了一遍,下面就该看一下,在目前的服务端中,各服务端所提供的功能了。

Gate:game-server/app/servers/gate/handler/gateHandler.js

queryEntry(msg,session,next):注册服务端,返回分配的connector服务端地址

Connector:game-server/app/servers/connector/handler/entryHandler.js

entry(msg, session, next):服务端注册session信息 返回玩家playerId
onUserLeave(app, session, reason):用户离开或关闭链接

Area:game-server/app/servers/area/handler/playerHandler.js

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

因为服务端中多玩家的功能已经实现,这里不再继续赘述。只要找到对应的服务端方法 就可以进行服务端的逻辑代码修改。

egret例子下载

例子中已经实现游戏的登录和进入服务端,下面来看一下服务端中关于游戏数据的返回值处理。

首先在游戏场景中申请游戏场景数据

                    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的工作流程,和使用哪些处理器处理相关的业务逻辑,下节就要根据自己的需求设计游戏,遇见什么问题解决什么问题。

[egret+pomelo]实时游戏杂记(3)的更多相关文章

  1. [egret+pomelo]实时游戏杂记(2)

    [egret+pomelo]学习笔记(1) [egret+pomelo]学习笔记(2) [egret+pomelo]学习笔记(3) pomelo pomelo服务端介绍(game-server/con ...

  2. [egret+pomelo]实时游戏杂记(1)

    [egret+pomelo]学习笔记(1) [egret+pomelo]学习笔记(2) [egret+pomelo]学习笔记(3) 资料 egret pomelo pomelo捡宝项目 准备工作 1. ...

  3. [egret+pomelo]实时游戏杂记(4)

    了解了前后端的通信,下面就可以开始自己的业务逻辑了,首先玩家输入名称,选择角色后进入游戏世界. 服务端的demo中已经提供了一些简单的角色信息和属性,数据地址位于 game-server/config ...

  4. [egret+pomelo]实时对战游戏杂记(5)

    之前大体了解了pomelo服务端的运行的大体运行流程,下面详细的学习一下在服务端比较重要的一个容器模块bearcat,在bearcat的wiki中我们可以对其有个大概的了解,在服务端示例的代码中也大量 ...

  5. Egret 之 消除游戏 开发 PART 6 Egret elimination game development PART 6

    Egret 之 消除游戏 开发 PART 6 Egret elimination game development PART 6 作者:韩梦飞沙 Author:han_meng_fei_sha 邮箱: ...

  6. Pomelo分布式游戏服务器框架

    Pomelo介绍&入门 目录 前言&介绍 安装Pomelo 创建项目并启动 创建项目 项目结构说明 启动 测试连接 聊天服务器 新建gate和chat服务器 配置master.json ...

  7. 为什么MOBA和吃鸡类游戏不推荐用tcp协议 延迟不利于实时游戏

    http://news.gamedog.cn/a/20171221/2287418.html 我们知道,不同类型的游戏因为玩法.竞技程度不一样,采用的同步算法不一样,对网络延迟的要求也不一样.例如,M ...

  8. 微信小游戏 查看egret的小游戏支持库版本

    在开发者工具 console输入egret.wxgame

  9. egret之消除游戏开发

    1.地图 (1)地图形状不同,尺寸不变 (2)背景图变化 2.步数 (1)不同关卡步数不同 (2)步数为01,游戏失败 3.道具 4.消除 (1)>=3可消除 (2)不可消除时,自动打乱 5.数 ...

随机推荐

  1. EasyMvc入门教程-高级控件说明(14)列布局控件

    想起刚做网页时候,看着这么大的屏幕,一直在 想该如何布局呢,后来经过Table布局,Div布局,Border布局,列式布局. 目前EasyMvc主要支持12列的列式布局(手机兼容性好).请看下面的例子 ...

  2. PHP提权之异步执行

    在服务器上都会定时运行一些脚本以完成周期性的任务. 而这些脚本往往是以root权限启动的, 替换或者改变其中的内容就可以完成提权.而今天在这要讲解的就是php提权中的异步执行方法. 在php中一般大家 ...

  3. 浅谈对TDD的看法

    程序猿对TDD这个词一定不陌生.近几年比較火.英文全称Test-Driven Development,測试驱动开发. 它要求在编写某个功能的代码之前先编写測试代码,然后仅仅编写使測试通过的功能代码,通 ...

  4. 我的IT之路

    在写这篇文章的时候内心是无比激动,因为这辈子是注定和IT打交道了. 都说大学时光是美好的,但却只有到了大四才知道时间是短暂的,也许和许多人一样,我的大学主要时光是在游戏中度过,1000多把的寒冰算是同 ...

  5. 关于meta标签的name="viewport" 概述

    <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scal ...

  6. vim  模式查找

    1. / 正向查找, ?反向查找 2. \v 激活very magic搜索模式,撰写正则表达式更接近于perl的正则表达式,大多数字符不需要进行转义 3. \V 激活noVeryMagic模式,按字符 ...

  7. vim 穿越时空

    1. 回到以前的文件状态 :earlier 3m   回到文件3分钟之前的状态 2. 回到以后的文件状态 :later 3m      回到文件3分钟之后的状态 3. 时间单位 s 秒 m 分钟 d ...

  8. linux下复制文件夹命令

    在源文件的目录下,对其进行cp操作,到后面的目标路径,对其进行文件夹复制 cp -rf /home/wangshiming/Downloads/* /home/wangshiming/tools

  9. CSS -- 未解之疑

    @.css那些事儿 -- 第9章 反馈表单 自己编写了CSS,可是红框中的横线比下面的要粗.对比作者的代码,发现可能与上面标题h3的height和line-height有关,但是不知道具体是为什么? ...

  10. JAVA学习第五十二课 — IO流(六)File对象

    File类 用来给文件或者目录封装成对象 方便对文件与目录的属性信息进行操作 File对象能够作为參数传递给流的构造函数 一.构造函数和分隔符 public static void FileDemo( ...