Make sprite texture atlas more generic
This commit is contained in:
parent
b9d0398157
commit
d1aee610cc
|
@ -43,7 +43,7 @@ impl SpriteAnimation {
|
|||
let mut frames = vec![]; //Vec::with_capacity(sprites.len());
|
||||
|
||||
for i in sprites {
|
||||
let r = atlas.index_rect(i);
|
||||
let r = atlas.frames.get(i as usize).cloned().unwrap();
|
||||
frames.push(r);
|
||||
}
|
||||
|
||||
|
|
|
@ -1,72 +1,43 @@
|
|||
use glam::{UVec2, Vec3};
|
||||
use glam::UVec2;
|
||||
use lyra_ecs::Component;
|
||||
use lyra_math::URect;
|
||||
use lyra_reflect::Reflect;
|
||||
use lyra_resource::ResHandle;
|
||||
|
||||
use super::Pivot;
|
||||
|
||||
/// A texture atlas of multiple sprites.
|
||||
#[derive(Clone, Component, Reflect)]
|
||||
pub struct TextureAtlas {
|
||||
pub texture: ResHandle<lyra_resource::Image>,
|
||||
/// The coordinates in the texture where the grid starts.
|
||||
pub grid_offset: UVec2,
|
||||
/// The size of the grid in cells.
|
||||
pub grid_size: UVec2,
|
||||
/// The size of each cell.
|
||||
pub cell_size: UVec2,
|
||||
|
||||
pub sprite_color: Vec3,
|
||||
pub pivot: Pivot,
|
||||
pub frames: Vec<URect>,
|
||||
}
|
||||
|
||||
impl TextureAtlas {
|
||||
/// The cell x and y in the grid of a specific index.
|
||||
pub fn index_cell(&self, i: u32) -> UVec2 {
|
||||
let x = i % self.grid_size.x;
|
||||
let y = i / self.grid_size.x;
|
||||
UVec2 { x, y }
|
||||
}
|
||||
|
||||
/// The coords of the cell at x and y in the grid.
|
||||
/// Create a texture atlas with rectangles of a grid.
|
||||
///
|
||||
/// The indices are different then the image coords, this is the position in the grid.
|
||||
/// So if you have a 9x7 grid, and wanted to get the 1nd cell on the 2nd row, you'd
|
||||
/// use the values `x = 0, y = 1` (indices start at zero like arrays).
|
||||
#[inline(always)]
|
||||
pub fn cell_coords(&self, x: u32, y: u32) -> UVec2 {
|
||||
UVec2 {
|
||||
x: x * self.cell_size.x,
|
||||
y: y * self.cell_size.y,
|
||||
/// Parameters:
|
||||
/// * `texture` - The asset handle of the texture to get the sprites from.
|
||||
/// * `grid_size` - The number of the cells in the grid (i.e., 9x7 grid).
|
||||
/// * `cell_size` - The dimensions of each cell in the grid (i.e., 100x100 sprites).
|
||||
pub fn from_grid(
|
||||
texture: ResHandle<lyra_resource::Image>,
|
||||
grid_size: UVec2,
|
||||
cell_size: UVec2,
|
||||
) -> Self {
|
||||
let mut frames = vec![];
|
||||
|
||||
for y in 0..grid_size.y {
|
||||
for x in 0..grid_size.x {
|
||||
let r = URect::new(
|
||||
cell_size.x * x,
|
||||
cell_size.y * y,
|
||||
cell_size.x * (x + 1),
|
||||
cell_size.y * (y + 1),
|
||||
);
|
||||
frames.push(r);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// The coords of the cell at an index.
|
||||
#[inline(always)]
|
||||
pub fn index_coords(&self, i: u32) -> UVec2 {
|
||||
let cell = self.index_cell(i);
|
||||
|
||||
self.cell_coords(cell.x, cell.y)
|
||||
}
|
||||
|
||||
/// The rectangle of the cell at the x and y indices in the grid.
|
||||
///
|
||||
/// The indices are different then the image coords, this is the position in the grid.
|
||||
/// So if you have a 9x7 grid, and wanted to get the 1nd cell on the 2nd row, you'd
|
||||
/// use the values `x = 0, y = 1` (indices start at zero like arrays).
|
||||
#[inline(always)]
|
||||
pub fn cell_rect(&self, x: u32, y: u32) -> URect {
|
||||
let start = self.cell_coords(x, y);
|
||||
let end = start + self.cell_size;
|
||||
URect { min: start, max: end }
|
||||
}
|
||||
|
||||
/// The rectangle of the cell at an index.
|
||||
#[inline(always)]
|
||||
pub fn index_rect(&self, i: u32) -> URect {
|
||||
let cell = self.index_cell(i);
|
||||
self.cell_rect(cell.x, cell.y)
|
||||
Self { texture, frames }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -95,11 +66,11 @@ impl AtlasSprite {
|
|||
#[inline(always)]
|
||||
pub fn from_atlas_index(atlas: ResHandle<TextureAtlas>, i: u32) -> Self {
|
||||
let a = atlas.data_ref().unwrap();
|
||||
let rect = a.index_rect(i);
|
||||
let rect = a.frames.get(i as usize).cloned().unwrap(); //index_rect(i);
|
||||
|
||||
Self {
|
||||
atlas: atlas.clone(),
|
||||
sprite: rect,
|
||||
sprite: rect,
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,10 +1,22 @@
|
|||
use lyra_engine::{
|
||||
assets::{Image, ResourceManager}, ecs::query::{Res, ResMut, View}, game::App, gltf::Gltf, input::{
|
||||
assets::{Image, ResourceManager},
|
||||
ecs::query::{Res, ResMut, View},
|
||||
game::App,
|
||||
gltf::Gltf,
|
||||
input::{
|
||||
Action, ActionHandler, ActionKind, ActionMapping, ActionMappingId, ActionSource,
|
||||
InputActionPlugin, KeyCode, LayoutId,
|
||||
}, math::{self, Rect, Transform, URect, UVec2, Vec2, Vec3}, render::light::directional::DirectionalLight, scene::{
|
||||
system_update_world_transforms, Camera2dBundle, CameraProjection, OrthographicProjection, ScaleMode, TopDown2dCamera, TopDown2dCameraPlugin, WorldTransform, ACTLBL_LOOK_LEFT_RIGHT, ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD, ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN
|
||||
}, sprite::{self, AtlasAnimations, AtlasSprite, Pivot, Sprite, SpriteAnimation, TextureAtlas}, DeltaTime
|
||||
},
|
||||
math::{self, Rect, Transform, URect, UVec2, Vec2, Vec3},
|
||||
render::light::directional::DirectionalLight,
|
||||
scene::{
|
||||
system_update_world_transforms, Camera2dBundle, CameraProjection, OrthographicProjection,
|
||||
ScaleMode, TopDown2dCamera, TopDown2dCameraPlugin, WorldTransform, ACTLBL_LOOK_LEFT_RIGHT,
|
||||
ACTLBL_LOOK_ROLL, ACTLBL_LOOK_UP_DOWN, ACTLBL_MOVE_FORWARD_BACKWARD,
|
||||
ACTLBL_MOVE_LEFT_RIGHT, ACTLBL_MOVE_UP_DOWN,
|
||||
},
|
||||
sprite::{self, AtlasAnimations, AtlasSprite, Pivot, Sprite, SpriteAnimation, TextureAtlas},
|
||||
DeltaTime,
|
||||
};
|
||||
use tracing::debug;
|
||||
|
||||
|
@ -96,7 +108,11 @@ async fn main() {
|
|||
fn setup_scene_plugin(app: &mut App) {
|
||||
//app.add_resource(Timer(0.0));
|
||||
//app.with_system("sprite_change", sprite_change, &[]);
|
||||
app.with_system("sprite_atlas_animation", sprite::system_sprite_atlas_animation, &[]);
|
||||
app.with_system(
|
||||
"sprite_atlas_animation",
|
||||
sprite::system_sprite_atlas_animation,
|
||||
&[],
|
||||
);
|
||||
|
||||
let world = &mut app.world;
|
||||
let resman = world.get_resource_mut::<ResourceManager>().unwrap();
|
||||
|
@ -125,21 +141,19 @@ fn setup_scene_plugin(app: &mut App) {
|
|||
let image = resman.request::<Image>("../assets/Egg_item.png").unwrap();
|
||||
image.wait_recurse_dependencies_load().unwrap();
|
||||
|
||||
let soldier = resman.request::<Image>("../assets/tiny_rpg_characters/Characters(100x100)/Soldier/Soldier/Soldier.png").unwrap();
|
||||
let soldier = resman
|
||||
.request::<Image>(
|
||||
"../assets/tiny_rpg_characters/Characters(100x100)/Soldier/Soldier/Soldier.png",
|
||||
)
|
||||
.unwrap();
|
||||
soldier.wait_recurse_dependencies_load().unwrap();
|
||||
|
||||
let atlas = resman.store_new(TextureAtlas {
|
||||
texture: soldier,
|
||||
grid_offset: UVec2::ZERO,
|
||||
grid_size: UVec2::new(9, 7),
|
||||
cell_size: UVec2::new(100, 100),
|
||||
sprite_color: Vec3::ONE,
|
||||
pivot: Pivot::default(),
|
||||
});
|
||||
|
||||
let animations = AtlasAnimations::new(atlas, &[
|
||||
("soldier_run", 0.1, 9..=16),
|
||||
]);
|
||||
let atlas = resman.store_new(TextureAtlas::from_grid(
|
||||
soldier,
|
||||
UVec2::new(9, 7),
|
||||
UVec2::new(100, 100),
|
||||
));
|
||||
let animations = AtlasAnimations::new(atlas, &[("soldier_run", 0.1, 9..=16)]);
|
||||
let run_anim = animations.get_active("soldier_run");
|
||||
let animations = resman.store_new(animations);
|
||||
|
||||
|
@ -180,6 +194,6 @@ fn setup_scene_plugin(app: &mut App) {
|
|||
zoom_speed: Some(0.2),
|
||||
speed: 14.0,
|
||||
..Default::default()
|
||||
}
|
||||
},
|
||||
));
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue