minetest源码解析八:ClientEnvironment

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 environment
m_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 queue
			ClientEvent 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;
		else
			lplayer->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并处理

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


  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值