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
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
extern crate line_drawing;
use line_drawing::{Point, Bresenham, BresenhamCircle};
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
pub enum Material {
Wood,
Metal,
Rope
}
#[derive(Debug)]
pub enum Part {
Beam(Beam),
Wheel(Wheel)
}
#[derive(Debug)]
pub struct Beam {
pub start: Point<f64>,
pub end: Point<f64>,
pub material: Material
}
impl Beam {
pub fn new(start: (i32, i32), end: (i32, i32), material: Material) -> Self {
Beam {
material,
start: (start.0 as f64, start.1 as f64),
end: (end.0 as f64, end.1 as f64),
}
}
pub fn draw(&self, dst: &mut [u32], dst_width: usize, offset: (f64, f64)) {
let color = match self.material {
Material::Wood => 0x8F563B,
Material::Metal => 0x696A6A,
Material::Rope => 0xD9A066,
};
let start = ((self.start.0 + offset.0) as i32, (self.start.1 + offset.1) as i32);
let end = ((self.end.0 + offset.0) as i32, (self.end.1 + offset.1) as i32);
for (x, y) in Bresenham::new(start, end) {
dst[x as usize + y as usize * dst_width] = color;
}
}
}
#[derive(Debug)]
pub struct Wheel {
pub pos: Point<f64>,
pub radius: f64,
pub material: Material
}
impl Wheel {
pub fn new(start: (i32, i32), end: (i32, i32), material: Material) -> Self {
let dx = (end.0 - start.0) as f64;
let dy = (end.1 - start.1) as f64;
Wheel {
material,
pos: (start.0 as f64, start.1 as f64),
radius: (dx * dx + dy * dy).sqrt()
}
}
pub fn draw(&self, dst: &mut [u32], dst_width: usize, offset: (f64, f64)) {
let color = match self.material {
Material::Wood => 0x8F563B,
Material::Metal => 0x696A6A,
Material::Rope => 0xD9A066,
};
let pos = ((self.pos.0 + offset.0) as i32, (self.pos.1 + offset.1) as i32);
for (x, y) in BresenhamCircle::new(pos.0, pos.1, self.radius as i32) {
dst[x as usize + y as usize * dst_width] = color;
}
}
}
#[derive(Debug)]
pub struct Engine {
pub pos: Point<f64>,
pub parts: Vec<Part>
}
impl Engine {
pub fn new(x: f64, y: f64) -> Self {
Engine {
pos: (x, y),
parts: Vec::new()
}
}
pub fn render_to_buffer(&self, dst: &mut [u32], dst_width: usize) {
for part in self.parts.iter() {
if let &Part::Beam(ref beam) = part {
beam.draw(dst, dst_width, self.pos);
}
if let &Part::Wheel(ref wheel) = part {
wheel.draw(dst, dst_width, self.pos);
}
}
}
pub fn add_beam(&mut self, start: (i32, i32), end: (i32, i32), material: Material) {
self.parts.push(Part::Beam(Beam::new(start, end, material)));
}
pub fn add_wheel(&mut self, start: (i32, i32), end: (i32, i32), material: Material) {
self.parts.push(Part::Wheel(Wheel::new(start, end, material)));
}
}
#[cfg(test)]
mod tests {
#[test]
fn it_works() {
assert_eq!(2 + 2, 4);
}
}