Skip to content

Commit

Permalink
Render framed images based on offset and size
Browse files Browse the repository at this point in the history
  • Loading branch information
marcotoniut committed Sep 22, 2024
1 parent 9872fbe commit cef3895
Show file tree
Hide file tree
Showing 8 changed files with 762 additions and 12 deletions.
Binary file added assets/frame/runner.px_frame.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
14 changes: 14 additions & 0 deletions assets/frame/runner.px_frame.png.meta
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
(
meta_format_version: "1.0",
asset: Load(
loader: "seldom_pixel::frame::PxFrameLoader",
settings: (
image_loader_settings: (
format: FromExtension,
is_srgb: true,
sampler: Default,
asset_usage: ("MAIN_WORLD | RENDER_WORLD"),
),
),
),
)
46 changes: 46 additions & 0 deletions examples/frame.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
// In this program, two frames are spawned

use bevy::prelude::*;
use seldom_pixel::{frame::PxFrameBundle, prelude::*};

fn main() {
App::new()
.add_plugins((
DefaultPlugins.set(WindowPlugin {
primary_window: Some(Window {
resolution: Vec2::new(512., 384.).into(),
..default()
}),
..default()
}),
PxPlugin::<Layer>::new(UVec2::new(32, 24), "palette/palette_1.palette.png"),
))
.insert_resource(ClearColor(Color::BLACK))
.add_systems(Startup, init)
.run();
}

fn init(assets: Res<AssetServer>, mut commands: Commands) {
commands.spawn(Camera2dBundle::default());

commands.spawn(PxFrameBundle::<Layer> {
frame: assets.load("frame/runner.px_frame.png"),
offset: UVec2::new(2, 0).into(),
size: UVec2::new(10, 15).into(),
position: IVec2::new(1, 1).into(),
anchor: PxAnchor::BottomLeft,
..default()
});

commands.spawn(PxFrameBundle::<Layer> {
frame: assets.load("frame/runner.px_frame.png"),
offset: UVec2::new(0, 18).into(),
size: UVec2::new(11, 16).into(),
position: IVec2::new(24, 20).into(),
anchor: PxAnchor::TopCenter,
..default()
});
}

#[px_layer]
struct Layer;
49 changes: 48 additions & 1 deletion src/animation.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use std::time::Duration;
use bevy::render::extract_resource::{ExtractResource, ExtractResourcePlugin};
use bevy::utils::Instant;

use crate::position::Spatial;
use crate::position::{PxOffset, PxSize, Spatial};
use crate::{
image::{PxImage, PxImageSliceMut},
pixel::Pixel,
Expand Down Expand Up @@ -135,6 +135,19 @@ pub(crate) trait Animation {
);
}

pub(crate) trait Drawable {
type Param;

fn draw(
&self,
param: Self::Param,
image: &mut PxImageSliceMut<impl Pixel>,
offset: UVec2,
size: UVec2,
filter: impl Fn(u8) -> u8,
);
}

pub(crate) trait AnimationAsset: Asset {
fn max_frame_count(&self) -> usize;
}
Expand Down Expand Up @@ -259,6 +272,40 @@ pub(crate) fn draw_animation<'a, A: Animation>(
}
}

pub(crate) fn draw_frame<'a, D: Drawable>(
drawable: &D,
param: <D as Drawable>::Param,
image: &mut PxImage<impl Pixel>,
position: PxPosition,
PxOffset(offset): PxOffset,
PxSize(size): PxSize,
anchor: PxAnchor,
canvas: PxCanvas,
filters: impl IntoIterator<Item = &'a PxFilter>,
camera: PxCamera,
) {
// let size = spatial.frame_size();
let position = *position - anchor.pos(size).as_ivec2();
let position = match canvas {
PxCanvas::World => position - *camera,
PxCanvas::Camera => position,
};

let mut image_slice = image.slice_mut(IRect {
min: position,
max: position + size.as_ivec2(),
});

let mut filter: Box<dyn Fn(u8) -> u8> = Box::new(|pixel| pixel);
for filter_part in filters {
let filter_part = filter_part.as_fn();
filter = Box::new(move |pixel| filter_part(filter(pixel)));
}

// drawable.draw(param, &mut image_slice, |_| 0, filter);
drawable.draw(param, &mut image_slice, offset, size, filter);
}

pub(crate) fn draw_spatial<'a, A: Animation + Spatial>(
spatial: &A,
param: <A as Animation>::Param,
Expand Down
Loading

0 comments on commit cef3895

Please sign in to comment.