36 个版本

0.2.0-beta.52024 年 7 月 8 日
0.2.0-beta.22024 年 3 月 25 日
0.1.45 2023 年 12 月 16 日
0.1.42 2023 年 11 月 12 日
0.1.17 2022 年 10 月 14 日

#102 in 游戏开发

Download history • Rust 包仓库 62/week @ 2024-05-04 • Rust 包仓库 17/week @ 2024-05-11 • Rust 包仓库 86/week @ 2024-05-18 • Rust 包仓库 3/week @ 2024-05-25 • Rust 包仓库 1/week @ 2024-06-01 • Rust 包仓库 103/week @ 2024-06-29 • Rust 包仓库 103/week @ 2024-07-06 • Rust 包仓库 10/week @ 2024-07-13 • Rust 包仓库 198/week @ 2024-07-27 • Rust 包仓库

217 每月下载量

MIT 许可证

86KB
2K SLoC

devotee

简约可视化项目。

使用 devotee

创建应用程序

Devotee 应用程序由 Root 实现和 Backend 系统表示。

Root 实现

Root 实现者必须选择所需的输入系统、像素数据转换器和渲染表面。它还必须实现 updaterenderconverter 方法。

简约的 Root 实现可能如下所示

struct Minimal;

impl Root for Minimal {
    type Input = NoInput;
    type Converter = BlackWhiteConverter;
    type RenderSurface = Canvas<bool>;

    fn update(&mut self, _: AppContext<Self::Input>) {}

    fn render(&self, _: &mut Self::RenderSurface) {}

    fn converter(&self) -> Self::Converter {
        BlackWhiteConverter
    }
}

这个 Root 实现

  • 使用 NoInput 作为输入系统;
  • 依赖于 BlackWhiteConverter(实现将在后面讨论)来转换 RenderSurface 的数据;
  • 使用具有 bool 像素的 Canvas 作为 RenderSurface
  • update 期间不做任何事情;
  • render 期间不绘制任何内容;
  • 返回 BlackWhiteConverter 实例以进行数据转换;

示例 BlackWhiteConverter 实现如下

struct BlackWhiteConverter;

impl Converter for BlackWhiteConverter {
    type Data = bool;

    fn convert(&self, _x: usize, _y: usize, data: Self::Data) -> u32 {
        if data {0xffffffff} else {0xff000000}
    }
}

它忽略像素的 xy 坐标,并根据 data 值返回纯白或纯黑。

后端使用

因此,当 Root 被实现后,是时候使用某些后端来启动它了。

对于这个例子,我们将依赖于基于 Softbuffer 的后端 实现

fn main() -> Result<(), Error> {
    let backend = SoftBackend::try_new("minimal")?;
    backend.run(
        App::new(Minimal),
        SoftMiddleware::new(Canvas::with_resolution(false, 128, 128), NoInput),
        Duration::from_secs_f32(1.0 / 60.0),
    )
}

更新应用程序状态

考虑 Extended 实现 Root

struct Extended {
    counter: f32,
}

让它使用 Keyboard 作为输入。当按下 Escape 按钮时关闭。它还计算经过的模拟时间 counter

因此,其实施的第一部分看起来像这样

impl Root for Extended {
    type Input = Keyboard;
    type Converter = BlackWhiteConverter;
    type RenderSurface = Canvas<bool>;

    fn update(&mut self, mut context: devotee::app::AppContext<Self::Input>) {
        if context.input().just_pressed(KeyCode::Escape) {
            context.shutdown();
        }

        self.counter += context.delta().as_secs_f32();
    }

    // ...
}

在渲染过程中,它会清理渲染表面,计算表面中心,并使用painter绘制两个填充的圆。Painter实例接受函数作为参数,而不是纯颜色。该函数根据像素的坐标决定对该像素进行什么操作。paint是一个预定义的函数,用于覆盖任何原始值。

请注意,存在两种painter的实现:一种用于i32坐标,另一种(亚像素)用于f32坐标。

    //. ..
    fn render(&self, surface: &mut Self::RenderSurface) {
        surface.clear(false);
        let center = surface.dimensions().map(|a| a as f32) / 2.0;

        let mut painter = surface.painter();
        let radius = 48.0 + 16.0 * self.counter.sin();

        painter.circle_f(center, radius, paint(true));
        painter.circle_f(center, radius / 2.0, |x, y, _| (x + y) % 2 == 0)
    }
    // ...

示例

examples文件夹中有一些示例。

许可证

devotee遵循MIT许可证。

依赖项

~0–35MB
~547K SLoC