Stubbing out shape asset loading for tetris, also fixed imports
parent
277260ecf6
commit
e07ff07e23
@ -1,44 +1,3 @@
|
||||
[package]
|
||||
name = "games"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[[example]]
|
||||
name = "demo_parallax2d"
|
||||
path = "examples/demos/parallax2d.rs"
|
||||
|
||||
[[example]]
|
||||
name = "demo_parallax3d"
|
||||
path = "examples/demos/parallax3d.rs"
|
||||
|
||||
[features]
|
||||
hide_debug = []
|
||||
|
||||
[dependencies]
|
||||
itertools = "*"
|
||||
thiserror = "2.0.12"
|
||||
toml = "0.9.8"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0.219"
|
||||
features = ["derive"]
|
||||
|
||||
[dependencies.avian3d]
|
||||
version = "0.4.1"
|
||||
|
||||
[dependencies.avian2d]
|
||||
version = "0.4.1"
|
||||
|
||||
[dependencies.bevy]
|
||||
version = "0.17.2"
|
||||
features = ["wayland", "dynamic_linking", "track_location", "experimental_bevy_feathers", "experimental_bevy_ui_widgets"]
|
||||
|
||||
[dev-dependencies]
|
||||
lipsum = "*"
|
||||
rand = "*"
|
||||
itertools = "*"
|
||||
indoc = "*"
|
||||
|
||||
[build-dependencies]
|
||||
walkdir = "*"
|
||||
chrono = "*"
|
||||
[workspace]
|
||||
resolver = "3"
|
||||
members = ["engine", "flappy", "hum", "physics", "tetris", "trees"]
|
||||
|
||||
@ -0,0 +1,28 @@
|
||||
[package]
|
||||
name = "engine"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[features]
|
||||
hide_debug = []
|
||||
|
||||
[dependencies.bevy]
|
||||
version = "0.17.2"
|
||||
features = ["wayland", "dynamic_linking", "track_location", "experimental_bevy_feathers", "experimental_bevy_ui_widgets"]
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0.219"
|
||||
features = ["derive"]
|
||||
|
||||
[dependencies]
|
||||
itertools = "0.14.0"
|
||||
thiserror = "2.0.12"
|
||||
|
||||
[dev-dependencies]
|
||||
lipsum = "*"
|
||||
rand = "*"
|
||||
itertools = "*"
|
||||
|
||||
[build-dependencies]
|
||||
walkdir = "*"
|
||||
chrono = "*"
|
||||
@ -1,4 +1,4 @@
|
||||
use games::*;
|
||||
use engine::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
@ -1,6 +1,6 @@
|
||||
use std::f32::consts::PI;
|
||||
|
||||
use games::*;
|
||||
use engine::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
@ -1,4 +1,4 @@
|
||||
use games::*;
|
||||
use engine::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
@ -1,4 +1,4 @@
|
||||
use games::*;
|
||||
use engine::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
@ -1,4 +1,4 @@
|
||||
use games::*;
|
||||
use engine::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
@ -1,2 +1,2 @@
|
||||
/// Include the version of this build from an auto-generated version file
|
||||
pub const VERSION: &str = include_str!("../VERSION");
|
||||
pub const VERSION: &str = include_str!("../../VERSION");
|
||||
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "flappy"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies.engine]
|
||||
path = "../engine"
|
||||
|
||||
[dependencies.physics]
|
||||
path = "../physics"
|
||||
@ -0,0 +1,6 @@
|
||||
[package]
|
||||
name = "hum"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies]
|
||||
@ -1,4 +1,4 @@
|
||||
use games::*;
|
||||
use engine::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "physics"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies.engine]
|
||||
path = "../engine"
|
||||
|
||||
[dependencies.avian3d]
|
||||
version = "0.4.1"
|
||||
|
||||
[dependencies.avian2d]
|
||||
version = "0.4.1"
|
||||
|
||||
@ -0,0 +1,2 @@
|
||||
pub mod physics2d;
|
||||
pub mod physics3d;
|
||||
@ -1,4 +1,5 @@
|
||||
use super::*;
|
||||
|
||||
pub use avian2d::prelude::*;
|
||||
|
||||
/// 2D Physics systems, resources, events, etc.
|
||||
@ -1,53 +0,0 @@
|
||||
use super::*;
|
||||
|
||||
/// Create tetris game with camera that renders to subset of viewport
|
||||
///
|
||||
/// Focus on a single piece and making it really tight mechanically
|
||||
/// A single piece with movement, rotation, jump-to-end, line clearing, etc.
|
||||
///
|
||||
/// Once done, make pieces a data input so we can add arbitrary metadata to them
|
||||
pub struct BlocksPlugin;
|
||||
|
||||
impl Plugin for BlocksPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.add_systems(Startup, init_blocks);
|
||||
}
|
||||
}
|
||||
|
||||
/// Shape asset
|
||||
/// Stores shape data in an asset file, likely toml
|
||||
#[derive(Asset, TypePath, Debug, Deserialize)]
|
||||
struct ShapeAsset {
|
||||
layout: Vec<Vec<u8>>
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ShapeAssetLoader;
|
||||
|
||||
impl AssetLoader for ShapeAssetLoader {
|
||||
type Asset = ShapeAsset;
|
||||
type Settings = ();
|
||||
type Error = ();
|
||||
async fn load(
|
||||
&self,
|
||||
reader: &mut dyn Reader,
|
||||
_settings: &(),
|
||||
_load_context: &mut LoadContext<'_>,
|
||||
) -> Result<Self::Asset, Self::Error> {
|
||||
let mut bytes = Vec::new();
|
||||
reader.read_to_end(&mut bytes).await.unwrap_or(());
|
||||
let shape_asset = toml::from_slice::<ShapeAsset>(bytes.into()).unwrap_or(());
|
||||
Ok(shape_asset)
|
||||
}
|
||||
|
||||
fn extension(&self) -> &[str] {
|
||||
&["shape.toml"]
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize camera and block game area
|
||||
fn init_blocks(
|
||||
mut commands: Commands,
|
||||
) {
|
||||
commands.spawn((Camera2d, Camera::default()));
|
||||
}
|
||||
@ -1,16 +0,0 @@
|
||||
mod blocks;
|
||||
mod debug;
|
||||
mod fighter;
|
||||
|
||||
use games::*;
|
||||
|
||||
use blocks::*;
|
||||
use debug::*;
|
||||
use fighter::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((DefaultPlugins, BlocksPlugin, FighterPlugin))
|
||||
.run();
|
||||
}
|
||||
|
||||
@ -0,0 +1,19 @@
|
||||
[package]
|
||||
name = "tetris"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies.serde]
|
||||
version = "1.0.219"
|
||||
features = ["derive"]
|
||||
|
||||
[dependencies.engine]
|
||||
path = "../engine"
|
||||
|
||||
[dependencies]
|
||||
toml = "0.9.8"
|
||||
thiserror = "*"
|
||||
|
||||
[dependencies.bevy]
|
||||
version = "0.17.2"
|
||||
features = ["wayland", "dynamic_linking", "track_location", "experimental_bevy_feathers", "experimental_bevy_ui_widgets"]
|
||||
@ -0,0 +1,4 @@
|
||||
layout = [
|
||||
[0,1,0],
|
||||
[1,1,1],
|
||||
]
|
||||
@ -0,0 +1,90 @@
|
||||
use super::*;
|
||||
|
||||
/// Create tetris game with camera that renders to subset of viewport
|
||||
///
|
||||
/// Focus on a single piece and making it really tight mechanically
|
||||
/// A single piece with movement, rotation, jump-to-end, line clearing, etc.
|
||||
///
|
||||
/// Once done, make pieces a data input so we can add arbitrary metadata to them
|
||||
pub struct BlocksPlugin;
|
||||
|
||||
impl Plugin for BlocksPlugin {
|
||||
fn build(&self, app: &mut App) {
|
||||
app.init_asset::<ShapeAsset>()
|
||||
.init_asset_loader::<ShapeAssetLoader>()
|
||||
.add_systems(OnEnter(LoadState::Loading), load_assets)
|
||||
.add_systems(OnEnter(GameState::Setup), (setup_camera, setup_blocks))
|
||||
.add_observer(add_shape);
|
||||
}
|
||||
}
|
||||
|
||||
/// Shape asset
|
||||
/// Stores shape data in an asset file, likely toml
|
||||
#[derive(Asset, TypePath, Debug, Deserialize)]
|
||||
struct ShapeAsset {
|
||||
layout: Vec<Vec<u8>>,
|
||||
}
|
||||
|
||||
impl ShapeAsset {
|
||||
fn into_bundle(&self) -> impl Bundle {
|
||||
()
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Default)]
|
||||
struct ShapeAssetLoader;
|
||||
|
||||
#[derive(Debug, Error)]
|
||||
enum ShapeAssetError {
|
||||
#[error("Failed to read file {0}")]
|
||||
Io(#[from] std::io::Error),
|
||||
#[error("Failed to parse file {0}")]
|
||||
Parse(#[from] toml::de::Error),
|
||||
}
|
||||
|
||||
impl AssetLoader for ShapeAssetLoader {
|
||||
type Asset = ShapeAsset;
|
||||
type Settings = ();
|
||||
type Error = ShapeAssetError;
|
||||
async fn load(
|
||||
&self,
|
||||
reader: &mut dyn Reader,
|
||||
_settings: &(),
|
||||
_load_context: &mut LoadContext<'_>,
|
||||
) -> Result<Self::Asset, Self::Error> {
|
||||
let mut bytes = Vec::new();
|
||||
reader.read_to_end(&mut bytes).await?;
|
||||
let shape_asset = toml::from_slice::<ShapeAsset>(bytes.as_slice())?;
|
||||
Ok(shape_asset)
|
||||
}
|
||||
|
||||
fn extensions(&self) -> &[&str] {
|
||||
&["shape.toml"]
|
||||
}
|
||||
}
|
||||
|
||||
/// Initialize camera and block game area
|
||||
fn load_assets(server: Res<AssetServer>, mut all_assets: ResMut<AllAssets>) {
|
||||
all_assets.handles.push(server.load::<ShapeAsset>("t.shape.toml").untyped());
|
||||
}
|
||||
|
||||
fn setup_camera(mut commands: Commands) {
|
||||
commands.spawn((Camera2d, Camera::default()));
|
||||
}
|
||||
|
||||
fn setup_blocks(mut commands: Commands) {
|
||||
error!("Setup blocks");
|
||||
error!("Once all steps are setup, move on to Run");
|
||||
}
|
||||
|
||||
/// Event handler for transforming a handle component into a thing
|
||||
fn add_shape(
|
||||
event: On<Add, AssetComponent<ShapeAsset>>,
|
||||
query: Query<&AssetComponent<ShapeAsset>>,
|
||||
mut commands: Commands,
|
||||
shapes: Res<Assets<ShapeAsset>>,
|
||||
) {
|
||||
let asset_component = query.get(event.entity).unwrap();
|
||||
let shape = shapes.get(asset_component.handle.id()).unwrap();
|
||||
commands.entity(event.entity).insert(shape.into_bundle());
|
||||
}
|
||||
@ -0,0 +1,69 @@
|
||||
mod blocks;
|
||||
mod debug;
|
||||
mod fighter;
|
||||
|
||||
use engine::*;
|
||||
use serde::Deserialize;
|
||||
use thiserror::Error;
|
||||
|
||||
use blocks::*;
|
||||
use debug::*;
|
||||
use fighter::*;
|
||||
|
||||
fn main() {
|
||||
App::new()
|
||||
.add_plugins((DefaultPlugins, BlocksPlugin, FighterPlugin))
|
||||
.init_state::<GameState>()
|
||||
.init_resource::<AllAssets>()
|
||||
.add_systems(Update, load.run_if(in_state(LoadState::Loading)))
|
||||
.run();
|
||||
}
|
||||
|
||||
#[derive(Default, Resource)]
|
||||
struct AllAssets {
|
||||
handles: Vec<UntypedHandle>,
|
||||
}
|
||||
|
||||
/// Reports if the game is loading assets
|
||||
#[derive(States, Default, Clone, Eq, Debug, PartialEq, Hash)]
|
||||
enum LoadState {
|
||||
#[default]
|
||||
Loading,
|
||||
Loaded,
|
||||
}
|
||||
|
||||
/// Tracks if the game is in debug mode
|
||||
#[derive(States, Default, Clone, Eq, Debug, PartialEq, Hash)]
|
||||
enum DebugState {
|
||||
#[default]
|
||||
Off,
|
||||
On,
|
||||
}
|
||||
|
||||
/// Tracks what state the main game loop is in
|
||||
#[derive(States, Default, Clone, Eq, Debug, PartialEq, Hash)]
|
||||
enum GameState {
|
||||
#[default]
|
||||
Setup,
|
||||
Run,
|
||||
}
|
||||
|
||||
fn load(mut next: ResMut<NextState<GameState>>, server: Res<AssetServer>, assets: Res<AllAssets>) {
|
||||
for asset in assets.handles.iter() {
|
||||
let state = server.get_load_state(asset.id());
|
||||
println!("{:?}", state);
|
||||
}
|
||||
next.set(GameState::Setup);
|
||||
}
|
||||
|
||||
/// A wrapper around a handle for assigning an arbitrary Handle<T> to an entity
|
||||
#[derive(Debug, Component)]
|
||||
struct AssetComponent<T: Asset> {
|
||||
handle: Handle<T>,
|
||||
}
|
||||
|
||||
impl<T: Asset> AssetComponent<T> {
|
||||
fn new(handle: Handle<T>) -> Self {
|
||||
Self { handle }
|
||||
}
|
||||
}
|
||||
@ -0,0 +1,10 @@
|
||||
[package]
|
||||
name = "trees"
|
||||
version = "0.1.0"
|
||||
edition = "2024"
|
||||
|
||||
[dependencies.engine]
|
||||
path = "../engine"
|
||||
|
||||
[dev-dependencies]
|
||||
indoc = "*"
|
||||
Loading…
Reference in New Issue