| @@ -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); | |||
| } | |||
| } | |||