minetest源码解析八:ClientEnvironment

来源:互联网 发布:利口酒 知乎 编辑:程序博客网 时间:2024/06/05 17:13

minetest源码解析八:ClientEnvironment


ClientEnvironment

minetest->environment.h


class ClientEnvironment : public Environment

{

void step(f32 dtime);

ClientMap *m_map;

std::map<u16,ClientActiveObject*> m_active_objects;

std::list<ClientSimpleObject*> m_simple_objects;

std::list<ClientEnvEvent> m_client_event_queue;

std::list<Player*> m_players;

};


这个对象主要是客户端环境对象,继承于Environment。服务端也有对应的ServerEnvironment类,同样也是继承于Environment


ClientEnvironment对象中主要包含ClientMap(客户端地图)、Players(玩家)、ClientActiveObject(客户端激活对象)这几个对象。函数方法中有个step()函数比较重要,主要是通过它来进行客户端环境更新的。


ClientEnvironment->step() 调用

只有客户端进行更新时才会调用客户端环境更新(ClientEnvironment->step()),即client->step()中有m_env->step()


客户端环境进行更新,主要更新光照、溺水、液体流淌等或者是设置客户端环境事件。然后在客户端更新中获取客户端环境事件,并根据相应事件类型做出相应的操作。


涉及函数


// Step environmentm_env.step(dtime);/*Get events*/for(;;){ClientEnvEvent event = m_env.getClientEvent();if(event.type == CEE_NONE){break;}else if(event.type == CEE_PLAYER_DAMAGE){if(m_ignore_damage_timer <= 0){u8 damage = event.player_damage.amount;if(event.player_damage.send_to_server)sendDamage(damage);// Add to ClientEvent queueClientEvent event;event.type = CE_PLAYER_DAMAGE;event.player_damage.amount = damage;m_client_event_queue.push_back(event);}}else if(event.type == CEE_PLAYER_BREATH){u16 breath = event.player_breath.amount;sendBreath(breath);}}


客户端环境事件相关定义


enum ClientEnvEventType{CEE_NONE,CEE_PLAYER_DAMAGE,CEE_PLAYER_BREATH};struct ClientEnvEvent{ClientEnvEventType type;union {struct{} none;struct{u8 amount;bool send_to_server;} player_damage;struct{u16 amount;} player_breath;};};



客户端环境更新流程图





客户端环境更新流程图核心函数说明


1.Step time of day

更新day time


2.Get some settings

获取玩家的flyfree_move属性


3.Get local playerGet the speed the player is going

获取本地玩家以及当前玩家的速度,主要为后面做准备


4.Maximum position increment

最大位置增量、时间增量等


5.Handle local play->move(最大时间增量)应用物理:重力、液体浮力、液体下沉、液体阻力

循环执行,根据物理特性(重力、液体浮力、液体下沉、液体阻力)以及当前玩家的速度等计算玩家新的速度,来最终执行玩家移动。玩家以新的速度在最大的时间增量范围内移动。


6.坠落损伤:客户端环境事件

计算玩家坠落时的速度,根据速度来进一步确定玩家受伤情况甚至死亡。如果玩家死亡则执行damageLocalPlayer(damage,true);这里主要设置了一个玩家消亡的环境事件,没有真的立马执行玩家消亡事件,而是在退出客户端环境更新时再执行的。

涉及到的函数

damageLocalPlayer(damage, true);


void ClientEnvironment::damageLocalPlayer(u8 damage, bool handle_hp){LocalPlayer *lplayer = getLocalPlayer();assert(lplayer);if(handle_hp){if(lplayer->hp > damage)lplayer->hp -= damage;elselplayer->hp = 0;}ClientEnvEvent event;event.type = CEE_PLAYER_DAMAGE;event.player_damage.amount = damage;event.player_damage.send_to_server = handle_hp;m_client_event_queue.push_back(event);}



7.熔岩损伤:客户端环境事件

先获取玩家头、中间、脚不同位置的node,根据nodenodedefinition中的contentFeature中的damage_per_second计算损伤,从而进行damageLocalPlayer(damage_per_second,true)


8.Drowning:溺水时呼吸、玩家生命值没了damage

溺水大于2s时头溺水情况,如果头已经在水里了,就需要计算玩家的呼吸情况以及要更新玩家呼吸事件,如果呼吸为0了,还需要damage玩家。

呼吸间隔大于0.5s时,如果没有溺水,就正常更新玩家呼吸情况,并更新环境事件列表。


涉及到的函数

void ClientEnvironment::updateLocalPlayerBreath(u16 breath){ClientEnvEvent event;event.type = CEE_PLAYER_BREATH;event.player_breath.amount = breath;m_client_event_queue.push_back(event);}


9.non-local palyers->move

处理不是本地的玩家move


10.Update lighting on all players on client

更新客户端上所有玩家的光照


11.Step active objects and update lighting of them

更新active objects以及它们的光照


12.Step and handle simple objects

更新处理simple Objects


13.GetClientEnvironmentEvent并处理

循环获取客户端环境事件,知道所有事件处理完毕退出循环。


阅读全文
0 0