写点什么

Rust 元宇宙 9 —— 库和序列化

作者:Miracle
  • 2021 年 11 月 30 日
  • 本文字数:1512 字

    阅读完需:约 5 分钟

Rust 元宇宙 9 —— 库和序列化

让我们看看到目前为止的成果吧:

接下来我们需要完成两个任务,

一个是能够存储某个角色的状态,这样如果新用户暂时离开之后,再回到我们的虚拟世界,就可以回到上次所在的位置,还拥有上次在元宇宙中获得的物品和好友。

另外一个当然是开始实现元宇宙的接入端,今后的形态可能是电脑,手机,VR/AR 眼镜等等,每个人每台设备,都可以以自己的方式进入元宇宙,所以我们需要规定元宇宙的接入协议。

作为一个开始,我们需要清理我们的代码,目前所有的代码都是为服务器服务的,我们需要将接入协议相关的内容从服务器代码中独立出来,这样,我们可以直接在此基础上,实现协议,甚至是客户端的实现。

Rust 的 包管理系统就是做这件事情的。

首先我们创建一个 share 的库,将 客户端和服务端需要共享的代码分离出来。

执行上述代码之后,我们得到一个 share 目录

我们创建一个 msg.rs,在 lib.rs 加上一行

pub mod msg;
复制代码

把 Point 的定义放到 msg.rs 中

#[derive(Debug, Serialize, Deserialize, Clone)]pub struct Position {    pub x: f32,    pub y: f32}
static CENTER_QUADRANT: Lazy<Vec<Vec<((i32, i32), usize)>>> = Lazy::new(|| { vec![vec![((-1, -1), 1), ((-1, 0), 4), ((-1, 0), 1), ((-1, 1), 4)], vec![((0, -1), 2), ((0, 0), 3), ((0, 0), 2), ((0, 1), 3)], vec![((0, -1), 1), ((0, 0), 4), ((0, 0), 1), ((0, 1), 4)], vec![((1, -1), 2), ((1, 0), 3), ((1, 0), 2), ((1, 1), 3)]]});
impl Position { #[allow(dead_code)] pub fn distance_square(&self, pos: &Position)-> i32 { let delta_x = (self.x - pos.x) as i32; let delta_y = (self.y - pos.y) as i32; delta_x * delta_x + delta_y * delta_y } fn _index(value: i32, half: i32)-> usize { if value < -half { 0 } else if value < 0 { 1 } else if value < half { 2 } else { 3 } } #[allow(dead_code)] pub fn center_quadrant(&self, size: i32)-> ((i32, i32), usize) { //get position's center and quadrant ((center's x, center's y), quadrant) let xy = (self.x as i32, self.y as i32); let offset = (xy.0 % size, xy.1 % size); let delta = CENTER_QUADRANT[Position::_index(offset.0, size >> 1)][Position::_index(offset.1, size >> 1)]; ((xy.0 - offset.0 + delta.0.0 * size, xy.1 - offset.1 + delta.0.1 * size), delta.1) }}
复制代码

在我们 server 工程的 Cargo.toml 里面加上一行:

share = { path = "../share"}
复制代码

使用的时候,use 一下:

use share::msg::{Position, Movement};
复制代码

这样,我们可以把所有客户端和服务器公用的代码放在 share 目录下面了。


注意看 刚才这行代码

#[derive(Debug, Serialize, Deserialize, Clone)]pub struct Position {
复制代码

我们将结构 Position 申明为,可以调试显示,可以序列化,可以反序列化以及可以克隆的。

我们需要用到一个 Rust 最常见的 序列化框架 Serde

use serde_derive::{Deserialize, Serialize};
复制代码

注意 Serde 只是申明了这个结构可以被序列化和反序列化,但是具体怎么序列化和反序列化,还是跟我们的格式有关。

比如说我们最常见的 json 格式来序列化和反序列化 Position

我们需要在 Cargo.toml 加上一行

serde_json = "1.0"

下面的序列化/反序列化代码:

    let p = Position{x: 10.0, y: 20.0};    let json_str = serde_json::to_string(&p).unwrap();    println!("{} -> {:?}", json_str, serde_json::from_str::<Position>(&json_str));
复制代码

执行的结果如下


发布于: 5 小时前阅读数: 67
用户头像

Miracle

关注

三十年资深码农 2019.10.25 加入

还未添加个人简介

评论 (1 条评论)

发布
用户头像
一如既往的简洁
1 小时前
回复
没有更多了
Rust 元宇宙 9 —— 库和序列化