From 6f809f525fc2ab6b93cff48b55abe104699eb3d8 Mon Sep 17 00:00:00 2001 From: Nao Pross Date: Mon, 17 Dec 2018 15:33:56 +0100 Subject: Implement loading of tile sets --- src/graphics.rs | 87 ++++++++++++++++++++++++++++++++++++++++----------------- src/main.rs | 18 ++++++------ 2 files changed, 71 insertions(+), 34 deletions(-) diff --git a/src/graphics.rs b/src/graphics.rs index 0edb4ad..947992a 100644 --- a/src/graphics.rs +++ b/src/graphics.rs @@ -9,6 +9,7 @@ use sfml::graphics::{ RenderWindow, RenderTarget, Texture, + Image, Color, Rect, }; @@ -51,43 +52,77 @@ pub fn render(window: &mut RenderWindow, state: &crate::game::State) { window.clear(&bgcolor); - // load tilesets - let mut textures: HashMap = HashMap::new(); - for tileset in &state.map.tilesets { - - let image = &tileset.images[0]; - let asset = Assets::get(&image.source); - - if let Some(asset) = asset { - let texture = Texture::from_memory( - asset.as_ref(), - &Rect { - left: 0, - top: 0, - width: image.width, - height: image.height - } - ); - - if let Some(texture) = texture { - textures.insert(tileset.first_gid, texture); - } - } - } - // render map + // loaded textures + // TODO: cache outside of this function + let mut tilesets: HashMap = HashMap::new(); + let mut textures: HashMap = HashMap::new(); + // for each tile for y in 0 .. state.map.height { for x in 0 .. state.map.width { // for each layer for layer in &state.map.layers { - state.map.get_tileset_by_gid(layer.tiles[y as usize][x as usize]); + let tmx_tile = layer.tiles[y as usize][x as usize]; + + let tmx_tileset = match state.map.get_tileset_by_gid(tmx_tile) { + Some(tileset) => tileset, + None => continue + }; + + // load tileset if not loaded yet + // TODO: load in a separate thread? + if !tilesets.contains_key(&tmx_tileset.first_gid) { + // TODO: replace with iter or error message + assert_eq!(tmx_tileset.images.len(), 1); + + (|| { + // load tileset image + let tmx_image = &tmx_tileset.images[0]; + + let asset = match Assets::get(&tmx_image.source) { + Some(asset) => asset, + None => return, + }; + + let image = match Image::from_memory(asset.as_ref()) { + Some(image) => image, + None => return, + }; + + // load tiles (textures) + let tileset_width = tmx_image.width as u32 / tmx_tileset.tile_width; + let tileset_height = tmx_image.height as u32 / tmx_tileset.tile_height; + + for ty in 0 .. tileset_height { + for tx in 0 .. tileset_width { + let texture = match Texture::from_image_with_rect( + &image, &Rect::new( + (tx * tmx_tileset.tile_width) as i32, + (ty * tmx_tileset.tile_height) as i32, + tmx_tileset.tile_width as i32, + tmx_tileset.tile_height as i32 + ) + ) { + Some(texture) => texture, + None => continue, + }; + // save tile texture + textures.insert(tmx_tile, texture); + } + } + + // save tileset image + tilesets.insert(tmx_tileset.first_gid, image); + })(); + } + + // } } } - window.display(); } diff --git a/src/main.rs b/src/main.rs index 3cf9d47..b5190bf 100644 --- a/src/main.rs +++ b/src/main.rs @@ -45,14 +45,16 @@ fn main() { graphics::update(&mut window); } - // aquire state resource - let mut game_state = match game_state.lock() { - Ok(game_state) => game_state, - Err(poisoned) => poisoned.into_inner(), - }; - - // stop game thread - game_state.running = false; + { + // aquire state resource + let mut game_state = match game_state.lock() { + Ok(game_state) => game_state, + Err(poisoned) => poisoned.into_inner(), + }; + + // stop game thread + game_state.running = false; + } }); // wait for both thread to die -- cgit v1.2.1