1 个不稳定版本

0.1.2 2021 年 6 月 5 日
0.1.1 2021 年 6 月 5 日
0.1.0 2021 年 6 月 5 日

#740游戏开发

自定义许可证

175KB
1.5K SLoC

olc-pge

这是 olcPixelGameEngine 的一个非官方重实现。如果将来有 olcPixelGameEngine 的官方 Rust 版本,我会很高兴放弃这个包。

这是一个 olcPixelGameEngine 的派生作品,因此使用了 OLC-3 许可证。此许可证包含在源代码中的 LICENSE.md 文件以及本 Readme 文件的末尾。

缺少的功能

  • 真实文档
  • PGE 2.0 或更高版本中添加的任何内容
  • 资源包
  • 鼠标按钮超过 2 个
  • 全屏
  • 垂直同步
  • PixelMode::Custom 仅作为 PixelMode::Normal 使用
  • set_screen_size() 无作用
  • set_sub_pixel_offset() 无作用

新增功能

增加了对几乎所有 US 键盘上的键的支持,包括控制、shift、alt 和 windows 键的左右版本。我添加了这些,因为我想尝试制作一个文本编辑器,并且需要更多的键。

Return 键是大多数人称为 enter 的键。而 Enter 键既是 Return 键也是 NumPadEnter 键。类似于 Shift 既是 LeftShift 也是 RightShift

目前,由于我尚未解释的原因,alt 和 F10 无法捕获。这似乎是 minifb 的限制。这可能是 Windows 的限制。我仍在调查。

Windows 键也无法捕获,但没关系,我并不真的期望能够捕获,但它在枚举中作为 SystemLeftSystemRightSystem 中的 available。也许它们在 Linux 或 Mac 上工作?谁知道?不是我知道的。

我也没有添加 F13-F24。我敢肯定你们中没有人真的需要它们,你们大多数人甚至不知道它们的存在,而 minifb 只支持到 F15

平台

理论上,它支持 imageminifb 所支持的所有功能,但仅在 Windows 上进行了测试。如果在其他平台上不起作用,请告诉我。我会至少尝试修复它,如果您能提供修复方案,那将节省我的精力。

基本用法

以下是使用 Rust 编写的 PGE 示例程序的全部内容。

use olc_pge as olc;

use rand::Rng;

pub struct Example;

impl olc::PGEApplication for Example {
    const APP_NAME: &'static str = "Example - Rust";

    fn on_user_update(&mut self, pge: &mut olc::PixelGameEngine, _: f32) -> bool {
        let mut rng = rand::thread_rng();

        for x in 0..pge.screen_width() as i32 {
            for y in 0..pge.screen_height() as i32 {
                pge.draw(x, y, olc::Pixel::rgb(rng.gen(), rng.gen(), rng.gen()));
            }
        }

        true
    }
}

fn main() {
    olc::PixelGameEngine::construct(Example, 256, 240, 4, 4).start();
}

您只需为某些 struct 实现 PGEApplication,然后您就基本完成了。只有 APP_NAMEon_user_update() 是必需的,但您仍然可以访问 on_user_create()on_user_destroy()

PGEApplication 的完整定义如下

pub trait PGEApplication {
    const APP_NAME: &'static str;
    fn on_user_create(&mut self, pge: &mut PixelGameEngine) -> bool { true }
    fn on_user_update(&mut self, pge: &mut PixelGameEngine, elapsed_time: f32) -> bool;
    fn on_user_destroy(&mut self) -> bool { true }
}

您通常会调用的所有函数,例如 DrawSprite(),现在都封装在通过 pge 访问的 PixelGameEngine 中。除了这一点,以及习惯使用 Rust 而不是 C++,这应该是一个相对直接的经历。除了下一节中的有趣部分。

为了适应 Rust 而做的更改

函数重载/默认参数

实际上,没有这个功能。Rust 不支持这一点。支持可选 scalepatternmask,并且可以处理向量或单个组件的绘图函数现在有多个函数。

void DrawLine(int32_t x1, int32_t y1, int32_t x2, int32_t y2, Pixel p = olc::WHITE, uint32_t pattern = 0xFFFFFFFF);

这一行变成了以下 4 个函数

fn draw_line(&mut self, x1: i32, y1: i32, x2: i32, y2: i32, p: Pixel);
fn draw_line_pattern(&mut self, x1: i32, y1: i32, x2: i32, y2: i32, p: Pixel, pattern: u32);

fn draw_line_v(&mut self, pos1: Vi2d, pos2: Vi2d, p: Pixel);
fn draw_line_pattern_v(&mut self, pos1: Vi2d, pos2: Vi2d, p: Pixel, pattern: u32);

这不是很棒吗?

精灵

最明显的变化将是精灵的更改。原来接收 Sprite * 的每个函数现在都接收 SpriteRef。这是因为原始指针是不安全的,在 Rust 中除非您非常清楚您将要做什么,否则不应该使用。我不知道我将要做什么,更重要的是,我不知道您将要做些什么。理论上,SpriteRef 是很好且安全的。

要创建一个 SpriteRef,请在新创建的精灵上调用 into_ref()。要将一个传递给函数,您需要调用它的 clone()

以下是一个示例

let sprite = olc::Sprite::from_file("path/to/file.png").into_ref();
pge.draw_sprite(0, 0, sprite.clone());

定义了一个 SpriteRef,它被定义为 Rc<RefCell<Sprite>>。对于不熟悉的人来说,一个 Rc<> 给你一个引用计数、不可变 的引用。因为 Rc<> 只能是不可变的,而且我相信有些人希望在运行时编辑精灵,因此我们需要 RefCell<>。这些小巧的结构提供了 内部可变性。这可以说是一个复杂的说法,意思是可以获取到一个不可变对象内部的可变引用。一个 RefCell<> 具有一个重要的特性,它在运行时强制执行 Rust 的借用规则。也就是说,你可以有 1 个可变引用 或者 多个不可变引用。不能两者兼得。

要通过 SpriteRef 做任何事情,你必须首先显式地借用它

let immutable_ref = sprite.borrow();
// These cannot actually coexist and must be in different scopes
let mutable_ref = sprite.borrow_mut();

绘图目标

原始的 C++ API 允许你随意将任何旧的 Sprite* 放入其中,然后就可以比赛了。如上所述,这里不能这样做。它还允许使用 null 作为目标以返回默认目标。我并不真正知道为什么,但我尽量保持了类似的功能。对于 set_draw_target() 的参数是一个 Option<SpriteRef>

// to set a custom draw target
pge.set_draw_target(Some(sprite.clone());
// to go back to the default
pge.set_draw_target(None);

许可 (OLC-3)

版权所有 2018-2021 OneLoneCoder.com

在满足以下条件的情况下,允许重新分配和使用源代码和二进制形式,无论是否修改:

  1. 源代码的重新分配或衍生产物必须保留上述版权声明、本条件列表和以下免责声明。

  2. 二进制形式的重新分配或衍生产物必须复制上述版权声明。本条件列表和以下免责声明必须复制在提供分发的文档和其他材料中。

  3. 未经事先书面许可,不得使用版权所有者的名称或其贡献者的名称来推广或认可由此软件派生出来的产品。

本软件由版权所有者和贡献者提供,“现状”和“按原样”提供,并不附带任何明示或暗示的保证,包括但不限于适销性和针对特定目的的适用性保证。在任何情况下,版权所有者或贡献者均不对任何直接、间接、偶然、特殊、示范性或后续的损害(包括但不限于替代商品或服务的采购;使用、数据或利润的损失;或业务中断)承担责任,无论此类损害是由于何种原因引起的,无论是在合同、严格责任还是侵权(包括疏忽或其他),即使已告知此类损害的可能性。

依赖项

~14MB
~72K SLoC