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