diff --git a/.gitignore b/.gitignore index 869df07..93688a9 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ /target +/demo/target Cargo.lock \ No newline at end of file diff --git a/README.md b/README.md index 8c6697f..a15efcb 100644 --- a/README.md +++ b/README.md @@ -2,7 +2,6 @@ [![Build Status](https://travis-ci.org/klangner/mapgen.rs.svg?branch=master)](https://travis-ci.org/klangner/mapgen.rs) [![Crates.io](https://img.shields.io/crates/v/mapgen.svg)](https://crates.io/crates/mapgen) -[![Crates.io](https://img.shields.io/crates/l/mapgen.svg)](https://github.com/klangner/mapgen.rs/blob/master/LICENSE-MIT) [![mapgen.rs](https://docs.rs/mapgen/badge.svg)](https://docs.rs/mapgen/) Generate procedural maps for games. diff --git a/demo/Cargo.toml b/demo/Cargo.toml new file mode 100644 index 0000000..f329aea --- /dev/null +++ b/demo/Cargo.toml @@ -0,0 +1,15 @@ +[package] +name = "mapgen-demo" +version = "0.1.0" +authors = ["Krzysztof Langner "] +edition = "2018" + +[dependencies] +amethyst = {version = "0.15", features = ["tiles", "no-slow-safety-checks"]} +log = { version = "0.4.8", features = ["serde"] } +mapgen = {path=".."} + +[features] +default = ["metal"] +metal = ["amethyst/metal"] +vulkan = ["amethyst/vulkan"] diff --git a/demo/assets/texture/cp437_20x20.png b/demo/assets/texture/cp437_20x20.png new file mode 100644 index 0000000..e7e2f5f Binary files /dev/null and b/demo/assets/texture/cp437_20x20.png differ diff --git a/demo/assets/texture/cp437_20x20.ron b/demo/assets/texture/cp437_20x20.ron new file mode 100644 index 0000000..41fb405 --- /dev/null +++ b/demo/assets/texture/cp437_20x20.ron @@ -0,0 +1,8 @@ +#![enable(implicit_some)] + +Grid(( + texture_width: 320, + texture_height: 320, + columns: 16, + rows: 16, +)) \ No newline at end of file diff --git a/demo/config/display.ron b/demo/config/display.ron new file mode 100644 index 0000000..c5a98fd --- /dev/null +++ b/demo/config/display.ron @@ -0,0 +1,4 @@ +( + title: "mapgen demo", + dimensions: Some((840, 520)), +) \ No newline at end of file diff --git a/demo/config/input.ron b/demo/config/input.ron new file mode 100644 index 0000000..cb5dae1 --- /dev/null +++ b/demo/config/input.ron @@ -0,0 +1,27 @@ + +( + axes: { + "camera_x": Emulated( + pos: Key(D), + neg: Key(A), + ), + "camera_y": Emulated( + pos: Key(W), + neg: Key(S), + ), + "camera_scale": Emulated( + pos: Key(E), + neg: Key(Q), + ), + "camera_z": Emulated( + pos: Key(R), + neg: Key(F), + ), + }, + actions: { + "camera_switch": [[Key(Space)]], + "select": [[Mouse(Left)]], + "toggle_rotation": [[Key(Y)]], + "toggle_translation": [[Key(T)]], + }, +) \ No newline at end of file diff --git a/demo/src/main.rs b/demo/src/main.rs new file mode 100644 index 0000000..83d7d92 --- /dev/null +++ b/demo/src/main.rs @@ -0,0 +1,150 @@ +use amethyst::{ + assets::{AssetStorage, Loader}, + core::{ + math::{Point3, Vector3}, + Transform, TransformBundle, + }, + ecs::Entity, + input::{is_close_requested, is_key_down, InputBundle, StringBindings}, + prelude::*, + renderer::{ + camera::Camera, + formats::texture::ImageFormat, + sprite::{SpriteSheet, SpriteSheetFormat, SpriteSheetHandle}, + types::DefaultBackend, + RenderFlat2D, RenderToWindow, RenderingBundle, Texture, + }, + tiles::{MortonEncoder, RenderTiles2D, Tile, TileMap}, + utils::application_root_dir, + window::ScreenDimensions, + winit, +}; +use mapgen::dungeon::{ + map::{Map, TileType}, +}; + + +#[derive(Default, Clone)] +struct MapTiles ; + +impl Tile for MapTiles { + fn sprite(&self, p: Point3, world: &World) -> Option { + let map = world.read_resource::(); + if map.at(p.x as usize, p.y as usize) == TileType::Wall { + Some(35) + } else { + Some(46) + } + } +} + +fn load_tiles_sprite_sheet(world: &mut World, png_path: &str, ron_path: &str) -> SpriteSheetHandle { + let texture_handle = { + let loader = world.read_resource::(); + let texture_storage = world.read_resource::>(); + loader.load(png_path, ImageFormat::default(), (), &texture_storage) + }; + let loader = world.read_resource::(); + let sprite_sheet_store = world.read_resource::>(); + loader.load( + ron_path, + SpriteSheetFormat(texture_handle), + (), + &sprite_sheet_store, + ) +} + +fn init_camera(world: &mut World, transform: Transform, camera: Camera) -> Entity { + world + .create_entity() + .with(transform) + .with(camera) + .named("camera") + .build() +} + + +struct PlayState; +impl SimpleState for PlayState { + fn on_start(&mut self, data: StateData<'_, GameData<'_, '_>>) { + + let world = data.world; + + // Create map + let map = Map::new(80, 50); + world.insert(map); + + let map_sprite_sheet_handle = + load_tiles_sprite_sheet(world, "texture/cp437_20x20.png", "texture/cp437_20x20.ron"); + + let (width, height) = { + let dim = world.read_resource::(); + (dim.width(), dim.height()) + }; + + let _camera = init_camera( + world, + Transform::from(Vector3::new(-10.0, 10.0, 1.1)), + Camera::standard_2d(width, height), + ); + + let tile_map = TileMap::::new( + Vector3::new(80, 50, 1), + Vector3::new(20, 20, 1), + Some(map_sprite_sheet_handle), + ); + + let _map_entity = world + .create_entity() + .with(tile_map) + .with(Transform::default()) + .build(); + } + + fn handle_event( + &mut self, + data: StateData<'_, GameData<'_, '_>>, + event: StateEvent, + ) -> SimpleTrans { + let StateData { .. } = data; + if let StateEvent::Window(event) = &event { + if is_close_requested(&event) || is_key_down(&event, winit::VirtualKeyCode::Escape) { + Trans::Quit + } else { + Trans::None + } + } else { + Trans::None + } + } +} + +fn main() -> amethyst::Result<()> { + amethyst::Logger::from_config(Default::default()) + .level_for("demo", log::LevelFilter::Warn) + .start(); + + let app_root = application_root_dir()?; + let assets_directory = app_root.join("assets"); + let display_config_path = app_root.join("config/display.ron"); + + let game_data = GameDataBuilder::default() + .with_bundle(TransformBundle::new())? + .with_bundle( + InputBundle::::new() + .with_bindings_from_file("config/input.ron")?, + )? + .with_bundle( + RenderingBundle::::new() + .with_plugin( + RenderToWindow::from_config_path(display_config_path)? + .with_clear([0.0, 0.0, 0.0, 1.0]), + ) + .with_plugin(RenderFlat2D::default()) + .with_plugin(RenderTiles2D::::default()), + )?; + + let mut game = Application::build(assets_directory, PlayState)?.build(game_data)?; + game.run(); + Ok(()) +} \ No newline at end of file diff --git a/src/dungeon/map.rs b/src/dungeon/map.rs index b2a9d42..2a0260f 100644 --- a/src/dungeon/map.rs +++ b/src/dungeon/map.rs @@ -6,15 +6,15 @@ pub enum TileType { #[derive(Default, Clone)] pub struct Map { pub tiles : Vec, - pub width : i32, - pub height : i32, + pub width : usize, + pub height : usize, } impl Map { /// Generates an empty map, consisting entirely of solid walls - pub fn new(width: i32, height: i32) -> Map { - let map_tile_count = (width*height) as usize; + pub fn new(width: usize, height: usize) -> Map { + let map_tile_count = width*height; Map{ tiles : vec![TileType::Wall; map_tile_count], width, @@ -22,8 +22,8 @@ impl Map { } } - pub fn at(&self, x: i32, y: i32) -> TileType { - let idx = (y as usize * self.width as usize) + x as usize; + pub fn at(&self, x: usize, y: usize) -> TileType { + let idx = y * self.width + x; self.tiles[idx] }