diff --git a/assets/Martian Chess.blend b/assets/Martian Chess.blend index 1f05824..f582f8c 100644 --- a/assets/Martian Chess.blend +++ b/assets/Martian Chess.blend @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:e4202c0804f2fdf2f0539546f89a38970953e4a96d7bdf341b647e9271ab36b6 -size 2410456 +oid sha256:2ea8f157f041836cb978d78951ca2540d32f2049ad68524006293d0eb5802b31 +size 2921476 diff --git a/assets/Martian Chess.blend1 b/assets/Martian Chess.blend1 index 5d690e0..f44d907 100644 --- a/assets/Martian Chess.blend1 +++ b/assets/Martian Chess.blend1 @@ -1,3 +1,3 @@ version https://git-lfs.github.com/spec/v1 -oid sha256:3d67a7463cefd880ed977a06573242d49b00cb2c32a0e64d6e423ef28758f256 -size 2410248 +oid sha256:9ebd6e85899ad9ad4b38fde009971b2c33f6d60d554da6302e7df9d0a9be717a +size 3307980 diff --git a/assets/gltf/Example Flight Helmet.glb b/assets/gltf/Example Flight Helmet.glb index ea80303..0eb29c5 100644 Binary files a/assets/gltf/Example Flight Helmet.glb and b/assets/gltf/Example Flight Helmet.glb differ diff --git a/assets/gltf/Martian Chess.glb b/assets/gltf/Martian Chess.glb index 900a7ed..123fa74 100644 Binary files a/assets/gltf/Martian Chess.glb and b/assets/gltf/Martian Chess.glb differ diff --git a/assets/sprites.png b/assets/sprites.png new file mode 100644 index 0000000..3b876e0 Binary files /dev/null and b/assets/sprites.png differ diff --git a/assets/sprites.xcf b/assets/sprites.xcf new file mode 100644 index 0000000..cfe4dbd Binary files /dev/null and b/assets/sprites.xcf differ diff --git a/examples/gltf-inspector.rs b/examples/gltf-inspector.rs index 69744f5..2301a4e 100644 --- a/examples/gltf-inspector.rs +++ b/examples/gltf-inspector.rs @@ -1,46 +1,58 @@ -use bevy::{prelude::*, gltf::Gltf}; +use bevy::{gltf::Gltf, prelude::*}; fn main() { App::new() - .add_plugins(( - DefaultPlugins, - )) + .add_plugins((DefaultPlugins,)) .add_systems(Startup, startup) .add_systems(Update, inspect) + .add_systems(Update) .run(); } #[derive(Debug, Resource)] struct AssetRegistry { - gltfs: Vec>, + gltfs: Vec>, } fn startup(server: Res, mut commands: Commands) { - commands.insert_resource(AssetRegistry { - gltfs: server.load_folder("gltf").expect("Loading GLTF Assets").into_iter().map(|untyped| untyped.typed::()).collect() + commands.insert_resource(AssetRegistry { + gltfs: vec![server.load("gltf/Martian Chess.glb")], }); - commands.spawn(SpotLightBundle { + commands.spawn(SpotLightBundle { transform: Transform::from_xyz(0.0, 5.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y), ..default() }); - commands.spawn(Camera3dBundle { + commands.spawn(Camera3dBundle { transform: Transform::from_xyz(1.0, 1.0, 1.0).looking_at(Vec3::new(0.0, 0.3, 0.0), Vec3::Y), - ..default() }); + ..default() + }); } -fn inspect(mut events: EventReader>, gltfs: Res>, mut commands: Commands) { - events.iter().for_each(|event| { - match event { - AssetEvent::Created { handle } => { - let gltf = gltfs.get(handle).expect("Fetch GLTF data"); - commands.spawn(SceneBundle { - scene: gltf.named_scenes.get("Helmet").expect("Fetch board scene").clone(), - ..default() - }); - }, - _ => () +fn inspect( + mut events: EventReader>, + gltfs: Res>, + mut commands: Commands, +) { + events.iter().for_each(|event| match event { + AssetEvent::Created { handle } => { + let gltf = gltfs.get(handle).expect("Fetch GLTF data"); + commands.spawn(SceneBundle { + scene: gltf + .named_scenes + .get("Board") + .expect("Fetch board scene") + .clone(), + ..default() + }); } + _ => (), + }); +} + +fn track_named(events: Query<&Name, Added>) { + events.iter().for_each(|name| { + info!("named entity: {:?}", name); }); -} \ No newline at end of file +} diff --git a/examples/sprites-2d.rs b/examples/sprites-2d.rs new file mode 100644 index 0000000..da1a7da --- /dev/null +++ b/examples/sprites-2d.rs @@ -0,0 +1,100 @@ +use std::time::Duration; + +use bevy::{asset::ChangeWatcher, prelude::*, sprite::MaterialMesh2dBundle}; + +const SCALE: f32 = 80.0; + +fn main() { + App::new() + .add_plugins((DefaultPlugins + .set(ImagePlugin::default_nearest()) + .set(WindowPlugin { + primary_window: Some(Window { + title: "2D Sprites".into(), + resolution: (640., 480.).into(), + ..default() + }), + ..default() + }) + .set(AssetPlugin { + watch_for_changes: ChangeWatcher::with_delay(Duration::from_millis(200)), + ..default() + }),)) + .add_systems(Startup, (initialize_camera, load_spritesheet)) + .add_systems(Update, initialize_board.run_if(check_initialize_board)) + .run(); +} + +/// Sprite sheet Resource for later reference +#[derive(Debug, Resource)] +struct SpriteSheet { + handle: Handle, +} + +// Marker component for the 2d board entity +#[derive(Debug, Component)] +struct Board2d; + +/// STARTUP: Initialize 2d gameplay Camera +fn initialize_camera(mut commands: Commands) { + commands.spawn(Camera2dBundle::default()); +} + +/// STARTUP: Load sprite sheet and insert texture atlas +fn load_spritesheet( + mut texture_atlases: ResMut>, + server: Res, + mut commands: Commands, +) { + let atlas = TextureAtlas::from_grid( + server.load("sprites.png"), + Vec2::new(16.0, 16.0), + 5, + 1, + None, + None, + ); + commands.insert_resource(SpriteSheet { + handle: texture_atlases.add(atlas), + }); +} + +fn check_initialize_board(query: Query>) -> bool { + query.is_empty() +} + +/// STARTUP: Initialize the board for representation +fn initialize_board(sprite_sheet: Option>, mut commands: Commands) { + if let Some(sprite_sheet) = sprite_sheet { + commands + .spawn(( + SpatialBundle { + transform: Transform::from_xyz(-SCALE * 3.5, -SCALE * 1.5, 0.0), + ..default() + }, + Board2d, + )) + .with_children(|parent| { + for i in 0..32 { + let x = i % 8; + let y = i / 8; + let s = (x % 2) ^ (y % 2); + + let transform = Transform::from_scale(Vec3::splat(5.0)) + .with_translation(Vec3::new(SCALE * x as f32, SCALE * y as f32, 0.0)); + + let sprite = TextureAtlasSprite::new(s); + + let texture_atlas = sprite_sheet.handle.clone(); + + // Rectangle + parent.spawn(SpriteSheetBundle { + texture_atlas, + sprite, + transform, + ..default() + }); + } + }); + } +} diff --git a/src/audio.rs b/src/audio.rs new file mode 100644 index 0000000..82e93e3 --- /dev/null +++ b/src/audio.rs @@ -0,0 +1,16 @@ +use crate::prelude::*; + +pub struct AudioPlugin; + +impl Plugin for AudioPlugin { + fn build(&self, app: &mut App) { + app.add_plugins(FmodPlugin { + audio_banks_paths: &[ + "./assets/audio/Martian Chess/Build/Desktop/Master.bank", + "./assets/audio/Martian Chess/Build/Desktop/Master.strings.bank", + "./assets/audio/Martian Chess/Build/Desktop/Music.bank", + "./assets/audio/Martian Chess/Build/Desktop/SFX.bank", + ], + }); + } +} diff --git a/src/debug.rs b/src/debug.rs new file mode 100644 index 0000000..88a0e70 --- /dev/null +++ b/src/debug.rs @@ -0,0 +1,24 @@ +use crate::prelude::*; + +pub struct DebugPlugin; + +impl Plugin for DebugPlugin { + fn build(&self, app: &mut App) { + app.add_systems(PostStartup, display_board); + } +} + +fn display_board(board: Res, pieces: Query<&crate::game::Piece>) { + board.inner.iter().for_each(|row| { + print!("+--+--+--+--+--+--+--+--+\n"); + print!("|"); + row.iter() + .map(|piece| piece.and_then(|p| pieces.get(p).ok())) + .for_each(|piece| match piece { + Some(p) => print!("{} |", p), + None => print!(" |"), + }); + print!("\n"); + }); + print!("+--+--+--+--+--+--+--+--+\n"); +} diff --git a/src/display2d.rs b/src/display2d.rs new file mode 100644 index 0000000..7a4feac --- /dev/null +++ b/src/display2d.rs @@ -0,0 +1,9 @@ +use crate::prelude::*; + +pub struct Display2dPlugin; + +impl Plugin for Display2dPlugin { + fn build(&self, app: &mut App) { + todo!() + } +} diff --git a/src/display3d.rs b/src/display3d.rs new file mode 100644 index 0000000..a2d32ad --- /dev/null +++ b/src/display3d.rs @@ -0,0 +1,9 @@ +use crate::prelude::*; + +pub struct Display3dPlugin; + +impl Plugin for Display3dPlugin { + fn build(&self, app: &mut App) { + todo!() + } +} diff --git a/src/game.rs b/src/game.rs new file mode 100644 index 0000000..1b1f93a --- /dev/null +++ b/src/game.rs @@ -0,0 +1,147 @@ +use crate::prelude::*; + +pub struct GamePlugin; + +impl Plugin for GamePlugin { + fn build(&self, app: &mut App) { + app.add_systems(Startup, setup_board); + } +} + +#[derive(Debug, Component)] +pub(crate) enum Piece { + Pawn, + Drone, + Queen, +} + +// manually for the type. +impl std::fmt::Display for Piece { + fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { + match self { + Piece::Queen => write!(f, "@"), + Piece::Drone => write!(f, "^"), + Piece::Pawn => write!(f, "*"), + } + } +} + +/// The board is setup like this: +/// ```text +/// 0 1 2 3 4 5 6 7 +/// +--+--+--+--+--+--+--+--+ +/// a | | | | I | d| Q| Q| +/// +--+--+--+--+--+--+--+--+ +/// b |d |p |p | I | p| d| Q| +/// +--+--+--+--+--+--+--+--+ +/// c |Q |d |p | I | p| p| d| +/// +--+--+--+--+--+--+--+--+ +/// d |Q |Q |d | I | | | | +/// +--+--+--+--+--+--+--+--+ +/// ```` +#[derive(Debug, Resource)] +pub(crate) struct Board { + pub inner: Vec>>, +} + +fn setup_board(mut commands: Commands) { + let a5d = commands + .spawn((SpatialBundle { ..default() }, Piece::Drone)) + .id(); + let a6q = commands + .spawn((SpatialBundle { ..default() }, Piece::Queen)) + .id(); + let a7q = commands + .spawn((SpatialBundle { ..default() }, Piece::Queen)) + .id(); + let b0d = commands + .spawn((SpatialBundle { ..default() }, Piece::Drone)) + .id(); + let b1p = commands + .spawn((SpatialBundle { ..default() }, Piece::Pawn)) + .id(); + let b2p = commands + .spawn((SpatialBundle { ..default() }, Piece::Pawn)) + .id(); + let c5p = commands + .spawn((SpatialBundle { ..default() }, Piece::Pawn)) + .id(); + let b5p = commands + .spawn((SpatialBundle { ..default() }, Piece::Pawn)) + .id(); + let b6d = commands + .spawn((SpatialBundle { ..default() }, Piece::Drone)) + .id(); + let b7q = commands + .spawn((SpatialBundle { ..default() }, Piece::Queen)) + .id(); + let c0q = commands + .spawn((SpatialBundle { ..default() }, Piece::Queen)) + .id(); + let c1d = commands + .spawn((SpatialBundle { ..default() }, Piece::Drone)) + .id(); + let c2p = commands + .spawn((SpatialBundle { ..default() }, Piece::Pawn)) + .id(); + let c6p = commands + .spawn((SpatialBundle { ..default() }, Piece::Pawn)) + .id(); + let c7d = commands + .spawn((SpatialBundle { ..default() }, Piece::Drone)) + .id(); + let d0q = commands + .spawn((SpatialBundle { ..default() }, Piece::Queen)) + .id(); + let d1q = commands + .spawn((SpatialBundle { ..default() }, Piece::Queen)) + .id(); + let d2d = commands + .spawn((SpatialBundle { ..default() }, Piece::Drone)) + .id(); + + commands.insert_resource(Board { + inner: vec![ + vec![ + None, + None, + None, + None, + None, + Some(a5d), + Some(a6q), + Some(a7q), + ], + vec![ + Some(b0d), + Some(b1p), + Some(b2p), + None, + None, + Some(b5p), + Some(b6d), + Some(b7q), + ], + vec![ + Some(c0q), + Some(c1d), + Some(c2p), + None, + None, + Some(c5p), + Some(c6p), + Some(c7d), + ], + vec![ + Some(d0q), + Some(d1q), + Some(d2d), + None, + None, + None, + None, + None, + ], + ], + }); +} diff --git a/src/main.rs b/src/main.rs index b33e79a..67a999f 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,173 +1,21 @@ -use bevy::prelude::*; -use bevy_fmod::prelude::*; +mod audio; +mod debug; +mod display2d; +mod display3d; +mod game; +mod prelude; + +use crate::prelude::*; fn main() { App::new() .add_plugins(( DefaultPlugins, - FmodPlugin { - audio_banks_paths: &[ - "./assets/audio/Martian Chess/Build/Desktop/Master.bank", - "./assets/audio/Martian Chess/Build/Desktop/Master.strings.bank", - "./assets/audio/Martian Chess/Build/Desktop/Music.bank", - "./assets/audio/Martian Chess/Build/Desktop/SFX.bank", - ], - }, + audio::AudioPlugin, + debug::DebugPlugin, + display2d::Display2dPlugin, + display3d::Display3dPlugin, + game::GamePlugin, )) - .add_systems(Startup, setup_board) - .add_systems(PostStartup, display_board) .run(); } - -#[derive(Debug, Component)] -enum Piece { - Pawn, - Drone, - Queen, -} - -// manually for the type. -impl std::fmt::Display for Piece { - fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result { - match self { - Piece::Queen => write!(f, "@"), - Piece::Drone => write!(f, "^"), - Piece::Pawn => write!(f, "*"), - } - } -} - -/// The board is setup like this: -/// ```text -/// 0 1 2 3 4 5 6 7 -/// +--+--+--+--+--+--+--+--+ -/// a | | | | I | d| Q| Q| -/// +--+--+--+--+--+--+--+--+ -/// b |d |p |p | I | p| d| Q| -/// +--+--+--+--+--+--+--+--+ -/// c |Q |d |p | I | p| p| d| -/// +--+--+--+--+--+--+--+--+ -/// d |Q |Q |d | I | | | | -/// +--+--+--+--+--+--+--+--+ -/// ```` -#[derive(Debug, Resource)] -struct Board { - inner: Vec>>, -} - -fn setup_board(mut commands: Commands) { - let a5d = commands - .spawn((SpatialBundle { ..default() }, Piece::Drone)) - .id(); - let a6q = commands - .spawn((SpatialBundle { ..default() }, Piece::Queen)) - .id(); - let a7q = commands - .spawn((SpatialBundle { ..default() }, Piece::Queen)) - .id(); - let b0d = commands - .spawn((SpatialBundle { ..default() }, Piece::Drone)) - .id(); - let b1p = commands - .spawn((SpatialBundle { ..default() }, Piece::Pawn)) - .id(); - let b2p = commands - .spawn((SpatialBundle { ..default() }, Piece::Pawn)) - .id(); - let c5p = commands - .spawn((SpatialBundle { ..default() }, Piece::Pawn)) - .id(); - let b5p = commands - .spawn((SpatialBundle { ..default() }, Piece::Pawn)) - .id(); - let b6d = commands - .spawn((SpatialBundle { ..default() }, Piece::Drone)) - .id(); - let b7q = commands - .spawn((SpatialBundle { ..default() }, Piece::Queen)) - .id(); - let c0q = commands - .spawn((SpatialBundle { ..default() }, Piece::Queen)) - .id(); - let c1d = commands - .spawn((SpatialBundle { ..default() }, Piece::Drone)) - .id(); - let c2p = commands - .spawn((SpatialBundle { ..default() }, Piece::Pawn)) - .id(); - let c6p = commands - .spawn((SpatialBundle { ..default() }, Piece::Pawn)) - .id(); - let c7d = commands - .spawn((SpatialBundle { ..default() }, Piece::Drone)) - .id(); - let d0q = commands - .spawn((SpatialBundle { ..default() }, Piece::Queen)) - .id(); - let d1q = commands - .spawn((SpatialBundle { ..default() }, Piece::Queen)) - .id(); - let d2d = commands - .spawn((SpatialBundle { ..default() }, Piece::Drone)) - .id(); - - commands.insert_resource(Board { - inner: vec![ - vec![ - None, - None, - None, - None, - None, - Some(a5d), - Some(a6q), - Some(a7q), - ], - vec![ - Some(b0d), - Some(b1p), - Some(b2p), - None, - None, - Some(b5p), - Some(b6d), - Some(b7q), - ], - vec![ - Some(c0q), - Some(c1d), - Some(c2p), - None, - None, - Some(c5p), - Some(c6p), - Some(c7d), - ], - vec![ - Some(d0q), - Some(d1q), - Some(d2d), - None, - None, - None, - None, - None, - ], - ], - }); -} - -fn display_board(board: Res, pieces: Query<&Piece>) { - board.inner.iter().for_each(|row| { - print!("+--+--+--+--+--+--+--+--+\n"); - print!("|"); - row.iter() - .map(|piece| piece.and_then(|p| pieces.get(p).ok())) - .for_each(|piece| match piece { - Some(p) => print!("{} |", p), - None => print!(" |"), - }); - print!("\n"); - }); - print!("+--+--+--+--+--+--+--+--+\n"); -} diff --git a/src/prelude.rs b/src/prelude.rs new file mode 100644 index 0000000..5df1da5 --- /dev/null +++ b/src/prelude.rs @@ -0,0 +1,2 @@ +pub use bevy::prelude::*; +pub use bevy_fmod::prelude::*;