• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Xevion / Pac-Man / 16928353819

13 Aug 2025 05:25AM UTC coverage: 53.801% (-0.2%) from 53.972%
16928353819

push

github

Xevion
feat!: dynamic map rendering from tiles

0 of 35 new or added lines in 4 files covered. (0.0%)

2 existing lines in 2 files now uncovered.

1019 of 1894 relevant lines covered (53.8%)

218.54 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

14.74
/src/map/render.rs
1
//! Map rendering functionality.
2

3
use crate::constants::{BOARD_CELL_OFFSET, CELL_SIZE};
4
use crate::map::layout::TILE_MAP;
5
use crate::texture::sprite::{AtlasTile, SpriteAtlas};
6
use crate::texture::text::TextTexture;
7
use glam::Vec2;
8
use sdl2::pixels::Color;
9
use sdl2::rect::{Point, Rect};
10
use sdl2::render::{Canvas, RenderTarget};
11

12
use crate::error::{EntityError, GameError, GameResult};
13

14
/// Handles rendering operations for the map.
15
pub struct MapRenderer;
16

17
impl MapRenderer {
18
    /// Renders the map to the given canvas.
19
    ///
20
    /// This function draws the static map texture to the screen at the correct
21
    /// position and scale.
NEW
22
    pub fn render_map<T: RenderTarget>(canvas: &mut Canvas<T>, atlas: &mut SpriteAtlas, map_tiles: &mut [AtlasTile]) {
×
NEW
23
        for (y, row) in TILE_MAP.iter().enumerate() {
×
NEW
24
            for (x, &tile_index) in row.iter().enumerate() {
×
NEW
25
                let mut tile = map_tiles[tile_index];
×
NEW
26
                tile.color = Some(Color::RGB(0x20, 0x20, 0xf9));
×
NEW
27
                let dest = Rect::new(
×
NEW
28
                    (BOARD_CELL_OFFSET.x as usize * CELL_SIZE as usize + x * CELL_SIZE as usize) as i32,
×
NEW
29
                    (BOARD_CELL_OFFSET.y as usize * CELL_SIZE as usize + y * CELL_SIZE as usize) as i32,
×
NEW
30
                    CELL_SIZE,
×
NEW
31
                    CELL_SIZE,
×
NEW
32
                );
×
33

NEW
34
                if let Err(e) = tile.render(canvas, atlas, dest) {
×
NEW
35
                    tracing::error!("Failed to render map tile: {}", e);
×
NEW
36
                }
×
37
            }
38
        }
39
    }
×
40

41
    /// Renders a debug visualization with cursor-based highlighting.
42
    ///
43
    /// This function provides interactive debugging by highlighting the nearest node
44
    /// to the cursor, showing its ID, and highlighting its connections.
45
    pub fn debug_render_with_cursor<T: RenderTarget>(
×
46
        graph: &crate::entity::graph::Graph,
×
47
        canvas: &mut Canvas<T>,
×
48
        text_renderer: &mut TextTexture,
×
49
        atlas: &mut SpriteAtlas,
×
50
        cursor_pos: Vec2,
×
51
    ) -> GameResult<()> {
×
52
        // Find the nearest node to the cursor
×
53
        let nearest_node = Self::find_nearest_node(graph, cursor_pos);
×
54

×
55
        // Draw all connections in blue
×
56
        canvas.set_draw_color(Color::RGB(0, 0, 128)); // Dark blue for regular connections
×
57
        for i in 0..graph.node_count() {
×
58
            let node = graph.get_node(i).ok_or(GameError::Entity(EntityError::NodeNotFound(i)))?;
×
59
            let pos = node.position + crate::constants::BOARD_PIXEL_OFFSET.as_vec2();
×
60

61
            for edge in graph.adjacency_list[i].edges() {
×
62
                let end_pos = graph
×
63
                    .get_node(edge.target)
×
64
                    .ok_or(GameError::Entity(EntityError::NodeNotFound(edge.target)))?
×
65
                    .position
66
                    + crate::constants::BOARD_PIXEL_OFFSET.as_vec2();
×
67
                canvas
×
68
                    .draw_line((pos.x as i32, pos.y as i32), (end_pos.x as i32, end_pos.y as i32))
×
69
                    .map_err(|e| GameError::Sdl(e.to_string()))?;
×
70
            }
71
        }
72

73
        // Draw all nodes in green
74
        canvas.set_draw_color(Color::RGB(0, 128, 0)); // Dark green for regular nodes
×
75
        for i in 0..graph.node_count() {
×
76
            let node = graph.get_node(i).ok_or(GameError::Entity(EntityError::NodeNotFound(i)))?;
×
77
            let pos = node.position + crate::constants::BOARD_PIXEL_OFFSET.as_vec2();
×
78

×
79
            canvas
×
80
                .fill_rect(Rect::new(0, 0, 3, 3).centered_on(Point::new(pos.x as i32, pos.y as i32)))
×
81
                .map_err(|e| GameError::Sdl(e.to_string()))?;
×
82
        }
83

84
        // Highlight connections from the nearest node in bright blue
85
        if let Some(nearest_id) = nearest_node {
×
86
            let nearest_pos = graph
×
87
                .get_node(nearest_id)
×
88
                .ok_or(GameError::Entity(EntityError::NodeNotFound(nearest_id)))?
×
89
                .position
90
                + crate::constants::BOARD_PIXEL_OFFSET.as_vec2();
×
91

×
92
            canvas.set_draw_color(Color::RGB(0, 255, 255)); // Bright cyan for highlighted connections
×
93
            for edge in graph.adjacency_list[nearest_id].edges() {
×
94
                let end_pos = graph
×
95
                    .get_node(edge.target)
×
96
                    .ok_or(GameError::Entity(EntityError::NodeNotFound(edge.target)))?
×
97
                    .position
98
                    + crate::constants::BOARD_PIXEL_OFFSET.as_vec2();
×
99
                canvas
×
100
                    .draw_line(
×
101
                        (nearest_pos.x as i32, nearest_pos.y as i32),
×
102
                        (end_pos.x as i32, end_pos.y as i32),
×
103
                    )
×
104
                    .map_err(|e| GameError::Sdl(e.to_string()))?;
×
105
            }
106

107
            // Highlight the nearest node in bright green
108
            canvas.set_draw_color(Color::RGB(0, 255, 0)); // Bright green for highlighted node
×
109
            canvas
×
110
                .fill_rect(Rect::new(0, 0, 5, 5).centered_on(Point::new(nearest_pos.x as i32, nearest_pos.y as i32)))
×
111
                .map_err(|e| GameError::Sdl(e.to_string()))?;
×
112

113
            // Draw node ID text (small, offset to top right)
114
            text_renderer.set_scale(0.5); // Small text
×
115
            let id_text = format!("#{nearest_id}");
×
116
            let text_pos = glam::UVec2::new(
×
117
                (nearest_pos.x + 4.0) as u32, // Offset to the right
×
118
                (nearest_pos.y - 6.0) as u32, // Offset to the top
×
119
            );
×
120
            if let Err(e) = text_renderer.render(canvas, atlas, &id_text, text_pos) {
×
121
                tracing::error!("Failed to render node ID text: {}", e);
×
122
            }
×
123
        }
×
124

125
        Ok(())
×
126
    }
×
127

128
    /// Finds the nearest node to the given cursor position.
129
    pub fn find_nearest_node(graph: &crate::entity::graph::Graph, cursor_pos: Vec2) -> Option<usize> {
3✔
130
        let mut nearest_id = None;
3✔
131
        let mut nearest_distance = f32::INFINITY;
3✔
132

133
        for i in 0..graph.node_count() {
9✔
134
            if let Some(node) = graph.get_node(i) {
9✔
135
                let node_pos = node.position + crate::constants::BOARD_PIXEL_OFFSET.as_vec2();
9✔
136
                let distance = cursor_pos.distance(node_pos);
9✔
137

9✔
138
                if distance < nearest_distance {
9✔
139
                    nearest_distance = distance;
6✔
140
                    nearest_id = Some(i);
6✔
141
                }
6✔
142
            }
×
143
        }
144

145
        nearest_id
3✔
146
    }
3✔
147
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc