bevy_pixel_camera

repository·main·Indexed 41 days ago

https://github.com/drakmaniso/bevy_pixel_camera

A pixel-perfect camera plugin for Bevy 0.13.0 designed for pixel-art rendering. It manages integer scaling and viewport resizing automatically using components like PixelZoom and PixelViewport to ensure crisp pixels and consistent target resolutions without rendering to an offscreen texture.

Tokens
3.6K
Snippets
10
Records
19
Agent score
99%

What's inside bevy_pixel_camera

  1. How `bevy_pixel_camera` works

    main

    The bevy_pixel_camera plugin facilitates pixel-art rendering by automatically configuring Bevy's Camera2dBundle. It uses an "upscale each sprite independently" approach rather than rendering to an offscreen texture.

    Key behaviors include:

    • Setting the camera to an integer scaling factor using Bevy's ScalingMode::WindowSize.
    • Automatically updating the zoom level so the specified target resolution fills as much of the screen as possible.
    • Optionally setting and resizing the camera viewport to match the target resolution.

    This method allows for smoother movement and easier mixing of pixel-art with high-resolution elements (like text or particles), though it may sacrifice the perfect pixel alignment found in offscreen texture methods.

  2. Migrate from `PixelCameraBundle` to `Camera2dBundle` (Bevy 0.11 to 0.12)

    main

    In versions compatible with Bevy 0.12, PixelCameraBundle is deprecated.

    Action: Replace PixelCameraBundle with a standard Camera2dBundle and manually add the PixelZoom and PixelViewport components to it.

  3. Set up `bevy_pixel_camera` for pixel-art rendering

    main

    To use bevy_pixel_camera, you must perform three main steps:

    1. Configure Texture Sampling: Bevy uses linear sampling by default, which blurs pixel art. You must configure DefaultPlugins with ImagePlugin::default_nearest() to ensure crisp pixels.
    2. Add Plugins: Add PixelCameraPlugin to your App.
    3. Configure the Camera: Spawn a Camera2dBundle and attach the PixelZoom and PixelViewport components.

    Note on Sprite Alignment: If a sprite's width or height is not divisible by 2, you may need to change its Anchor (the default is Anchor::Center) to ensure it aligns correctly with virtual pixels.

    use bevy::prelude::*;
    use bevy::sprite::Anchor;
    use bevy_pixel_camera::{
        PixelCameraPlugin, PixelZoom, PixelViewport
    };
    
    fn main() {
        App::new()
            .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
            .add_plugins(PixelCameraPlugin)
            .add_systems(Startup, setup)
            .run();
    }
    
    fn setup(
        mut commands: Commands,
        asset_server: Res<AssetServer>,
    ) {
        // Spawn the pixel camera
        commands.spawn((
            Camera2dBundle::default(),
            PixelZoom::FitSize {
                width: 320,
                height: 180,
            },
            PixelViewport,
        ));
    
        // Spawn a sprite with a specific anchor to ensure alignment
        commands.spawn(SpriteBundle {
            texture: asset_server.load("my-pixel-art-sprite.png"),
            sprite: Sprite {
                anchor: Anchor::BottomLeft,
                ..Default::default()
            },
            ..Default::default()
        });
    }
  4. How to use bevy_pixel_camera for pixel-art games

    main

    To use bevy_pixel_camera, you should configure Bevy's DefaultPlugins to use nearest-neighbor sampling for textures to avoid blurring pixel art. You then add the PixelCameraPlugin to your app.

    To set up a pixel-perfect camera, spawn a Camera2dBundle and attach the PixelZoom and PixelViewport components. PixelZoom determines how the target resolution is scaled to fit the screen, and PixelViewport ensures the viewport matches the target resolution.

    Important Note on Sprite Alignment: If a sprite's width or height is not divisible by 2, you may need to change its Anchor (which defaults to Center) to ensure it aligns correctly with virtual pixels.

    use bevy::prelude::*;
    use bevy::sprite::Anchor;
    use bevy_pixel_camera::*;
    
    fn main() {
        App::new()
            .add_plugins(DefaultPlugins.set(ImagePlugin::default_nearest()))
            .add_plugins(PixelCameraPlugin)
            .add_systems(Startup, setup)
            .run();
    }
    
    fn setup(
        mut commands: Commands,
        asset_server: Res<AssetServer>,
    ) {
        commands.spawn((
            Camera2dBundle::default(),
            PixelZoom::FitSize {
                width: 320,
                height: 180,
            },
            PixelViewport,
        ));
    
        commands.spawn(SpriteBundle {
            texture: asset_server.load("my-pixel-art-sprite.png"),
            sprite: Sprite {
                anchor: Anchor::BottomLeft,
                ..Default::default()
            },
            ..Default::default()
        });
    }
  5. Add pixel camera functionality using PixelCameraPlugin

    main

    To enable pixel-perfect camera behavior in your Bevy application, add the PixelCameraPlugin to your App during setup. This plugin registers the necessary types and systems to handle PixelProjection, including viewport updates and zoom systems, within the PostUpdate schedule.

    use bevy::prelude::App;
    use bevy_pixel_camera::PixelCameraPlugin;
    
    fn main() {
        App::new()
            .add_plugins(DefaultPlugins)
            .add_plugins(PixelCameraPlugin)
            // ... rest of your app
            .run();
    }
  6. Use `PixelZoom` and `PixelViewport` components

    main

    When spawning your camera, use these components to control how the pixel resolution is handled:

    • PixelZoom::FitSize { width, height }: Sets the target virtual resolution. The camera will automatically adjust zoom to fit this size into the window.
    • PixelViewport: Tells the plugin to automatically set and resize the camera's viewport to match the target resolution defined in PixelZoom.
    commands.spawn((
        Camera2dBundle::default(),
        PixelZoom::FitSize {
            width: 320,
            height: 180,
        },
        PixelViewport,
    ));
  7. Use `set_viewport` instead of `PixelBorderPlugin`

    main

    The PixelBorderPlugin is deprecated as of version 0.5.0. To achieve a similar effect of providing an opaque border around your desired resolution, you should use the set_viewport flag on your camera instead of using this plugin.

    If you are using an older version of bevy_pixel_camera (pre-0.5.0), you can use PixelBorderPlugin to spawn an opaque border around the resolution defined by your PixelProjection.

  8. Configure `PixelBorderPlugin` for opaque borders

    main

    If you are on a version prior to 0.5.0, you can use PixelBorderPlugin to add an opaque border around your pixel-art resolution. The plugin requires a color field to define the border's color and automatically handles spawning and resizing the border entities to match your PixelProjection dimensions.

    use bevy_pixel_camera::PixelBorderPlugin;
    use bevy::prelude::Color;
    
    // In your App setup
    app.add_plugins(PixelBorderPlugin {
        color: Color::BLACK,
    });