-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathfood.rs
71 lines (61 loc) · 2.1 KB
/
food.rs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
//! This module defines the food type.
use crate::snake::Snake;
use andiskaz::{
coord::{Coord, Vec2},
screen::Screen,
tile::Tile,
};
use gardiz::rect::Rect;
use rand::Rng;
/// A food in the game, or a fruit, or whatever our snake eats.
#[derive(Debug)]
pub struct Food {
/// Position of the food/fruit.
pos: Vec2,
/// The tile of a food/fruit.
tile: Tile,
}
impl Food {
/// Initializes the food, given its tile, as well the generated snake (for
/// random generation purposes) and the bounds of the screen.
pub fn new(tile: Tile, snake: &Snake, bounds: Rect<Coord>) -> Self {
// Initializes with random position.
Self { pos: Self::gen_pos(snake, bounds), tile }
}
/// Generates a new food such that it is in bounds and not in the same place
/// as the snake.
pub fn regenerate(&mut self, snake: &Snake, bounds: Rect<Coord>) {
self.pos = Self::gen_pos(snake, bounds);
}
/// Tests if the food is inside the bounds. Useful when the screen is
/// resized.
pub fn in_bounds(&self, bounds: Rect<Coord>) -> bool {
bounds.has_point(self.pos)
}
/// Returns the position of the food.
pub fn pos(&self) -> Vec2 {
self.pos
}
/// Generates a random position for the food, such that it is inside of the
/// bounds, and it is not at the same place as the snake.
fn gen_pos(snake: &Snake, bounds: Rect<Coord>) -> Vec2 {
loop {
// Initializes the random number generator (RNG).
let mut rng = rand::thread_rng();
// Generates a random point.
let point = Vec2 {
x: rng.gen_range(bounds.start.x .. bounds.end().x),
y: rng.gen_range(bounds.start.y .. bounds.end().y),
};
let valid = !snake.contains(point);
if valid {
// Only stops if the point is not contained by the snake.
break point;
}
}
}
/// Renders the food on the screen.
pub fn render(&self, screen: &mut Screen) {
screen.set(self.pos, self.tile.clone());
}
}