pixel_handler/structs/
grid_position.rs

1use std::{
2    hash::{Hash, Hasher},
3    ops::{Add, AddAssign, Mul},
4};
5
6use ggez::{glam::Vec2, graphics};
7
8#[derive(Debug, Copy, Clone)]
9pub struct GridPosition {
10    pub cell_size: (f32, f32),
11    pub x: i32,
12    pub y: i32,
13}
14
15impl PartialEq for GridPosition {
16    fn eq(&self, other: &Self) -> bool {
17        self.cell_size == other.cell_size && self.x == other.x && self.y == other.y
18    }
19}
20
21impl Eq for GridPosition {}
22
23impl Hash for GridPosition {
24    fn hash<H: Hasher>(&self, state: &mut H) {
25        self.cell_size.0.to_bits().hash(state);
26        self.cell_size.1.to_bits().hash(state);
27        self.x.hash(state);
28        self.y.hash(state);
29    }
30}
31
32impl GridPosition {
33    pub fn new(x: i32, y: i32, cell_size: (f32, f32)) -> Self {
34        let x = x * cell_size.0 as i32;
35        let y = y * cell_size.1 as i32;
36
37        Self { cell_size, x, y }
38    }
39
40    fn round_down(&self, value: f32, multiple: f32) -> f32 {
41        (value / multiple).floor() * multiple
42    }
43
44    fn round_up(&self, value: f32, multiple: f32) -> f32 {
45        (value / multiple).ceil() * multiple
46    }
47
48    pub fn from_vec2(vec: Vec2, cell_size: (f32, f32)) -> Self {
49        let x = (vec.x / cell_size.0).floor() as i32;
50        let y = (vec.y / cell_size.1).floor() as i32;
51
52        Self::new(x, y, cell_size)
53    }
54
55    pub fn as_vec2(&self) -> Vec2 {
56        Vec2::new(self.x as f32, self.y as f32)
57    }
58
59    pub fn as_rect(&self) -> graphics::Rect {
60        graphics::Rect::new(
61            self.x as f32,
62            self.y as f32,
63            self.cell_size.0,
64            self.cell_size.1,
65        )
66    }
67
68    pub fn is_offscreen(&self, ctx: &mut ggez::Context) -> bool {
69        let window_size = ctx.gfx.drawable_size();
70
71        let top = 0.0;
72        let left = 0.0;
73        let bottom = window_size.1 - self.cell_size.1;
74        let right = window_size.0 - self.cell_size.0;
75
76        let position = self.as_vec2();
77
78        return position.x < left 
79            || position.x > right 
80            || position.y < top 
81            || position.y > bottom
82    }
83}
84
85impl AddAssign for GridPosition {
86    fn add_assign(&mut self, other: Self) {
87        self.x += other.x;
88        self.y += other.y;
89    }
90}
91
92impl Add for GridPosition {
93    type Output = Self;
94
95    fn add(self, other: Self) -> Self {
96        Self {
97            cell_size: self.cell_size,
98            x: self.x + other.x,
99            y: self.y + other.y,
100        }
101    }
102}
103
104impl Mul for GridPosition {
105    type Output = Self;
106
107    fn mul(self, other: Self) -> Self {
108        Self {
109            cell_size: self.cell_size,
110            x: self.x * other.x,
111            y: self.y * other.y,
112        }
113    }
114}