#bevy #pixel-perfect #2d #gamedev #2d-game #2d-3d

bevy_retrograde

像素级,用于Bevy的2D渲染器和插件,无缝支持桌面和Web

3个版本 (破坏性)

0.2.0 2021年7月19日
0.1.0 2021年6月11日
0.0.0 2021年6月6日

#1076 in 游戏开发

自定义许可

495KB
2.5K SLoC

Bevy Retrograde

Crates.io Docs.rs Build Status lines of code Katharos License

( Bounty Bros. 游戏的截图,使用Bevy Retrograde和 Skip'n Go 制作)

bounty bros game screenshot

Bevy Retrograde是一个针对Bevy的2D,像素级渲染器,可以使用OpenGL/WebGL针对Web和桌面进行渲染。

Bevy Retrograde专注于提供一种简单且直观的方式编写2D,像素级游戏。与现成的Bevy设置相比,您不需要使用3D场景来创建2D游戏。精灵及其坐标基于复古分辨率场景中的像素位置。

Bevy Retrograde替换了您通常使用的许多现成的Bevy组件和Bundles(如 SpriteBundleCamera2DBundle 等),并提供自己的 CameraImageSprite 等组件和Bundles。Bevy Retrograde试图在Bevy之上提供一种专注于2D的体验,帮助避免一些陷阱,并使您在只需要2D时更容易思考游戏。

我们希望提供一个包含几乎所有您需要用Bevy制作2D像素游戏的插件的“全功能”插件,包括碰撞、声音、数据保存等。在添加这些功能时,我们将尝试保持完整的Web兼容性,但无法保证所有功能都适用于Web。

这些额外功能将以可选的cargo功能的形式包含,如果不需要,则可以禁用,并且,如果适用,还可以作为单独的Rust crate打包,即使您不想使用Bevy Retrograde的其余部分,也可以使用。

许可

Bevy Retrograde LDtk遵循Katharos License,该许可对您可以使用它的方式施加某些限制。请在使用Bevy Retrograde之前阅读并理解这些条款。

开发状态

Bevy Retrograde 处于早期开发阶段。API 不可稳定,可能随时发生重大变化。计划的可能变化包括

  • 将桌面/移动端的渲染器切换为使用 Bevy 内置的渲染器,以及使用 bevy_webgl2 而不是使用我们自己的基于 OpenGL 的渲染器。这将使 Bevy Retrograde 与更大的 Bevy 生态系统更具兼容性,而不是仅能在 Bevy Retro 上工作的插件孤岛。我们可能会等待 Bevy 渲染器的第二次迭代,以尝试这样做。

请参阅下面的 支持的 Bevy 版本

特性 & 示例

查看我们的 示例 列表,了解如何使用每个 Bevy Retrograde 特性

  • 开箱即支持网页和桌面
  • 精灵和精灵表
  • 使用三种相机模式(固定宽度、固定高度和字幕框)进行缩放像素完美渲染
  • 精灵默认以像素完美对齐,但可以设置为每个精灵不完美
  • LDtk 地图加载和渲染
  • RAUI UI 库集成,用于构建游戏用户界面和 HUD
  • HeronRapier 提供的物理和碰撞检测,可以从精灵图像自动生成凸碰撞形状
  • BDF 字体的文本渲染
  • 用于后处理的自定义着色器,包括内置的 CRT 着色器
  • 渲染钩子允许您降级到原始的 Luminance 调用来进行自定义渲染

支持的 Bevy 版本

Bevy Retrograde 目前适用于最新的 Bevy 版本,也可能支持 Bevy master。Bevy Retrograde 将尝试跟进最新的 Bevy 版本,但如果 Bevy master 中引入了我们需要的功能,我们可能需要在下一个 Bevy 版本发布前使用 Bevy master 的一段时间。

当依赖 bevy 包时,您必须确保在您的 Cargo.toml 中将 default-features 设置为 false,以便 bevy 中的渲染类型不会与 bevy_retrograde 中的类型冲突。

Cargo.toml:

bevy = { version = "0.5", default-features = false }
bevy_retrograde = "0.2.0"

示例

以下是一个快速示例,展示了使用 Bevy Retrograde 的样子

main.rs:

use bevy::prelude::*;
use bevy_retrograde::prelude::*;

fn main() {
    App::build()
        .add_plugins(RetroPlugins)
        .add_startup_system(setup.system())
        .run();
}

struct Player;

fn setup(
    mut commands: Commands,
    asset_server: Res<AssetServer>,
) {
    // Load our sprites
    let red_radish_image = asset_server.load("redRadish.png");
    let yellow_radish_image = asset_server.load("yellowRadish.png");
    let blue_radish_image = asset_server.load("blueRadish.png");

    // Spawn the camera
    commands.spawn().insert_bundle(CameraBundle {
        camera: Camera {
            // Set our camera to have a fixed height and an auto-resized width
            size: CameraSize::FixedHeight(100),
            background_color: Color::new(0.2, 0.2, 0.2, 1.0),
            ..Default::default()
        },
        ..Default::default()
    });

    // Spawn a red radish
    let red_radish = commands
        .spawn_bundle(SpriteBundle {
            image: red_radish_image,
            transform: Transform::from_xyz(0., 0., 0.),
            sprite: Sprite {
                flip_x: true,
                flip_y: false,
                ..Default::default()
            },
            ..Default::default()
        })
        // Add our player marker component so we can move it
        .insert(Player)
        .id();

    // Spawn a yellow radish
    let yellow_radish = commands
        .spawn_bundle(SpriteBundle {
            image: yellow_radish_image,
            transform: Transform::from_xyz(-20., 0., 0.),
            sprite: Sprite {
                // Flip the sprite upside down 🙃
                flip_y: true,
                // By setting a sprite to be non-pixel-perfect you can get smoother movement
                // for things like characters, like they did in Shovel Knight®.
                pixel_perfect: false,
                ..Default::default()
            },
            ..Default::default()
        })
        .id();

    // Make the yellow radish a child of the red radish
    commands.entity(red_radish).push_children(&[yellow_radish]);

    // Spawn a blue radish
    commands.spawn().insert_bundle(SpriteBundle {
        image: blue_radish_image,
        // Set the blue radish back a layer so that he shows up under the other two
        transform: Transform::from_xyz(-20., -20., -1.),
        sprite: Sprite {
            flip_x: true,
            flip_y: false,
            ..Default::default()
        },
        ..Default::default()
    });
}

依赖项

~38–52MB
~747K SLoC