第二人生的源码分析(二十五)人物行走与服务器同步
2023-09-14 09:10:40 时间
在网络游戏里,玩家的行走与平时单机版的游戏有着很大的差别,当你按下键盘时,人物角色并不能立即就向前行走,而是需要把它移动的请求发送到服务器,让服务器来作出判断是否可以行走,然后把行走位置通知视野里所有其它玩家,第二人生的客户端就会把这个人物按位置信息显示出来。下面就来分析怎么样发送玩家状态信息给服务器。
#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 深圳
相关文章
- linux ntp时钟服务器地址_Linux时间同步+国内常用的NTP服务器地址【NTP时间同步服务器】…
- 电力时间源服务器(北斗卫星同步时钟)技术应用方案
- 分布式互斥与同步
- 理论:第三章:索引使用的限制条件,sql优化有哪些,数据同步问题(缓存和数据库),缓存优化
- ntp时间同步协议_ntp服务器搭建
- gitee代码通过宝塔自动同步到服务器
- Canal实现MySQL数据实时同步
- java同步和锁(一)
- MySQL跨机房数据同步实现(mysql跨机房同步)
- 如何利用MySQL实现多数据库的同步(mysql同步不同数据库)
- 解决Linux服务器时钟同步的关键命令(linux时钟同步命令)
- MySQL多主同步技术实现高可用性(mysql多主同步)
- 数据同步深度解析:CSV与MySQL数据同步技术(csvmysql)
- 快速实现Linux与NFS服务器的数据同步(linuxnfs同步)
- 解决Linux时间同步问题:双机同步教程(两台linux时间同步)
- Linux系统中如何安装和配置NTP时间同步服务(linuxntp安装)
- 性能优化Redis同步性优化:改善服务器效率!(redis同步)
- 同步解决 Linux 服务器时间同步问题(linux服务器时间)
- Linux系统如何精确同步网络时间(linux网络时间同步)
- 开启Linux服务器之NTP时间同步(linux下ntp服务器)
- Linux下搭建NTP服务器实现时间同步(linux下ntp服务器)
- Linux下搭建NTP服务器,让时间保持同步!(linux下ntp服务器)
- 探究 Linux 中的同步异步原理(linux同步和异步)
- Mysql主从同步:同步时间有多种选择(mysql主从同步时间)
- Mysql时间同步:保持同一时刻(mysql同步时间)
- 库存如何实现同步至Redis(库存如何同步到redis)
- 实现四台Redis服务器实时同步(四台redis同步)
- 红色的同步Redis集群复制(redis集群同步复制)
- Redis队列实现跨服务器同步(redis 队列同步)
- Redis缓存同步实现极致性能优化(redis缓存如何同步)
- 解析Redis缓存同步的原理(redis缓存同步原理)
- 通过SQLServer2008数据库复制实现数据库同步备份