|
@@ -157,12 +157,6 @@ impl<Idx: Tile> Board<Idx> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
- // fn sprite_location(ch: u8) -> [f32; 4] {
|
|
|
- // let u = f32::from(ch % 16) * TILE_SIZE;
|
|
|
- // let v = f32::from(ch / 16) * TILE_SIZE;
|
|
|
- // [u, v, TILE_SIZE, TILE_SIZE]
|
|
|
- // }
|
|
|
-
|
|
|
pub fn draw(&self, ctx: &mut Context) -> Result<(), ggez::GameError> {
|
|
|
self.tileset.batch.draw(ctx, DrawParam::new())
|
|
|
}
|
|
@@ -220,23 +214,20 @@ impl Board<CP437> {
|
|
|
}
|
|
|
|
|
|
|
|
|
-
|
|
|
-pub struct Game<Idx> {
|
|
|
+pub struct World<Idx> {
|
|
|
pub world: specs::World,
|
|
|
idx: std::marker::PhantomData<Idx>,
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-impl<Idx: Tile + 'static> Game<Idx> {
|
|
|
- pub fn create(_name: &str, _author: &str, board: Board<Idx>) -> Result<Game<Idx>, ggez::GameError> {
|
|
|
+impl <Idx: Tile + 'static> World<Idx> {
|
|
|
+ pub fn new(board: Board<Idx>) -> World<Idx> {
|
|
|
let mut world = specs::World::new();
|
|
|
world.insert(board);
|
|
|
- Ok(Game {
|
|
|
+ World {
|
|
|
world,
|
|
|
idx: std::marker::PhantomData,
|
|
|
- })
|
|
|
+ }
|
|
|
}
|
|
|
-
|
|
|
pub fn set(&mut self, at: impl Into<Coord>, ch: Idx) {
|
|
|
self.world.fetch_mut::<Board<Idx>>().set(at, ch)
|
|
|
}
|
|
@@ -257,14 +248,13 @@ impl<Idx: Tile + 'static> Game<Idx> {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-impl Game<CP437> {
|
|
|
+impl World<CP437> {
|
|
|
pub fn print(&mut self, at: impl Into<Coord>, msg: &str) {
|
|
|
self.world.fetch_mut::<Board<CP437>>().print(at, msg)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-
|
|
|
-impl<Idx: 'static + Tile> ggez::event::EventHandler for Game<Idx> {
|
|
|
+impl<Idx: 'static + Tile> ggez::event::EventHandler for World<Idx> {
|
|
|
fn draw(&mut self, ctx: &mut Context) -> Result<(), ggez::GameError> {
|
|
|
ggez::graphics::clear(ctx, ggez::graphics::BLACK);
|
|
|
self.world.fetch::<Board<Idx>>().draw(ctx)?;
|
|
@@ -275,3 +265,105 @@ impl<Idx: 'static + Tile> ggez::event::EventHandler for Game<Idx> {
|
|
|
Ok(())
|
|
|
}
|
|
|
}
|
|
|
+
|
|
|
+//
|
|
|
+
|
|
|
+pub struct Game<Idx> {
|
|
|
+ pub ctx: ggez::Context,
|
|
|
+ pub evloop: ggez::event::EventsLoop,
|
|
|
+ pub world: World<Idx>,
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+impl<Idx: Tile + 'static> Game<Idx> {
|
|
|
+ pub fn create(board: Board<Idx>, ctx: ggez::Context, evloop: ggez::event::EventsLoop) -> Result<Game<Idx>, ggez::GameError> {
|
|
|
+ let world = World::new(board);
|
|
|
+ Ok(Game {
|
|
|
+ world,
|
|
|
+ ctx,
|
|
|
+ evloop,
|
|
|
+ })
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn run(self) -> ggez::GameResult<()> {
|
|
|
+ let Game { mut world, mut ctx, mut evloop } = self;
|
|
|
+ ggez::event::run(&mut ctx, &mut evloop, &mut world)
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+// game builder
|
|
|
+use std::path::PathBuf;
|
|
|
+
|
|
|
+pub struct GameBuilder<Idx: Tile> {
|
|
|
+ name: String,
|
|
|
+ author: String,
|
|
|
+ resource_path: Option<PathBuf>,
|
|
|
+ tile_size: Option<[usize;2]>,
|
|
|
+ tile_path: Option<PathBuf>,
|
|
|
+ map_size: Option<[usize;2]>,
|
|
|
+ idx: std::marker::PhantomData<Idx>,
|
|
|
+}
|
|
|
+
|
|
|
+impl<Idx: Tile + 'static> GameBuilder<Idx> {
|
|
|
+ pub fn new() -> GameBuilder<Idx> {
|
|
|
+ GameBuilder {
|
|
|
+ name: "Carpet Game".to_owned(),
|
|
|
+ author: "unknown author".to_owned(),
|
|
|
+ resource_path: None,
|
|
|
+ tile_size: None,
|
|
|
+ tile_path: None,
|
|
|
+ map_size: None,
|
|
|
+ idx: std::marker::PhantomData,
|
|
|
+ }
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn name(mut self, name: impl Into<String>) -> GameBuilder<Idx> {
|
|
|
+ self.name = name.into();
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn author(mut self, author: impl Into<String>) -> GameBuilder<Idx> {
|
|
|
+ self.author = author.into();
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn resource_path(mut self, path: impl AsRef<Path>) -> GameBuilder<Idx> {
|
|
|
+ self.resource_path = Some(path.as_ref().to_path_buf());
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn tileset(mut self, image: impl AsRef<Path>, size: impl Into<[usize;2]>) -> GameBuilder<Idx> {
|
|
|
+ self.tile_path = Some(image.as_ref().to_path_buf());
|
|
|
+ self.tile_size = Some(size.into());
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn map_size(mut self, width: usize, height: usize) -> GameBuilder<Idx> {
|
|
|
+ self.map_size = Some([width, height]);
|
|
|
+ self
|
|
|
+ }
|
|
|
+
|
|
|
+ pub fn build(self) -> ggez::GameResult<Game<Idx>> {
|
|
|
+ use ggez::error::GameError::ResourceLoadError;
|
|
|
+ let resource_path = self.resource_path
|
|
|
+ .ok_or_else(|| ResourceLoadError("No resource path specified".to_owned()))?;
|
|
|
+ let tile_path = self.tile_path
|
|
|
+ .ok_or_else(|| ResourceLoadError("No tile path specified".to_owned()))?;
|
|
|
+ let tile_size = self.tile_size
|
|
|
+ .ok_or_else(|| ResourceLoadError("No tile size specified".to_owned()))?;
|
|
|
+ let map_size = self.map_size
|
|
|
+ .ok_or_else(|| ResourceLoadError("No map size specified".to_owned()))?;
|
|
|
+ let (mut ctx, evloop) = ggez::ContextBuilder::new(&self.name, &self.author)
|
|
|
+ .add_resource_path(resource_path)
|
|
|
+ .window_mode(ggez::conf::WindowMode {
|
|
|
+ width: (tile_size[0] * map_size[0]) as f32,
|
|
|
+ height: (tile_size[1] * map_size[1]) as f32,
|
|
|
+ ..ggez::conf::WindowMode::default()
|
|
|
+ })
|
|
|
+ .build()?;
|
|
|
+ let tileset = Tileset::from_file(&mut ctx, tile_size, tile_path)?;
|
|
|
+ let board = Board::new(map_size, tileset);
|
|
|
+ Game::create(board, ctx, evloop)
|
|
|
+ }
|
|
|
+}
|