| @@ -0,0 +1 @@ | |||||
| /target | |||||
| @@ -0,0 +1,13 @@ | |||||
| [package] | |||||
| name = "unnamed" | |||||
| version = "0.1.0" | |||||
| authors = ["isabelle"] | |||||
| edition = "2018" | |||||
| # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html | |||||
| [dependencies] | |||||
| ggez = "0.5.1" | |||||
| thiserror = "1.0.20" | |||||
| serde = { version = "1.0.114", features = ["derive"] } | |||||
| toml = "0.5.6" | |||||
| @@ -0,0 +1,6 @@ | |||||
| [window_mode] | |||||
| width = 1024 | |||||
| height = 768 | |||||
| [window_setup] | |||||
| title = "unnamed" | |||||
| resizable = false | |||||
| @@ -0,0 +1,3 @@ | |||||
| [nothing] | |||||
| path = "img/tiles/nothing.png" | |||||
| blocking = true | |||||
| @@ -0,0 +1,53 @@ | |||||
| mod util; | |||||
| mod world; | |||||
| use ggez::{ | |||||
| event::{self, EventHandler}, | |||||
| graphics, Context, ContextBuilder, GameResult, | |||||
| }; | |||||
| use world::World; | |||||
| pub type Result<T> = std::result::Result<T, Error>; | |||||
| #[derive(Debug, thiserror::Error)] | |||||
| pub enum Error { | |||||
| #[error(transparent)] | |||||
| Stdio(#[from] std::io::Error), | |||||
| #[error(transparent)] | |||||
| Toml(#[from] toml::de::Error), | |||||
| } | |||||
| struct MainState { | |||||
| world: World, | |||||
| } | |||||
| impl MainState { | |||||
| pub fn new(_ctx: &mut Context) -> MainState { | |||||
| MainState { | |||||
| world: World::new(20, 20, 3), | |||||
| } | |||||
| } | |||||
| } | |||||
| impl EventHandler for MainState { | |||||
| fn update(&mut self, _ctx: &mut Context) -> GameResult<()> { | |||||
| Ok(()) | |||||
| } | |||||
| fn draw(&mut self, ctx: &mut Context) -> GameResult<()> { | |||||
| graphics::clear(ctx, graphics::WHITE); | |||||
| graphics::present(ctx) | |||||
| } | |||||
| } | |||||
| fn main() { | |||||
| let (mut ctx, mut event_loop) = ContextBuilder::new("unnamed", "Isabelle L.") | |||||
| .build() | |||||
| .expect("failed to start context"); | |||||
| let mut state = MainState::new(&mut ctx); | |||||
| if let Err(err) = event::run(&mut ctx, &mut event_loop, &mut state) { | |||||
| eprintln!("an error occured: {:?}", err); | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,69 @@ | |||||
| use std::convert::From; | |||||
| pub struct CartesianVector(usize, usize); | |||||
| pub struct IsometricVector(usize, usize); | |||||
| pub struct Vector3d(usize, usize, usize); | |||||
| impl Vector3d { | |||||
| pub fn x(&self) -> usize { | |||||
| self.0 | |||||
| } | |||||
| pub fn y(&self) -> usize { | |||||
| self.1 | |||||
| } | |||||
| pub fn z(&self) -> usize { | |||||
| self.2 | |||||
| } | |||||
| } | |||||
| impl From<(usize, usize, usize)> for Vector3d { | |||||
| fn from(tuple: (usize, usize, usize)) -> Vector3d { | |||||
| Vector3d(tuple.0, tuple.1, tuple.2) | |||||
| } | |||||
| } | |||||
| impl CartesianVector { | |||||
| pub fn x(&self) -> usize { | |||||
| self.0 | |||||
| } | |||||
| pub fn y(&self) -> usize { | |||||
| self.1 | |||||
| } | |||||
| } | |||||
| impl IsometricVector { | |||||
| pub fn x(&self) -> usize { | |||||
| self.0 | |||||
| } | |||||
| pub fn y(&self) -> usize { | |||||
| self.1 | |||||
| } | |||||
| } | |||||
| impl From<(usize, usize)> for CartesianVector { | |||||
| fn from(tuple: (usize, usize)) -> CartesianVector { | |||||
| CartesianVector(tuple.0, tuple.1) | |||||
| } | |||||
| } | |||||
| impl From<IsometricVector> for CartesianVector { | |||||
| fn from(iso: IsometricVector) -> CartesianVector { | |||||
| CartesianVector((2 * iso.y() + iso.x()) / 2, (2 * iso.y() - iso.x()) / 2) | |||||
| } | |||||
| } | |||||
| impl From<CartesianVector> for IsometricVector { | |||||
| fn from(cart: CartesianVector) -> IsometricVector { | |||||
| IsometricVector(cart.x() - cart.y(), (cart.x() + cart.y()) / 2) | |||||
| } | |||||
| } | |||||
| impl From<(usize, usize)> for IsometricVector { | |||||
| fn from(tuple: (usize, usize)) -> IsometricVector { | |||||
| IsometricVector(tuple.0, tuple.1) | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,23 @@ | |||||
| mod tile; | |||||
| use crate::util::Vector3d; | |||||
| use std::collections::HashMap; | |||||
| use tile::*; | |||||
| pub struct World { | |||||
| width: usize, | |||||
| height: usize, | |||||
| depth: usize, | |||||
| data: HashMap<Vector3d, Tile>, | |||||
| } | |||||
| impl World { | |||||
| pub fn new(width: usize, height: usize, depth: usize) -> World { | |||||
| World { | |||||
| width, | |||||
| height, | |||||
| depth, | |||||
| data: HashMap::new(), | |||||
| } | |||||
| } | |||||
| } | |||||
| @@ -0,0 +1,48 @@ | |||||
| use crate::Result; | |||||
| use ggez::graphics::Image; | |||||
| use ggez::Context; | |||||
| use serde::Deserialize; | |||||
| use std::collections::HashMap; | |||||
| use std::path::PathBuf; | |||||
| use std::rc::Rc; | |||||
| pub struct TileBuilder { | |||||
| textures: HashMap<String, MasterTile>, | |||||
| } | |||||
| impl TileBuilder { | |||||
| pub fn new(ctx: &mut Context, tiles_config: PathBuf) -> Result<TileBuilder> { | |||||
| let raw_data = std::fs::read_to_string(tiles_config)?; | |||||
| let raw_map: HashMap<String, RawTile> = toml::from_str(&raw_data)?; | |||||
| let mut textures: HashMap<String, MasterTile> = HashMap::new(); | |||||
| raw_map.iter().for_each(|(kind, raw_tile)| { | |||||
| let tile = MasterTile { | |||||
| texture: Image::new(ctx, &raw_tile.path).expect("failed to load image"), | |||||
| kind: kind.to_owned(), | |||||
| blocking: raw_tile.blocking, | |||||
| }; | |||||
| textures.insert(kind.to_owned(), tile); | |||||
| }); | |||||
| Ok(TileBuilder { textures: textures }) | |||||
| } | |||||
| } | |||||
| pub struct Tile { | |||||
| texture: Rc<Image>, | |||||
| kind: String, | |||||
| blocking: bool, | |||||
| } | |||||
| struct MasterTile { | |||||
| texture: Image, | |||||
| kind: String, | |||||
| blocking: bool, | |||||
| } | |||||
| #[derive(Deserialize)] | |||||
| struct RawTile { | |||||
| path: PathBuf, | |||||
| blocking: bool, | |||||
| } | |||||