Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update to Bevy 0.8 #8

Open
wants to merge 4 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
8 changes: 4 additions & 4 deletions Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,17 +1,17 @@
[package]
name = "bevy_ase"
version = "0.3.1"
version = "0.4.0"
authors = ["Bruce Reif", "alpine_alpaca <[email protected]>", ]
edition = "2021"

# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html

[dependencies]
bevy = "0.7"
bevy = "0.8"
asefile = "0.3.5"
anyhow = "1.0"
bevy_ecs_tilemap = { version = "0.6.0", optional = true }
benimator = { version = "3.5.0", optional = true}
bevy_ecs_tilemap = { version = "0.7.0", optional = true }
benimator = { version = "4.0.0-rc.1", optional = true}

[profile.dev.package."*"]
opt-level = 2
Expand Down
Binary file modified assets/sprites/hello.aseprite
Binary file not shown.
52 changes: 38 additions & 14 deletions examples/animated/main.rs
Original file line number Diff line number Diff line change
@@ -1,24 +1,29 @@
use std::path::Path;

use bevy::{input::system::exit_on_esc_system, prelude::*, sprite::SpriteSheetBundle};
use bevy::{prelude::*, reflect::TypeUuid, sprite::SpriteSheetBundle};
use bevy_ase::{
self,
asset::{Animation, AseAsset},
loader::{self, Loader},
};

#[derive(TypeUuid, Deref)]
#[uuid = "33fd3d9b-dd1e-4d38-9b82-30751b29c72c"]
pub struct SpriteSheetAnimation(benimator::Animation);

#[derive(Default, Component, Deref, DerefMut)]
pub struct SpriteSheetAnimationState(benimator::State);

fn main() {
App::new()
.add_plugins(DefaultPlugins)
.add_plugin(loader::AseLoaderDefaultPlugin)
.add_plugin(benimator::AnimationPlugin::default())
.add_system(exit_on_esc_system.system())
.add_asset::<SpriteSheetAnimation>()
.add_state(AppState::Loading)
.add_system_set(SystemSet::on_enter(AppState::Loading).with_system(load_sprites.system()))
.add_system_set(
SystemSet::on_update(AppState::Loading).with_system(check_loading_sprites.system()),
)
.add_system_set(SystemSet::on_enter(AppState::Game).with_system(spawn_sprites.system()))
.add_system_set(SystemSet::on_enter(AppState::Loading).with_system(load_sprites))
.add_system_set(SystemSet::on_update(AppState::Loading).with_system(check_loading_sprites))
.add_system_set(SystemSet::on_enter(AppState::Game).with_system(spawn_sprites))
.add_system_set(SystemSet::on_update(AppState::Game).with_system(animate))
.run()
}

Expand Down Expand Up @@ -47,20 +52,20 @@ pub fn check_loading_sprites(mut state: ResMut<State<AppState>>, ase_loader: Res
pub fn spawn_sprites(
mut commands: Commands,
animations: Res<Assets<Animation>>,
mut sprite_sheet_animations: ResMut<Assets<benimator::SpriteSheetAnimation>>,
mut sprite_sheet_animations: ResMut<Assets<SpriteSheetAnimation>>,
) {
commands.spawn_bundle({
let mut b = OrthographicCameraBundle::new_2d();
b.orthographic_projection.scale = 1.0 / 3.0; // scale to 3x
let mut b = Camera2dBundle::default();
b.projection.scale = 1.0 / 3.0; // scale to 3x
b
});

let anims = animations.iter().enumerate();
for (idx, (_id, anim)) in anims {
let texture_atlas = anim.atlas();
// The "benimator" feature provides a From implementation to convert animations.
let anim: benimator::SpriteSheetAnimation = anim.into();
let anim_handle = sprite_sheet_animations.add(anim);
let anim: benimator::Animation = anim.into();
let anim_handle = sprite_sheet_animations.add(SpriteSheetAnimation(anim));
let x_position = idx as f32 * 50.0;

commands
Expand All @@ -70,6 +75,25 @@ pub fn spawn_sprites(
..Default::default()
})
.insert(anim_handle)
.insert(benimator::Play);
.insert(SpriteSheetAnimationState::default());
}
}

pub fn animate(
time: Res<Time>,
animations: Res<Assets<SpriteSheetAnimation>>,
mut query: Query<(
&mut SpriteSheetAnimationState,
&mut TextureAtlasSprite,
&Handle<SpriteSheetAnimation>,
)>,
) {
for (mut state, mut texture, handle) in query.iter_mut() {
let animation = match animations.get(handle) {
Some(anim) => anim,
None => continue,
};
state.update(animation, time.delta());
texture.index = state.frame_index();
}
}
69 changes: 31 additions & 38 deletions examples/tilemap/main.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::path::Path;

use bevy::{input::system::exit_on_esc_system, prelude::*};
use bevy::prelude::*;
use bevy_ase::{
self,
asset::{AseAsset, Tileset},
Expand All @@ -14,14 +14,11 @@ fn main() {
.add_plugins(DefaultPlugins)
.add_plugin(TilemapPlugin)
.add_plugin(loader::AseLoaderDefaultPlugin)
.add_system(exit_on_esc_system.system())
.add_state(AppState::Loading)
.add_system_set(SystemSet::on_enter(AppState::Loading).with_system(load_sprites.system()))
.add_system_set(
SystemSet::on_update(AppState::Loading).with_system(check_loading_sprites.system()),
)
.add_system_set(SystemSet::on_enter(AppState::Game).with_system(spawn_camera.system()))
.add_system_set(SystemSet::on_enter(AppState::Game).with_system(spawn_tiles.system()))
.add_system_set(SystemSet::on_enter(AppState::Loading).with_system(load_sprites))
.add_system_set(SystemSet::on_update(AppState::Loading).with_system(check_loading_sprites))
.add_system_set(SystemSet::on_enter(AppState::Game).with_system(spawn_camera))
.add_system_set(SystemSet::on_enter(AppState::Game).with_system(spawn_tiles))
.run()
}

Expand All @@ -48,52 +45,48 @@ pub fn check_loading_sprites(mut state: ResMut<State<AppState>>, aseloader: Res<

fn spawn_camera(mut commands: Commands) {
commands.spawn_bundle({
let mut b = OrthographicCameraBundle::new_2d();
b.orthographic_projection.scale = 1.0 / 3.0; // scale to 3x
let mut b = Camera2dBundle::default();
b.projection.scale = 1.0 / 3.0; // scale to 3x
b
});
}

fn set_tiles(layer_builder: &mut LayerBuilder<TileBundle>) {
fn set_tiles(commands: &mut Commands, map_entity: Entity, tile_storage: &mut TileStorage) {
for y in 0..3 {
let y_offset = 7 - (y * 3);
for x in 0..3 {
let texture_index = y_offset + x;
let tile = Tile {
texture_index,
..Tile::default()
};
let tile_pos = UVec2::new(x as u32, y as u32);
layer_builder.set_tile(tile_pos, tile.into()).unwrap();
let tile_pos = TilePos::new(x as u32, y as u32);
let tile = commands
.spawn_bundle(TileBundle {
position: tile_pos,
tilemap_id: TilemapId(map_entity),
texture: TileTexture(texture_index),
..TileBundle::default()
})
.id();
tile_storage.set(&tile_pos, Some(tile));
}
}
}

fn spawn_tiles(
mut commands: Commands,
tilesets: Res<Assets<Tileset>>,
mut materials: ResMut<Assets<ColorMaterial>>,
mut map_query: MapQuery,
) {
fn spawn_tiles(mut commands: Commands, tilesets: Res<Assets<Tileset>>) {
for (_, tileset) in tilesets.iter() {
let texture_handle = tileset.texture.clone();
let material_handle = materials.add(ColorMaterial::texture(texture_handle));
// The layer_settings method of Tileset is implemented in the "bevy_ecs_tilemap" feature.
let settings = tileset.layer_settings(UVec2::new(3, 3), UVec2::new(3, 3));

let (mut layer_builder, layer_entity) =
LayerBuilder::<TileBundle>::new(&mut commands, settings, 0u16, 0u16);

set_tiles(&mut layer_builder);
let map_size = TilemapSize { x: 3, y: 3 };
let map_entity = commands.spawn().id();
let mut tile_storage = TileStorage::empty(map_size);

map_query.build_layer(&mut commands, layer_builder, material_handle);
set_tiles(&mut commands, map_entity, &mut tile_storage);

let map_entity = commands.spawn().id();
let mut map = Map::new(0u16, map_entity);
map.add_layer(&mut commands, 0u16, layer_entity);
commands
.entity(map_entity)
.insert(map)
.insert(GlobalTransform::default());
commands.entity(map_entity).insert_bundle(TilemapBundle {
grid_size: (&tileset.tile_size).into(),
size: map_size,
storage: tile_storage,
texture: TilemapTexture(texture_handle),
tile_size: (&tileset.tile_size).into(),
..Default::default()
});
}
}
6 changes: 3 additions & 3 deletions src/benimator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ impl From<&Frame> for benimator::Frame {
)
}
}
impl From<&Animation> for benimator::SpriteSheetAnimation {
impl From<&Animation> for benimator::Animation {
fn from(a: &Animation) -> Self {
let frames = a.frames().iter().map(|f| f.into()).collect();
benimator::SpriteSheetAnimation::from_frames(frames)
let frames = a.frames().iter().map(|f| f.into());
benimator::Animation::from_frames(frames)
}
}
44 changes: 17 additions & 27 deletions src/bevy_ecs_tilemap.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
use crate::asset::{TileSize, Tileset};
use bevy::math::{UVec2, Vec2};
use crate::asset::TileSize;
use bevy::math::Vec2;
use bevy_ecs_tilemap::prelude::*;

impl From<TileSize> for Vec2 {
Expand All @@ -8,30 +8,20 @@ impl From<TileSize> for Vec2 {
}
}

impl Tileset {
/// Creates new [LayerSettings] using the [Tileset's](Tileset) own tile size and texture size.
///
/// # Examples
///
/// ```
/// #[cfg(feature = "bevy_ecs_tilemap")]
/// use bevy_ase::asset::Tileset;
/// use bevy_ecs_tilemap::LayerSettings;
/// use bevy::math::UVec2;
///
/// // Create new layer settings from a tileset, with specified map size and chunk size.
/// fn my_layer_settings(tileset: &Tileset) -> LayerSettings {
/// let map_size = UVec2::new(30, 30);
/// let chunk_size = UVec2::new(15, 15);
/// tileset.layer_settings(map_size, chunk_size)
/// }
/// ```
pub fn layer_settings(&self, map_size: UVec2, chunk_size: UVec2) -> LayerSettings {
LayerSettings::new(
map_size,
chunk_size,
Vec2::new(self.tile_size.width as f32, self.tile_size.height as f32),
self.texture_size(),
)
impl From<&TileSize> for TilemapTileSize {
fn from(tile_size: &TileSize) -> Self {
Self {
x: tile_size.width as f32,
y: tile_size.height as f32,
}
}
}

impl From<&TileSize> for TilemapGridSize {
fn from(tile_size: &TileSize) -> Self {
Self {
x: tile_size.width as f32,
y: tile_size.height as f32,
}
}
}
4 changes: 2 additions & 2 deletions src/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -212,7 +212,7 @@ impl Loader {
let mut ase_files: Vec<(PathBuf, AsepriteFile)> = Vec::with_capacity(handles.len());
for h in &handles {
let ase_asset = aseprites
.get_mut(h.clone_weak())
.get_mut(&h)
.expect("Failed to get aseprite from handle");

// We actually remove the AsepriteFile from the AsepriteAsset so
Expand Down Expand Up @@ -290,7 +290,6 @@ pub(crate) type AseAssetResources<'a> = (
/// ```
pub fn ase_importer(
mut loader: ResMut<Loader>,
task_pool: ResMut<AsyncComputeTaskPool>,
mut aseassets: ResMut<Assets<AseAsset>>,
asset_server: Res<AssetServer>,
resources: AseAssetResources,
Expand All @@ -300,6 +299,7 @@ pub fn ase_importer(
debug!("Processing asefiles (batches: {})", pending);
}
if loader.all_todo_handles_ready(&asset_server) {
let task_pool = AsyncComputeTaskPool::get();
loader.spawn_tasks(&task_pool, &mut aseassets);
}
loader.move_finished_into_resources(resources);
Expand Down
6 changes: 6 additions & 0 deletions src/processing.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use crate::{
handle_id,
};
use asefile::AsepriteFile;
use bevy::render::texture::ImageSampler;
use bevy::sprite::TextureAtlasBuilder;
use bevy::{prelude::*, utils::HashMap};
use std::path::{Path, PathBuf};
Expand Down Expand Up @@ -150,6 +151,11 @@ fn move_sprites(
let atlas = texture_atlas_builder
.finish(images)
.expect("Creating texture atlas failed");
// Since we likely are dealing with pixel art, default to nearest image sampling
images
.get_mut(&atlas.texture)
.expect("Texture atlas texture missing")
.sampler_descriptor = ImageSampler::nearest();
let atlas_handle_id = handle_id::atlas(path);
let atlas_handle = atlases.set(atlas_handle_id, atlas);
file_assets.insert_atlas(atlas_handle.clone());
Expand Down