diff options
author | metamuffin <metamuffin@disroot.org> | 2024-07-16 23:38:46 +0200 |
---|---|---|
committer | metamuffin <metamuffin@disroot.org> | 2024-07-16 23:38:46 +0200 |
commit | 775b0148cec4329a6abb19d03220dc1d8a8b68c3 (patch) | |
tree | 9e715df1db4f23a9c3f1e9c07cf7e93e376b512f /pixel-client/src/tilemap.rs | |
parent | 3a358c6dd39aa78319549658adf1028cea61f643 (diff) | |
download | hurrycurry-775b0148cec4329a6abb19d03220dc1d8a8b68c3.tar hurrycurry-775b0148cec4329a6abb19d03220dc1d8a8b68c3.tar.bz2 hurrycurry-775b0148cec4329a6abb19d03220dc1d8a8b68c3.tar.zst |
rename pixel client
Diffstat (limited to 'pixel-client/src/tilemap.rs')
-rw-r--r-- | pixel-client/src/tilemap.rs | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/pixel-client/src/tilemap.rs b/pixel-client/src/tilemap.rs new file mode 100644 index 00000000..768f79ba --- /dev/null +++ b/pixel-client/src/tilemap.rs @@ -0,0 +1,117 @@ +/* + Hurry Curry! - a game about cooking + Copyright 2024 metamuffin + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU Affero General Public License as published by + the Free Software Foundation, version 3 of the License only. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU Affero General Public License for more details. + + You should have received a copy of the GNU Affero General Public License + along with this program. If not, see <https://www.gnu.org/licenses/>. + +*/ +use hurrycurry_protocol::{glam::IVec2, TileIndex}; +use log::warn; +use sdl2::rect::Rect; +use std::collections::{HashMap, HashSet}; + +use crate::render::{ + sprite::{Sprite, SpriteDraw}, + SpriteRenderer, +}; + +#[derive(Default)] +pub struct Tilemap { + connect_group_by_tile: Vec<Option<usize>>, + connect_members_by_group: Vec<HashSet<Option<TileIndex>>>, + tile_srcs: Vec<[Rect; 16]>, + tiles: HashMap<IVec2, SpriteDraw>, +} + +impl Tilemap { + pub fn init(&mut self, tile_names: &[String], sprite_rects: &HashMap<String, Rect>) { + let tile_index = tile_names + .iter() + .enumerate() + .map(|(t, i)| (i.to_string(), t)) + .collect::<HashMap<_, _>>(); + self.connect_group_by_tile = vec![None; tile_names.len()]; + self.connect_members_by_group = include_str!("../assets/connect.csv") + .lines() + .enumerate() + .map(|(gid, line)| { + line.split(",") + .flat_map(|tile| tile_index.get(tile).copied()) + .map(|ti| { + self.connect_group_by_tile[ti] = Some(gid); + Some(TileIndex(ti)) + }) + .collect::<HashSet<_>>() + }) + .collect::<Vec<_>>(); + + self.tile_srcs = tile_names + .iter() + .map(|name| { + let fallback = sprite_rects + .get(&format!("{name}+a")) + .copied() + .unwrap_or_else(|| { + warn!("no sprite for tile {name:?}"); + Rect::new(0, 0, 0, 0) + }); + + [ + sprite_rects.get(&format!("{name}+")), + sprite_rects.get(&format!("{name}+w")), + sprite_rects.get(&format!("{name}+e")), + sprite_rects.get(&format!("{name}+we")), + sprite_rects.get(&format!("{name}+n")), + sprite_rects.get(&format!("{name}+wn")), + sprite_rects.get(&format!("{name}+en")), + sprite_rects.get(&format!("{name}+wen")), + sprite_rects.get(&format!("{name}+s")), + sprite_rects.get(&format!("{name}+ws")), + sprite_rects.get(&format!("{name}+es")), + sprite_rects.get(&format!("{name}+wes")), + sprite_rects.get(&format!("{name}+ns")), + sprite_rects.get(&format!("{name}+wns")), + sprite_rects.get(&format!("{name}+ens")), + sprite_rects.get(&format!("{name}+wens")), + ] + .map(|e| e.copied().unwrap_or(fallback)) + }) + .collect(); + } + + pub fn set(&mut self, pos: IVec2, tile: Option<TileIndex>, neighbors: [Option<TileIndex>; 4]) { + let Some(tile) = tile else { + self.tiles.remove(&pos); + return; + }; + + let mut idx = 0; + if let Some(gid) = self.connect_group_by_tile[tile.0] { + let cgroup = &self.connect_members_by_group[gid]; + idx |= 0b0100 * (cgroup.contains(&neighbors[0])) as usize; + idx |= 0b0001 * (cgroup.contains(&neighbors[1])) as usize; + idx |= 0b1000 * (cgroup.contains(&neighbors[2])) as usize; + idx |= 0b0010 * (cgroup.contains(&neighbors[3])) as usize; + } + + let src = self.tile_srcs[tile.0][idx]; + self.tiles + .insert(pos, Sprite::new_tile(src).at(pos.as_vec2())); + } + + pub fn draw(&self, ctx: &mut SpriteRenderer) { + for &sprite in self.tiles.values() { + ctx.draw_world(sprite); + } + } +} |