From 775b0148cec4329a6abb19d03220dc1d8a8b68c3 Mon Sep 17 00:00:00 2001 From: metamuffin Date: Tue, 16 Jul 2024 23:38:46 +0200 Subject: rename pixel client --- pixel-client/src/tilemap.rs | 117 ++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 117 insertions(+) create mode 100644 pixel-client/src/tilemap.rs (limited to 'pixel-client/src/tilemap.rs') 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 . + +*/ +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>, + connect_members_by_group: Vec>>, + tile_srcs: Vec<[Rect; 16]>, + tiles: HashMap, +} + +impl Tilemap { + pub fn init(&mut self, tile_names: &[String], sprite_rects: &HashMap) { + let tile_index = tile_names + .iter() + .enumerate() + .map(|(t, i)| (i.to_string(), t)) + .collect::>(); + 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::>() + }) + .collect::>(); + + 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, neighbors: [Option; 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); + } + } +} -- cgit v1.2.3-70-g09d2