mirror of
https://github.com/Xevion/Pac-Man.git
synced 2025-12-14 14:12:26 -06:00
test: setup common submodule, add text.rs tests, pattern exclude error.rs
This commit is contained in:
@@ -49,53 +49,74 @@ use glam::UVec2;
|
||||
use sdl2::render::{Canvas, RenderTarget};
|
||||
use std::collections::HashMap;
|
||||
|
||||
use crate::texture::sprite::{AtlasTile, SpriteAtlas};
|
||||
use crate::{
|
||||
error::{GameError, TextureError},
|
||||
texture::sprite::{AtlasTile, SpriteAtlas},
|
||||
};
|
||||
|
||||
/// Converts a character to its tile name in the atlas.
|
||||
fn char_to_tile_name(c: char) -> Option<String> {
|
||||
let name = match c {
|
||||
// Letters A-Z
|
||||
'A'..='Z' | '0'..='9' => format!("text/{c}.png"),
|
||||
// Special characters
|
||||
'!' => "text/!.png".to_string(),
|
||||
'-' => "text/-.png".to_string(),
|
||||
'"' => "text/_double_quote.png".to_string(),
|
||||
'/' => "text/_forward_slash.png".to_string(),
|
||||
// Skip spaces for now - they don't have a tile
|
||||
' ' => return None,
|
||||
|
||||
// Unsupported character
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
Some(name)
|
||||
}
|
||||
|
||||
/// A text texture that renders characters from the atlas.
|
||||
#[derive(Debug)]
|
||||
pub struct TextTexture {
|
||||
char_map: HashMap<char, AtlasTile>,
|
||||
scale: f32,
|
||||
}
|
||||
|
||||
impl Default for TextTexture {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
scale: 1.0,
|
||||
char_map: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl TextTexture {
|
||||
/// Creates a new text texture with the given atlas and scale.
|
||||
/// Creates a new text texture with the given scale.
|
||||
pub fn new(scale: f32) -> Self {
|
||||
Self {
|
||||
char_map: HashMap::new(),
|
||||
scale,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
|
||||
/// Maps a character to its atlas tile, handling special characters.
|
||||
fn get_char_tile(&mut self, atlas: &SpriteAtlas, c: char) -> Option<AtlasTile> {
|
||||
if let Some(tile) = self.char_map.get(&c) {
|
||||
return Some(*tile);
|
||||
}
|
||||
|
||||
let tile_name = self.char_to_tile_name(c)?;
|
||||
let tile = atlas.get_tile(&tile_name)?;
|
||||
self.char_map.insert(c, tile);
|
||||
Some(tile)
|
||||
pub fn get_char_map(&self) -> &HashMap<char, AtlasTile> {
|
||||
&self.char_map
|
||||
}
|
||||
|
||||
/// Converts a character to its tile name in the atlas.
|
||||
fn char_to_tile_name(&self, c: char) -> Option<String> {
|
||||
let name = match c {
|
||||
// Letters A-Z
|
||||
'A'..='Z' | '0'..='9' => format!("text/{c}.png"),
|
||||
// Special characters
|
||||
'!' => "text/!.png".to_string(),
|
||||
'-' => "text/-.png".to_string(),
|
||||
'"' => "text/_double_quote.png".to_string(),
|
||||
'/' => "text/_forward_slash.png".to_string(),
|
||||
// Skip spaces for now - they don't have a tile
|
||||
' ' => return None,
|
||||
pub fn get_tile(&mut self, c: char, atlas: &mut SpriteAtlas) -> Result<Option<&mut AtlasTile>> {
|
||||
if self.char_map.contains_key(&c) {
|
||||
return Ok(self.char_map.get_mut(&c));
|
||||
}
|
||||
|
||||
// Unsupported character
|
||||
_ => return None,
|
||||
};
|
||||
|
||||
Some(name)
|
||||
if let Some(tile_name) = char_to_tile_name(c) {
|
||||
let tile = atlas
|
||||
.get_tile(&tile_name)
|
||||
.ok_or(GameError::Texture(TextureError::AtlasTileNotFound(tile_name)))?;
|
||||
self.char_map.insert(c, tile);
|
||||
Ok(self.char_map.get_mut(&c))
|
||||
} else {
|
||||
Ok(None)
|
||||
}
|
||||
}
|
||||
|
||||
/// Renders a string of text at the given position.
|
||||
@@ -108,13 +129,16 @@ impl TextTexture {
|
||||
) -> Result<()> {
|
||||
let mut x_offset = 0;
|
||||
let char_width = (8.0 * self.scale) as u32;
|
||||
let char_height = (8.0 * self.scale) as u32;
|
||||
let char_height = self.text_height();
|
||||
|
||||
for c in text.chars() {
|
||||
if let Some(mut tile) = self.get_char_tile(atlas, c) {
|
||||
// Get the tile from the char_map, or insert it if it doesn't exist
|
||||
if let Some(tile) = self.get_tile(c, atlas)? {
|
||||
// Render the tile if it exists
|
||||
let dest = sdl2::rect::Rect::new((position.x + x_offset) as i32, position.y as i32, char_width, char_height);
|
||||
tile.render(canvas, atlas, dest)?;
|
||||
}
|
||||
|
||||
// Always advance x_offset for all characters (including spaces)
|
||||
x_offset += char_width;
|
||||
}
|
||||
@@ -138,7 +162,7 @@ impl TextTexture {
|
||||
let mut width = 0;
|
||||
|
||||
for c in text.chars() {
|
||||
if self.char_to_tile_name(c).is_some() {
|
||||
if char_to_tile_name(c).is_some() || c == ' ' {
|
||||
width += char_width;
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user