源地址:http://bbs.9miao.com/thread-45790-1-2.html

本例演示的是模拟游戏服务端,让角色在场景1中跳转到场景2中。在实际游戏中,client将要跳转的角色id和目标场景id发给net,net转发给gate,gate将目标场景id与角色当前所在场景id进行对比,一样则返回跳转失败,不一样则在目标场景服务器重新实例化一个角色,然后将之前的场景服务器中的角色实例删除。因为此次只是掩饰原理,所以实际中的各种验证等就不进行处理了,有问题可以在论坛发帖探讨。

1.创建工程

命令行下输入firefly-admin.py createproject communication(linux在终端输入)

<ignore_js_op>

firefly会创建一个名为communication的工程

<ignore_js_op>

2.导入工程

将工程导入到eclipse中

<ignore_js_op>

3.配置参数

配置config.json中的相应参数

  1. {
  2. "master":{"rootport":8999,"webport":9998},
  3. "servers":{
  4. "gate":{"rootport":10000,"name":"gate","app":"app.gate.gateserver"},
  5. "net":{"netport":11009,"name":"net","remoteport":[{"rootport":10000,"rootname":"gate"}],"app":"app.net.netserver"},
  6. "scene1":{"remoteport":[{"rootport":10000,"rootname":"gate"}],"name":"scene1","app":"app.scene.sceneserver"},
  7. "scene2":{"remoteport":[{"rootport":10000,"rootname":"gate"}],"name":"scene2","app":"app.scene.sceneserver"}
  8. },
  9. "db":{
  10. "host":"localhost",
  11. "user":"root",
  12. "passwd":"111",
  13. "port":3306,
  14. "db":"anheisg",
  15. "charset":"utf8"
  16. },
  17. "memcached":{
  18. "urls":["127.0.0.1:11211"],
  19. "hostname":"test"
  20. }
  21. }

复制代码

具体参数含义和配置说明详见:http://bbs.9miao.com/forum.php?m ... 6orderby%3Ddateline

4.编写代码

在上面填写的server配置的app对应路径下分别建立netserver.py、gateserver.py和sceneserver.py,这里只列出了几个重要文件,其他如User.py、UserManager.pu等详见附件。

1)netserver.py:

  1. #coding:utf8
  2. from firefly.server.globalobject import netserviceHandle,GlobalObject
  3. @netserviceHandle
  4. def login_1004(_conn,data):
  5. data = eval(data)#客户端传来的number是str型,转换成dict型
  6. pid = data.get("pid")#获取pid
  7. sid = data.get("sid")#获取sid
  8. result = GlobalObject().remote['gate'].callRemote("enterScene_1003",pid,sid)#调用root服务器(gate)的enterScene_1003方法,参数为pid,sid
  9. return result#返回结果

复制代码

2)gateserver.py:

  1. #coding:utf8
  2. from User import User
  3. from UserManager import UserManager
  4. from firefly.server.globalobject import GlobalObject,rootserviceHandle
  5. @rootserviceHandle
  6. def enterScene_1003(pid,sid):
  7. '''进入场景
  8. @param pid: int 角色id
  9. @param sid: str 要跳转的场景id
  10. '''
  11. if not UserManager().isHaveUser(pid):#如果用户管理器中没有该用户
  12. user = User(pid,sid)#实例化角色
  13. UserManager().addUser(user)#添加到用户管理器中
  14. result = GlobalObject().root.callChildByName(sid,"enterScene_1001",pid,sid)#调用node服务器(sid)的enterScene_1001方法,参数为pid,sid
  15. return result#返回结果
  16. else:#如果用户管理器中有该用户
  17. user = UserManager().getUser(pid)#获取该用户实例
  18. nowSid = user.sid#用户当前所在场景id
  19. if nowSid == sid:#用户当前所在场景id与要跳转的场景id相同
  20. return "Failure"#返回失败信息
  21. else:#否则
  22. result1 = GlobalObject().root.callChildByName(sid,"enterScene_1001",pid,sid)#调用node服务器(sid)的enterScene_1001方法,参数为pid,sid
  23. GlobalObject().root.callChildByName(nowSid,"deletePlayer_1002",pid)#调用node服务器(nowSid)的deletePlayer_1002方法,参数为pid
  24. UserManager().updateSid(pid, sid)#更新用户前所在场景id
  25. return result1#返回结果

复制代码

3)sceneserver.py

  1. #coding:utf8
  2. from firefly.server.globalobject import remoteserviceHandle
  3. from Player import Player
  4. from PlayersManager import PlayersManager
  5. @remoteserviceHandle("gate")
  6. def enterScene_1001(pid,sid):
  7. '''进入场景'''
  8. player = Player(pid,sid)#实例化角色实例
  9. PlayersManager().addPlayer(player)#将角色添加到角色管理器中
  10. return "I'm now at %s" % sid#返回跳转成功信息
  11. @remoteserviceHandle("gate")
  12. def deletePlayer_1002(pid):
  13. '''删除角色实例
  14. '''
  15. if PlayersManager().isHavePlayer(pid):#如果角色管理器中有该角色
  16. user = PlayersManager().getPlayer(pid)#获取该角色实例
  17. sid = user.sid#获取角色所在场景实例
  18. PlayersManager().dropPlayer(pid)#从角色管理器中删除该角色
  19. print 'I left %s' % sid

复制代码

4)最后编写客户端——client.py:

  1. #coding:utf8
  2. from socket import AF_INET,SOCK_STREAM,socket
  3. import struct
  4. import time
  5. def sendData(sendstr,commandId):
  6. '''定义协议头
  7. '''
  8. HEAD_0 = chr(0)
  9. HEAD_1 = chr(0)
  10. HEAD_2 = chr(0)
  11. HEAD_3 = chr(0)
  12. ProtoVersion = chr(0)
  13. ServerVersion = 0
  14. sendstr = sendstr
  15. data = struct.pack('!sssss3I',HEAD_0,HEAD_1,HEAD_2,\
  16. HEAD_3,ProtoVersion,ServerVersion,\
  17. len(sendstr)+4,commandId)
  18. senddata = data+sendstr
  19. return senddata
  20. def resolveRecvdata(data):
  21. '''解析数据,根据定义的协议头解析服务器返回的数据
  22. '''
  23. head = struct.unpack('!sssss3I',data[:17])
  24. lenght = head[6]
  25. message = data[17:17+lenght]
  26. return message
  27. if __name__ == "__main__":
  28. HOST='localhost'
  29. PORT=11009
  30. ADDR=(HOST , PORT)
  31. client = socket(AF_INET,SOCK_STREAM)
  32. client.connect(ADDR)#建立socket连接
  33. client.sendall(sendData("{'pid':100001,'sid':'scene1'}",1004))#向服务器发送消息
  34. message = client.recv(1024)#接收服务器返回的消息
  35. message = resolveRecvdata(message)#解析消息
  36. print message
  37. time.sleep(3)
  38. client.sendall(sendData("{'pid':100001,'sid':'scene2'}",1004))#向服务器发送消息
  39. message = client.recv(1024)#接收服务器返回的消息
  40. message = resolveRecvdata(message)#解析消息
  41. print message
  42. time.sleep(3)
  43. client.sendall(sendData("{'pid':100001,'sid':'scene2'}",1004))#向服务器发送消息
  44. message = client.recv(1024)#接收服务器返回的消息
  45. message = resolveRecvdata(message)#解析消息
  46. print message
  47. client.close()

复制代码

5.运行程序

1)运行服务器,打开附件下载的communication文件夹,打开命令行窗口,输入python startmaster.py,回车,如图:

<ignore_js_op>

2)运行客户端,第一次登陆时,角色进入了场景1,成功;第二次由场景1台转到场景2,成功;第三次由场景2跳转到场景2,失败。

<ignore_js_op>

Firefly的角色跳转场景简单示例的更多相关文章

  1. ibeacon的使用和应用场景简单示例

    目的,用ibeacon实现签到功能,不需要太严谨,只是试水. 拿到ibeacon的第一感觉是,这东西能用嘛,2-3年的电池,后面商家说是用个3M双面胶找个地方一贴就行,感觉不太靠谱,嘿嘿,在网上找了一 ...

  2. Optaplanner规划引擎的工作原理及简单示例(2)

    开篇 在前面一篇关于规划引擎Optapalnner的文章里(Optaplanner规划引擎的工作原理及简单示例(1)),老农介绍了应用Optaplanner过程中需要掌握的一些基本概念,这些概念有且于 ...

  3. spring-servlet.xml简单示例

    spring-servlet.xml简单示例 某个项目中的spring-servlet.xml 记下来以后研究用 <!-- springMVC简单配置 --> <?xml versi ...

  4. Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装项目其它需要包 清除冗余文件并重新规划项目目录 配置文件 规划示例路由,并新建相关文件 实现数据访问和业务逻辑相关方法 编写mys ...

  5. springMVC源码分析--异常处理机制HandlerExceptionResolver简单示例(一)

    springMVC对Controller执行过程中出现的异常提供了统一的处理机制,其实这种处理机制也简单,只要抛出的异常在DispatcherServlet中都会进行捕获,这样就可以统一的对异常进行处 ...

  6. [转]Nodejs学习笔记(十五)--- Node.js + Koa2 构建网站简单示例

    本文转自:https://www.cnblogs.com/zhongweiv/p/nodejs_koa2_webapp.html 目录 前言 搭建项目及其它准备工作 创建数据库 创建Koa2项目 安装 ...

  7. web 框架的本质及自定义web框架 模板渲染jinja2 mvc 和 mtv框架 Django框架的下载安装 基于Django实现的一个简单示例

    Django基础一之web框架的本质 本节目录 一 web框架的本质及自定义web框架 二 模板渲染JinJa2 三 MVC和MTV框架 四 Django的下载安装 五 基于Django实现的一个简单 ...

  8. Unity跳转场景进度条制作教程(异步加载)

    Unity跳转场景进度条制作 本文提供全流程,中文翻译. Chinar 坚持将简单的生活方式,带给世人!(拥有更好的阅读体验 -- 高分辨率用户请根据需求调整网页缩放比例) Chinar -- 心分享 ...

  9. Unity3d-通过简单示例来理解Time.deltaTime

    转载文章: Unity3d-通过简单示例来理解Time.deltaTime 2018年04月21日 18:04:14 Black_Window 阅读数:926 标签: UnityTime 更多 个人分 ...

随机推荐

  1. UML建模——概述

    轻松玩建模 统一建模语言UML快速入门 http://soft.yesky.com/lesson/281/2472281.shtml UML是一种定义良好.易于表达.功能强大且普遍适用的建模语言.它溶 ...

  2. python学习day2--python基础

    python没有常量的定义方式,一般常量可人为用全部大写字母来表示. 如: MYSQL_CONNECTION='192.168.10.2' 以os库为例: import os os.system('i ...

  3. JavaBean在JSP中显示时间

    创建DateTimeBean的类,将其放置于org.caiduping.bean的包中,实现时间,星期的封装. package org.caiduping.bean; import java.text ...

  4. Amoeba For MySQL入门:实现数据库水平切分

    当系统数据量发展到一定程度后,往往需要进行数据库的垂直切分和水平切分,以实现负载均衡和性能提升,而数据切分后随之会带来多数据源整合等等问题.如果仅仅从应用程序的角度去解决这类问题,无疑会加重应用程度的 ...

  5. 【leetcode】10.Regular Expression Matching

    题目描述: Implement regular expression matching with support for '.' and '*'. '.' Matches any single cha ...

  6. Contest1065 - 第四届“图灵杯”NEUQ-ACM程序设计竞赛(个人赛)C粉丝与汉诺塔

    题目描述 苟利国家生死以,岂因福祸避趋之?作为ACM真正的粉丝,应该都听闻过汉诺塔问题,汉诺塔问题是这样的: 有三根柱子,编号A,B,C柱,初始情况下A柱上有n个盘子,小盘子在上大盘子在下,n个盘子大 ...

  7. Ng机器学习笔记-1-一元线性回归

    一:回归模型介绍 从理论上讲,回归模型即用已知的数据变量来预测另外一个数据变量,已知的数据属性称为输入或者已有特征,想要预测的数据称为输出或者目标变量. 下图是一个例子: 图中是某地区的面积大小与房价 ...

  8. GSM嗅探

    GSM初探 大家应该都听说过HTTP协议,又听说WEB服务,每一个服务的背后都有一个协议在工作着.所谓的没有规矩不成方圆,说的就是这个道理,每一个细小的部分,都已经规定好,只要按照协议执行,就不会出现 ...

  9. HTTP Error 500.21解决方案

    Windows 7 IIS (HTTP Error 500.21 - Internal Server Error)解决方案   今天在测试网站的时候,在浏览器中输入http://localhost/时 ...

  10. java将多个连续的空格转化成一个空格

    java将多个连续的空格转化成一个空格: System.out.println("a a".replaceAll(" + ", " ")); ...