写点什么

Rust 元宇宙 3 —— 进入和离开

作者:Miracle
  • 2021 年 11 月 29 日
  • 本文字数:1370 字

    阅读完需:约 4 分钟

Rust 元宇宙 3 —— 进入和离开

不论是真实世界,还是我们的元宇宙世界中,角色总是来来往往的,从其中某个人的视角看去,就是不断的有角色进入自己的视野,离开自己的视野,这种进入和离开时的事件需要特别被关注,因为显示周边的角色,和周边角色发生社交关系,交互甚至战斗,是元宇宙最基础的功能。

所以,我们定义下面的通知类型:


pub enum NotifyType {    Enter(u32, Vec<(u32, Position, Movement)>),    Leave(u32, Vec<u32>), }
复制代码


如何在合适的时候,通知角色可视区域内的角色发生了变化呢,我们考虑下面三种情况:

  • 角色在进入世界的时候,需要知道周围的邻居,以及通知每一个邻居自己的到来

通过下面的代码完成


let neighbor = self.get_neighbor(&pos, region, quadrant);    for n in &neighbor {        self.roles.get_mut(n).map(|r| {            r.neighbor.push(id);            r.neighbor.sort();        });    }    let infos = self.get_role_infos(&neighbor);    self.notifier.blocking_send(NotifyType::Enter(id, infos)).ok();    for r in &neighbor {        self.notifier.blocking_send(NotifyType::Enter(*r, vec![(id, pos.clone(), action.clone())])).ok();    }
复制代码


  • 角色离开世界的时候,需要通知周围的邻居自己的离开

代码如下


for n in &role.neighbor {    self.roles.get_mut(n).map(|r| {        if let Ok(index) = r.neighbor.binary_search(&id) {            r.neighbor.remove(index);        }    });}for r in &role.neighbor {    self.notifier.blocking_send(NotifyType::Leave(*r, vec![id])).ok();}
复制代码


  • 定时刷新

仅仅是离开和进入的时候是不够的,由于角色的移动,会造成一段时间之后,角色的邻居发生了变化,需要刷新,当然这个刷新频率不需要类似移动那么快,我们假设移动的速率是每秒 20 次的话,大概五秒钟刷新一次就足够了,刷新的代码如下


let ids: Vec<u32> = self.roles.keys().map(|id| *id ).collect();for id in ids {    let role = self.roles.remove(&id).unwrap();    let (region, quadrant) = role.pos.center_quadrant(self.region_size);    let neighbor = self.get_neighbor(&role.pos, region, quadrant);    let appear = neighbor.iter().fold(Vec::new(), |mut v, n| {        if !role.neighbor.binary_search(n).is_ok() { v.push(*n); }        v    });    let disappear = role.neighbor.iter().fold(Vec::new(), |mut v, n| {        if !neighbor.binary_search(n).is_ok() { v.push(*n); }        v    });    if !appear.is_empty() {        let infos = self.get_role_infos(&appear);        self.notifier.blocking_send(NotifyType::Enter(id, infos)).ok();    }    if !disappear.is_empty() {        self.notifier.blocking_send(NotifyType::Leave(id, disappear)).ok();    }    self.roles.insert(id, RoleInfo{pos: role.pos, action: role.action, neighbor});}
复制代码


首先获得某个角色的最新邻居,然后跟之前的比较,新出现的,代表有新的角色进入某个角色的视野了,然后再遍历之前的邻居,如果新的里面没有,则表示消失的角色。

用户头像

Miracle

关注

还未添加个人签名 2019.10.25 加入

还未添加个人简介

评论

发布
暂无评论
Rust 元宇宙 3 —— 进入和离开