zoukankan      html  css  js  c++  java
  • Firefly的角色跳转场景简单示例

    源地址: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.         
    12. @remoteserviceHandle("gate")
    13. def deletePlayer_1002(pid):
    14.     '''删除角色实例
    15.     '''
    16.     if PlayersManager().isHavePlayer(pid):#如果角色管理器中有该角色
    17.         user = PlayersManager().getPlayer(pid)#获取该角色实例
    18.         sid = user.sid#获取角色所在场景实例
    19.         PlayersManager().dropPlayer(pid)#从角色管理器中删除该角色
    20.         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>

  • 相关阅读:
    composer "Illegal offset type in isset or empty"报错解决方案
    Yii2 使用a标签发送post请求
    YII2 项目安装步骤及异常记录
    三级城市联动菜单
    最新全国省、市、县数据库
    Sanic官翻-SSL示例
    Sanic官翻-WebSocket
    Sanic官翻-部署
    Sanic官翻-概述
    老子的道德经
  • 原文地址:https://www.cnblogs.com/123ing/p/3905123.html
Copyright © 2011-2022 走看看