| @@ -0,0 +1,6 @@ | |||||
| ( | |||||
| axes: {}, | |||||
| actions: { | |||||
| "exit_game": [[Key(Escape)]], | |||||
| }, | |||||
| ) | |||||
| @@ -0,0 +1 @@ | |||||
| pub mod spritesheet; | |||||
| @@ -0,0 +1,79 @@ | |||||
| use amethyst::{ | |||||
| assets::{AssetStorage, Handle, Loader, ProgressCounter}, | |||||
| prelude::*, | |||||
| renderer::{ImageFormat, Texture}, | |||||
| renderer::{SpriteSheet, SpriteSheetFormat}, | |||||
| }; | |||||
| use std::{collections::HashMap, path::PathBuf}; | |||||
| /// | |||||
| #[derive(Default)] | |||||
| pub struct SpriteSheetMapLoader { | |||||
| map: SpriteSheetMap, | |||||
| paths: Vec<(String, PathBuf, PathBuf)>, | |||||
| } | |||||
| impl SpriteSheetMapLoader { | |||||
| /// create a new map loader | |||||
| pub fn new() -> Self { | |||||
| Default::default() | |||||
| } | |||||
| /// add a path to a sprite sheet | |||||
| pub fn with_paths(mut self, name: String, spritesheet: PathBuf, texture: PathBuf) -> Self { | |||||
| self.paths.push((name, spritesheet, texture)); | |||||
| self | |||||
| } | |||||
| /// load all the sprites provided to the loader and return a progress counter and spritesheetmap | |||||
| pub fn load(mut self, world: &mut World) -> (SpriteSheetMap, ProgressCounter) { | |||||
| let map = &mut self.map; | |||||
| let mut counter = ProgressCounter::new(); | |||||
| for (name, spritesheet_path, texture_path) in self.paths { | |||||
| let texture_handle = { | |||||
| let loader = world.read_resource::<Loader>(); | |||||
| let texture_storage = world.read_resource::<AssetStorage<Texture>>(); | |||||
| loader.load( | |||||
| texture_path.to_str().unwrap(), | |||||
| ImageFormat::default(), | |||||
| &mut counter, | |||||
| &texture_storage, | |||||
| ) | |||||
| }; | |||||
| let spritesheet_handle = { | |||||
| let loader = world.read_resource::<Loader>(); | |||||
| let spritesheet_storage = world.read_resource::<AssetStorage<SpriteSheet>>(); | |||||
| loader.load( | |||||
| spritesheet_path.to_str().unwrap(), | |||||
| SpriteSheetFormat(texture_handle), | |||||
| &mut counter, | |||||
| &spritesheet_storage, | |||||
| ) | |||||
| }; | |||||
| map.insert(name.clone(), spritesheet_handle); | |||||
| } | |||||
| (self.map, counter) | |||||
| } | |||||
| } | |||||
| /// a map of spritesheets loaded into the game's memory | |||||
| #[derive(Default)] | |||||
| pub struct SpriteSheetMap { | |||||
| map: HashMap<String, Handle<SpriteSheet>>, | |||||
| } | |||||
| impl SpriteSheetMap { | |||||
| /// insert a new handle into the spritesheet map | |||||
| pub fn insert(&mut self, name: String, spritesheet_handle: Handle<SpriteSheet>) { | |||||
| self.map.insert(name, spritesheet_handle); | |||||
| } | |||||
| /// get a spritesheet handle from it's name | |||||
| pub fn get_handle(&self, name: String) -> Option<&Handle<SpriteSheet>> { | |||||
| self.map.get(&name) | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,2 @@ | |||||
| pub mod preload; | |||||
| pub mod titlescreen; | |||||
| @@ -0,0 +1,47 @@ | |||||
| use crate::resources::spritesheet::*; | |||||
| use amethyst::{assets::ProgressCounter, prelude::*}; | |||||
| /// struct for preloading the game | |||||
| pub struct PreloadState { | |||||
| counter: Option<ProgressCounter>, | |||||
| } | |||||
| impl PreloadState { | |||||
| pub fn new() -> Self { | |||||
| Self { counter: None } | |||||
| } | |||||
| } | |||||
| impl SimpleState for PreloadState { | |||||
| fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) { | |||||
| // load the spritesheet | |||||
| let (spritesheet_map, counter) = SpriteSheetMapLoader::new() | |||||
| .with_paths( | |||||
| "title_screen".into(), | |||||
| "img/title_screen_sprite_sheet.ron".into(), | |||||
| "img/title_screen_texture.png".into(), | |||||
| ) | |||||
| .load(data.world); | |||||
| self.counter = Some(counter); | |||||
| data.world.insert(spritesheet_map); | |||||
| } | |||||
| fn update(&mut self, _data: &mut StateData<'_, GameData<'_, '_>>) -> SimpleTrans { | |||||
| if let Some(counter) = &self.counter { | |||||
| let (assets, finished) = (counter.num_assets(), counter.num_finished()); | |||||
| if assets != finished { | |||||
| println!("{} of {} loaded", counter.num_finished(), counter.num_assets()); | |||||
| Trans::None | |||||
| } else if counter.is_complete() { | |||||
| println!("completed load!"); | |||||
| Trans::Switch(Box::new(crate::states::titlescreen::TitleScreenState)) | |||||
| } else { | |||||
| Trans::None | |||||
| } | |||||
| } else { | |||||
| Trans::None | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,82 @@ | |||||
| use crate::resources::spritesheet::SpriteSheetMap; | |||||
| use amethyst::{ | |||||
| core::transform::Transform, | |||||
| prelude::*, | |||||
| renderer::{Camera, SpriteRender}, | |||||
| window::ScreenDimensions, | |||||
| }; | |||||
| use nalgebra::Vector3; | |||||
| const DEFAULT_SPRITE_WIDTH: f32 = 256.0; | |||||
| const DEFAULT_SPRITE_HEIGHT: f32 = 144.0; | |||||
| /// struct for title screen state | |||||
| pub struct TitleScreenState; | |||||
| impl TitleScreenState { | |||||
| /// initialize the titlescreen | |||||
| fn init(&self, world: &mut World, dimensions: ScreenDimensions) { | |||||
| self.init_camera(world, &dimensions); | |||||
| self.init_scenery(world, &dimensions); | |||||
| } | |||||
| // initialize the camera | |||||
| fn init_camera(&self, world: &mut World, dimensions: &ScreenDimensions) { | |||||
| let mut transform = Transform::default(); | |||||
| transform.set_translation_xyz(dimensions.width() * 0.5, dimensions.height() * 0.5, 1.0); | |||||
| world | |||||
| .create_entity() | |||||
| .with(Camera::standard_2d(dimensions.width(), dimensions.height())) | |||||
| .with(transform) | |||||
| .build(); | |||||
| } | |||||
| // initialize the scenery | |||||
| fn init_scenery(&self, world: &mut World, dimensions: &ScreenDimensions) { | |||||
| // create the scale vector | |||||
| let scale_vector = Vector3::new( | |||||
| dimensions.width() / DEFAULT_SPRITE_WIDTH, | |||||
| dimensions.height() / DEFAULT_SPRITE_HEIGHT, | |||||
| 0.0, | |||||
| ); | |||||
| // create scenery transform | |||||
| let mut transform = Transform::default(); | |||||
| transform.set_translation_xyz(dimensions.width() * 0.5, dimensions.height() * 0.5, 0.0); | |||||
| transform.set_scale(scale_vector); | |||||
| // get the sprite sheet from the map | |||||
| let spritesheet_handle = { | |||||
| if let Some(map) = world.try_fetch::<SpriteSheetMap>() { | |||||
| map.get_handle("title_screen".into()) | |||||
| .expect("could not find title_screen sprite sheet") | |||||
| .clone() | |||||
| } else { | |||||
| panic!("failed to find") | |||||
| } | |||||
| }; | |||||
| // create a sprite render | |||||
| let mut sprite_render = SpriteRender { sprite_sheet: spritesheet_handle, sprite_number: 2 }; | |||||
| world.create_entity().with(transform.clone()).with(sprite_render.clone()).build(); | |||||
| sprite_render.sprite_number = 1; | |||||
| world.create_entity().with(transform.clone()).with(sprite_render.clone()).build(); | |||||
| sprite_render.sprite_number = 0; | |||||
| world.create_entity().with(transform.clone()).with(sprite_render.clone()).build(); | |||||
| sprite_render.sprite_number = 3; | |||||
| world.create_entity().with(transform.clone()).with(sprite_render.clone()).build(); | |||||
| sprite_render.sprite_number = 4; | |||||
| world.create_entity().with(transform.clone()).with(sprite_render.clone()).build(); | |||||
| } | |||||
| } | |||||
| impl SimpleState for TitleScreenState { | |||||
| fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) { | |||||
| let world = data.world; | |||||
| let dimensions = (*world.read_resource::<ScreenDimensions>()).clone(); | |||||
| self.init(world, dimensions); | |||||
| } | |||||
| } | |||||