| @@ -5,8 +5,9 @@ authors = ["Isabelle L. <me@izzabelle.dev>"] | |||
| edition = "2018" | |||
| [dependencies] | |||
| nalgebra = "0.19.0" | |||
| bevy = "0.1.2" | |||
| ron = "0.6.0" | |||
| [dependencies.amethyst] | |||
| version = "0.15.0" | |||
| features = ["vulkan"] | |||
| [dependencies.serde] | |||
| version = "1.0.115" | |||
| features = ["derive"] | |||
| @@ -1,36 +0,0 @@ | |||
| List(( | |||
| texture_width: 512, | |||
| texture_height: 432, | |||
| sprites: [ | |||
| ( | |||
| x: 0, | |||
| y: 0, | |||
| width: 256, | |||
| height: 144, | |||
| ), | |||
| ( | |||
| x: 0, | |||
| y: 144, | |||
| width: 256, | |||
| height: 144, | |||
| ), | |||
| ( | |||
| x: 0, | |||
| y: 288, | |||
| width: 256, | |||
| height: 144, | |||
| ), | |||
| ( | |||
| x: 256, | |||
| y: 0, | |||
| width: 256, | |||
| height: 144, | |||
| ), | |||
| ( | |||
| x: 256, | |||
| y: 144, | |||
| width: 256, | |||
| height: 144, | |||
| ), | |||
| ], | |||
| )) | |||
| @@ -1,13 +0,0 @@ | |||
| pub mod title_screen; | |||
| use amethyst::prelude::*; | |||
| use title_screen::TitleScreen; | |||
| /// a simple state for initializing the game | |||
| pub struct InitialState; | |||
| impl SimpleState for InitialState { | |||
| fn on_start(&mut self, _data: StateData<'_, GameData<'_, '_>>) { | |||
| Trans::Push(Box::new(TitleScreen)); | |||
| } | |||
| } | |||
| @@ -1,47 +0,0 @@ | |||
| use amethyst::ecs::prelude::*; | |||
| // deep water component | |||
| pub struct DeepWater { | |||
| pub y: f32, | |||
| } | |||
| impl Component for DeepWater { | |||
| type Storage = DenseVecStorage<Self>; | |||
| } | |||
| // shallow water component | |||
| pub struct ShallowWater { | |||
| pub y: f32, | |||
| } | |||
| impl Component for ShallowWater { | |||
| type Storage = DenseVecStorage<Self>; | |||
| } | |||
| // islands component | |||
| pub struct Islands; | |||
| impl Component for Islands { | |||
| type Storage = DenseVecStorage<Self>; | |||
| } | |||
| // sea component | |||
| pub struct Sea; | |||
| impl Component for Sea { | |||
| type Storage = DenseVecStorage<Self>; | |||
| } | |||
| // sky component | |||
| pub struct Sky; | |||
| impl Component for Sky { | |||
| type Storage = DenseVecStorage<Self>; | |||
| } | |||
| // title component | |||
| pub struct Title; | |||
| impl Component for Title { | |||
| type Storage = DenseVecStorage<Self>; | |||
| } | |||
| @@ -1,171 +0,0 @@ | |||
| mod components; | |||
| // namespacing | |||
| use crate::utils::{load_font, load_sprite_sheet, load_texture}; | |||
| use amethyst::{ | |||
| assets::Handle, | |||
| core::transform::Transform, | |||
| ecs::prelude::*, | |||
| prelude::*, | |||
| renderer::{Camera, SpriteRender, SpriteSheet}, | |||
| ui::{Anchor, FontAsset, UiText, UiTransform}, | |||
| window::ScreenDimensions, | |||
| }; | |||
| use components::*; | |||
| use nalgebra::Vector3; | |||
| // constants | |||
| const DEFAULT_SPRITE_WIDTH: f32 = 256.0; | |||
| const DEFAULT_SPRITE_HEIGHT: f32 = 144.0; | |||
| /// a simple state for the title screen | |||
| pub struct TitleScreen; | |||
| impl SimpleState for TitleScreen { | |||
| fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) { | |||
| let world = data.world; | |||
| let dimensions = (*world.read_resource::<ScreenDimensions>()).clone(); | |||
| let sprite_sheet = init_sprite_sheet(world); | |||
| let font_asset = load_font("fnt/8x8_wide_mono_bold.ttf", world); | |||
| world.register::<DeepWater>(); | |||
| world.register::<ShallowWater>(); | |||
| world.register::<Islands>(); | |||
| world.register::<Sky>(); | |||
| world.register::<Sea>(); | |||
| init_scene_entities(world, sprite_sheet, font_asset, &dimensions); | |||
| init_camera(world, &dimensions); | |||
| } | |||
| fn handle_event( | |||
| &mut self, | |||
| mut _data: StateData<'_, GameData<'_, '_>>, | |||
| _event: StateEvent, | |||
| ) -> SimpleTrans { | |||
| // keep going | |||
| Trans::None | |||
| } | |||
| } | |||
| fn init_sprite_sheet(world: &World) -> Handle<SpriteSheet> { | |||
| let texture_handle = load_texture("img/title_screen_texture.png", world); | |||
| load_sprite_sheet("img/title_screen_sprite_sheet.ron", world, texture_handle) | |||
| } | |||
| // initialize the camera | |||
| fn init_camera(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(); | |||
| } | |||
| // initailize the entities for the scene | |||
| fn init_scene_entities( | |||
| world: &mut World, | |||
| sprite_sheet_handle: Handle<SpriteSheet>, | |||
| font_asset_handle: Handle<FontAsset>, | |||
| dimensions: &ScreenDimensions, | |||
| ) { | |||
| // create the scale vector | |||
| let scale_vector3 = Vector3::new( | |||
| dimensions.width() / DEFAULT_SPRITE_WIDTH, | |||
| dimensions.height() / DEFAULT_SPRITE_HEIGHT, | |||
| 0.0, | |||
| ); | |||
| // create the scenery transform | |||
| let mut scenery_transform = Transform::default(); | |||
| scenery_transform.set_translation_xyz(dimensions.width() * 0.5, dimensions.height() * 0.5, 0.0); | |||
| scenery_transform.set_scale(scale_vector3); | |||
| // create the shallow water entity | |||
| let sprite_render = SpriteRender { | |||
| sprite_sheet: sprite_sheet_handle.clone(), | |||
| sprite_number: 1, | |||
| }; | |||
| world | |||
| .create_entity() | |||
| .with(ShallowWater { y: 0.0 }) | |||
| .with(scenery_transform.clone()) | |||
| .with(sprite_render) | |||
| .build(); | |||
| // create the deep water entity | |||
| let sprite_render = SpriteRender { | |||
| sprite_sheet: sprite_sheet_handle.clone(), | |||
| sprite_number: 0, | |||
| }; | |||
| world | |||
| .create_entity() | |||
| .with(DeepWater { y: 0.0 }) | |||
| .with(scenery_transform.clone()) | |||
| .with(sprite_render) | |||
| .build(); | |||
| // create the islands entity | |||
| let sprite_render = SpriteRender { | |||
| sprite_sheet: sprite_sheet_handle.clone(), | |||
| sprite_number: 2, | |||
| }; | |||
| world | |||
| .create_entity() | |||
| .with(Islands) | |||
| .with(scenery_transform.clone()) | |||
| .with(sprite_render) | |||
| .build(); | |||
| // create the sky entity | |||
| let sprite_render = SpriteRender { | |||
| sprite_sheet: sprite_sheet_handle.clone(), | |||
| sprite_number: 3, | |||
| }; | |||
| world | |||
| .create_entity() | |||
| .with(Sky) | |||
| .with(scenery_transform.clone()) | |||
| .with(sprite_render) | |||
| .build(); | |||
| // create the sea entity | |||
| let sprite_render = SpriteRender { | |||
| sprite_sheet: sprite_sheet_handle, | |||
| sprite_number: 4, | |||
| }; | |||
| world | |||
| .create_entity() | |||
| .with(Sea) | |||
| .with(scenery_transform) | |||
| .with(sprite_render) | |||
| .build(); | |||
| // create the title entity | |||
| let title_transform = UiTransform::new( | |||
| "title".to_owned(), | |||
| Anchor::TopLeft, | |||
| Anchor::TopLeft, | |||
| 150.0, | |||
| -150.0, | |||
| 1.0, | |||
| 450.0, | |||
| 45.0, | |||
| ); | |||
| world | |||
| .create_entity() | |||
| .with(UiText::new( | |||
| font_asset_handle, | |||
| "Merchant Seas".to_string(), | |||
| [1.0, 1.0, 1.0, 1.0], | |||
| 45.0, | |||
| )) | |||
| .with(title_transform) | |||
| .build(); | |||
| } | |||
| @@ -1,62 +1,5 @@ | |||
| // namespacing | |||
| use amethyst::{ | |||
| core::transform::TransformBundle, | |||
| input::{InputBundle, StringBindings}, | |||
| prelude::*, | |||
| renderer::{ | |||
| plugins::{RenderFlat2D, RenderToWindow}, | |||
| types::DefaultBackend, | |||
| RenderingBundle, | |||
| }, | |||
| ui::{RenderUi, UiBundle}, | |||
| utils::application_root_dir, | |||
| }; | |||
| use bevy::prelude::*; | |||
| mod game; | |||
| // a collection of utility functions | |||
| mod utils; | |||
| fn main() -> amethyst::Result<()> { | |||
| // enable engine logging | |||
| amethyst::start_logger(Default::default()); | |||
| // set up root dir | |||
| let app_root = application_root_dir()?; | |||
| // define assets dir | |||
| let assets = app_root.join("assets"); | |||
| // set up display configuration | |||
| let display_config = app_root.join("config").join("display_config.ron"); | |||
| let render_to_window = | |||
| RenderToWindow::from_config_path(display_config)?.with_clear([1.0, 1.0, 1.0, 1.0]); | |||
| // set up keybindings configuration | |||
| let bindings = app_root.join("config").join("bindings.ron"); | |||
| let input_bundle = InputBundle::<StringBindings>::new().with_bindings_from_file(bindings)?; | |||
| // initialize the game data struct | |||
| let game_data = GameDataBuilder::default() | |||
| // bundle inclusion | |||
| .with_bundle(TransformBundle::new())? | |||
| .with_bundle(input_bundle)? | |||
| .with_bundle(UiBundle::<StringBindings>::new())? | |||
| .with_bundle( | |||
| RenderingBundle::<DefaultBackend>::new() | |||
| .with_plugin(render_to_window) | |||
| .with_plugin(RenderUi::default()) | |||
| .with_plugin(RenderFlat2D::default()), | |||
| )? | |||
| // systems inclusion | |||
| .with( | |||
| utils::systems::ExitGameSystem, | |||
| "exit_system", | |||
| &["input_system"], | |||
| ); | |||
| // create and run the game | |||
| let mut game = Application::new(assets, game::title_screen::TitleScreen, game_data)?; | |||
| game.run(); | |||
| Ok(()) | |||
| fn main() { | |||
| App::build().add_default_plugins().run(); | |||
| } | |||
| @@ -1,53 +0,0 @@ | |||
| /// set of generic systems to be used through out the game | |||
| pub mod systems; | |||
| // namespacing | |||
| use amethyst::{ | |||
| assets::{AssetStorage, Handle, Loader}, | |||
| prelude::*, | |||
| renderer::{ImageFormat, SpriteSheet, SpriteSheetFormat, Texture}, | |||
| ui::{FontAsset, TtfFormat}, | |||
| }; | |||
| /// wrap the image loading functions | |||
| pub fn load_texture<T>(name: T, world: &World) -> Handle<Texture> | |||
| where | |||
| T: Into<String>, | |||
| { | |||
| let loader = world.read_resource::<Loader>(); | |||
| loader.load( | |||
| name, | |||
| ImageFormat::default(), | |||
| (), | |||
| &world.read_resource::<AssetStorage<Texture>>(), | |||
| ) | |||
| } | |||
| /// wrap spritesheet loading | |||
| pub fn load_sprite_sheet<T>( | |||
| name: T, | |||
| world: &World, | |||
| texture_handle: Handle<Texture>, | |||
| ) -> Handle<SpriteSheet> | |||
| where | |||
| T: Into<String>, | |||
| { | |||
| let loader = world.read_resource::<Loader>(); | |||
| let spritesheet_store = world.read_resource::<AssetStorage<SpriteSheet>>(); | |||
| loader.load( | |||
| name, | |||
| SpriteSheetFormat(texture_handle), | |||
| (), | |||
| &spritesheet_store, | |||
| ) | |||
| } | |||
| /// wrap font loading | |||
| pub fn load_font<T>(name: T, world: &World) -> Handle<FontAsset> | |||
| where | |||
| T: Into<String>, | |||
| { | |||
| world | |||
| .read_resource::<Loader>() | |||
| .load(name, TtfFormat, (), &world.read_resource()) | |||
| } | |||