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