在网络游戏里,玩家的行走与平时单机版的游戏有着很大的差别,当你按下键盘时,人物角色并不能立即就向前行走,而是需要把它移动的请求发送到服务器,让服务器来作出判断是否可以行走,然后把行走位置通知视野里所有其它玩家,第二人生的客户端就会把这个人物按位置信息显示出来。下面就来分析怎么样发送玩家状态信息给服务器。
#001 void LLAppViewer::idle()
#002 {
#003 // Update frame timers
#004 static LLTimer idle_timer;
#005 
#006 LLControlBase::updateAllListeners();
#007 
#008 LLFrameTimer::updateFrameTime();
#009 LLEventTimer::updateClass();
#010 LLCriticalDamp::updateInterpolants();
#011 LLMortician::updateClass();
#012  F32 dt_raw = idle_timer.getElapsedTimeAndResetF32();
#013 
……
#077
#078 static LLFrameTimer agent_update_timer;
#079 static U32                          last_control_flags;
#080
#081 //     When appropriate, update agent location to the simulator.
#082 F32 agent_update_time = agent_update_timer.getElapsedTimeF32();
#083 BOOL flags_changed = gAgent.controlFlagsDirty() || (last_control_flags != gAgent.getControlFlags());
#084
#085 if (flags_changed || (agent_update_time > (1.0f / (F32) AGENT_UPDATES_PER_SECOND)))
#086 {
#087 // Send avatar and camera info
#088 last_control_flags = gAgent.getControlFlags();
#089 send_agent_update(TRUE);
#090 agent_update_timer.reset();
#091 }
#092 }
#093 ......
#094 }
上面第83行获取当前角色的状态是否发生变化,然后通过send_agent_update函数不断地发送状态消息给服务器。接着下来就去分析这个函数,它的代码如下:
#001 void send_agent_update(BOOL force_send, BOOL send_reliable)
#002 {
#003 if (gAgent.getTeleportState() != LLAgent::TELEPORT_NONE)
#004 {
#005 // We don't care if they want to send an agent update, they're not allowed to until the simulator
……
#147 
#148 if (duplicate_count < DUP_MSGS && !gDisconnected)
#149 {
#150 // Build the message
#151 msg->newMessageFast(_PREHASH_AgentUpdate);
#152 msg->nextBlockFast(_PREHASH_AgentData);
#153 msg->addUUIDFast(_PREHASH_AgentID, gAgent.getID());
#154 msg->addUUIDFast(_PREHASH_SessionID, gAgent.getSessionID());
#155 msg->addQuatFast(_PREHASH_BodyRotation, body_rotation);
#156 msg->addQuatFast(_PREHASH_HeadRotation, head_rotation);
#157 msg->addU8Fast(_PREHASH_State, render_state);
#158 msg->addU8Fast(_PREHASH_Flags, flags);
#159 
#160 //if (camera_pos_agent.mV[VY] > 255.f)
#161 //{
#162 //llinfos << "Sending camera center " << camera_pos_agent << llendl;
#163 //}
#164 
#165 msg->addVector3Fast(_PREHASH_CameraCenter, camera_pos_agent);
#166 msg->addVector3Fast(_PREHASH_CameraAtAxis, gCamera->getAtAxis());
#167 msg->addVector3Fast(_PREHASH_CameraLeftAxis, gCamera->getLeftAxis());
#168 msg->addVector3Fast(_PREHASH_CameraUpAxis, gCamera->getUpAxis());
#169 msg->addF32Fast(_PREHASH_Far, gAgent.mDrawDistance);
#170 
#171 msg->addU32Fast(_PREHASH_ControlFlags, control_flags);
#172 
#173 if (gDebugClicks)
#174 {
#175 if (control_flags & AGENT_CONTROL_LBUTTON_DOWN)
#176 {
#177 llinfos << "AgentUpdate left button down" << llendl;
#178 }
#179 
#180 if (control_flags & AGENT_CONTROL_LBUTTON_UP)
#181 {
#182 llinfos << "AgentUpdate left button up" << llendl;
#183 }
#184 }
#185 
#186 gAgent.enableControlFlagReset();
#187 
#188 if (!send_reliable)
#189 {
#190 gAgent.sendMessage();
#191 }
#192 else
#193 {
#194 gAgent.sendReliableMessage();
#195 }
#196 
#197 //llinfos << "agent " << avatar_pos_agent << " cam " << camera_pos_agent << llendl;
#198 
#199 // Copy the old data
#200 last_head_rot = head_rotation;
#201 last_render_state = render_state;
#202 last_camera_pos_agent = camera_pos_agent;
#203 last_camera_at = gCamera->getAtAxis();
#204 last_camera_left = gCamera->getLeftAxis();
#205 last_camera_up = gCamera->getUpAxis();
#206 last_control_flags = control_flags;
#207 last_flags = flags;
#208 }
#209 }
#210 
在上面的代码里,就调用msg消息对象创建状态消息,然后通过sendMessage和sendReliableMessage函数发送给服务器,这样在服务器的玩家角色就会更新状态,如果行走的话,也会得到更新的。第二人生里的消息结构是根据XML模板来构造的,这个部分的功能也比较复杂。

蔡军生 2008/3/14 QQ:9073204 深圳

第二人生的源码分析(二十五)人物行走与服务器同步相关推荐

  1. 【转】ABP源码分析二十五:EventBus

    IEventData/EventData: 封装了EventData信息,触发event的源对象和时间 IEventBus/EventBus: 定义和实现了了一系列注册,注销和触发事件处理函数的方法. ...

  2. ABP源码分析二十五:EventBus

    IEventData/EventData: 封装了EventData信息,触发event的源对象和时间 IEventBus/EventBus: 定义和实现了了一系列注册,注销和触发事件处理函数的方法. ...

  3. 第二人生的源码分析(二十六)底层网络协议

    为了理解第二人生的客户端与服务器的沟通,那么下面就来分析一下第二人生采用的网络协议.在目前的网络里,主要有两个协议:TCP和UDP,而第二人生里是采用UDP协议.TCP协议与UDP协议的主要区别,就是 ...

  4. 【转】ABP源码分析二十九:ABP.MongoDb

    这个Module通过建立一个MongoDbRepositoryBase<TEntity> 基类,封装了对MongoDb数据库的操作. 这个module通过引用MongoDB.Driver, ...

  5. 【转】ABP源码分析四十五:ABP ZERO中的EntityFramework模块

    AbpZeroDbContext:配置ABP.Zero中定义的entity的Dbset EntityFrameworkModelBuilderExtensions:给PrimitiveProperty ...

  6. 【转】ABP源码分析三十五:ABP中动态WebAPI原理解析

    动态WebAPI应该算是ABP中最Magic的功能之一了吧.开发人员无须定义继承自ApiController的类,只须重用Application Service中的类就可以对外提供WebAPI的功能, ...

  7. 【转】ABP源码分析二十八:ABP.MemoryDB

    这个模块简单,且无实际作用(该模块用于支持ABP框架单元测试的).一般实际项目中都有用数据库做持久化,用了数据库就无法用这个MemoryDB 模块了.原因在于ABP限制了UnitOfWork的类型只能 ...

  8. 【转】ABP源码分析二十六:核心框架中的一些其他功能

    本文是ABP核心项目源码分析的最后一篇,介绍一些前面遗漏的功能 AbpSession AbpSession: 目前这个和CLR的Session没有什么直接的联系.当然可以自定义的去实现IAbpSess ...

  9. 【转】ABP源码分析二十四:Notification

    NotificationDefinition: 用于封装Notification Definnition 的信息.注意和Notification 的区别,如果把Notification看成是具体的消息 ...

  10. 【转】ABP源码分析二十二:Navigation

    MenuDefinition:封装了导航栏上的主菜单的属性. MenuItemDefinition:封装了主菜单的子菜单的属性.子菜单可以引用其他子菜单构成一个菜单树 UserMenu/UserMen ...

最新文章

  1. 【计算机视觉】跟踪算法及相关主页
  2. docker 在esx上的网络配置
  3. ZooKeeper自定义数据日志目录
  4. 前后端分离的项目部署到tomcat_如何在开发时部署和运行前后端分离的JavaWeb项目...
  5. linux dns 内网ip,Ubuntu中ip地址、网关、网络号、DNS等解释
  6. 深度学习数据标注工具(转)
  7. Yarn无法查看日志: Aggregation may not be complete, Check back later or try the nodemanager at xxxx:xxxx
  8. php 递归函数返回数组,php递归函数 PHP中Array相关函数简介
  9. 阿里播放器使用Aliplayer
  10. NB-IOT物联网模块BC26问题合集
  11. 小散量化炒股记|只花几秒钟!多任务爬虫获取A股每日实时行情数据
  12. js正则表达式 验证非负数
  13. excel离散度图表怎么算_excel离散数据表格-Excel 离散程度分析图表如何做
  14. requests 已过时,初探协程与异步 http 框架 httpx
  15. 大聪明教你学Java | 实现邮件发送(以163邮箱向QQ邮箱发送邮件为例)
  16. 《Linux内核设计与实现》之进程
  17. win10 路由表配置
  18. Elasticsearch 8.x 破解x-pack-core
  19. android英文文献翻译,安卓 英文 外文 文献翻译 android api级别.doc
  20. OpenMV 线性回归巡线之一:赛道提取

热门文章

  1. Intel Cyclone 10 GX 收发器的时钟网络
  2. html在excel中查询,excel通配符查找 excel任意字母的通配符
  3. python怎么算积分_Python求解数值积分-定积分求解
  4. 如何在CentOS系统服务器下搭建代理IP
  5. 2020 — 只争朝夕,不负韶华
  6. android 呼吸灯权限_自定义 呼吸灯 闪烁 效果 自定义View
  7. 2018第九届蓝桥杯B组决赛题解第四题 调手表(简单的dp)
  8. 如何使用Nginx Ingress实现灰度发布和蓝绿发布?
  9. 鸿蒙系统我的二次元之旅,创世神的二次元
  10. FTP上传失败报错解决