| @@ -5,8 +5,9 @@ authors = ["Isabelle L. <me@izzabelle.dev>"] | |||||
| edition = "2018" | edition = "2018" | ||||
| [dependencies] | [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()) | |||||
| } | |||||