-
Notifications
You must be signed in to change notification settings - Fork 4
/
Copy pathball_collection.rs
105 lines (101 loc) · 3.23 KB
/
ball_collection.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
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
use wasm_bindgen::prelude::*;
use ball::Ball;
use render;
#[wasm_bindgen]
extern "C" {
#[wasm_bindgen(js_namespace = console)]
fn log(message: String);
}
#[wasm_bindgen]
#[derive(Debug)]
pub struct BallCollection {
balls: Vec<Ball>,
}
#[wasm_bindgen]
impl BallCollection {
#[wasm_bindgen(constructor, catch)]
pub fn new() -> BallCollection {
BallCollection { balls: Vec::new() }
}
pub fn push(&mut self, ball: Ball) {
self.balls.push(ball);
}
pub fn fill(
&mut self,
quantity: i32,
radius: f64,
mass: f64,
gravity: f64,
elasticity: f64,
friction: f64,
) {
for _ in 0..quantity {
let ball = Ball::new(
0.0, 0.0, 0.0, 0.0, radius, mass, gravity, elasticity, friction,
);
self.push(ball);
}
}
pub fn len(&self) -> usize {
self.balls.len()
}
fn step(&mut self) {
self.balls.iter_mut().for_each(|ball| {
ball.step();
})
}
fn manage_stage_border_collision(&mut self, stage_width: f64, stage_height: f64) {
self.balls.iter_mut().for_each(|ball| {
ball.manage_stage_border_collision(stage_width, stage_height);
})
}
pub fn update(&mut self, stage_width: f64, stage_height: f64) {
// move balls
self.step();
// check balls vs border collision
self.manage_stage_border_collision(stage_width, stage_height);
// check ball vs ball collision
for i in 0..self.balls.len() {
// divide self.balls (mutable slice) into two mutable slices at an index (i + 1) - https://doc.rust-lang.org/std/vec/struct.Vec.html#method.split_at_mut
let (balls_mut_slice_left, ball_mut_slice_right) = self.balls.split_at_mut(i + 1);
for j in 0..ball_mut_slice_right.len() {
if balls_mut_slice_left[i].check_ball_collision(&mut ball_mut_slice_right[j])
== true
{
balls_mut_slice_left[i].resolve_ball_collision(&mut ball_mut_slice_right[j]);
}
}
}
}
#[wasm_bindgen(js_name=drawToCtx)]
pub fn draw_to_ctx(
&self,
ctx: &web_sys::CanvasRenderingContext2d,
color: &JsValue,
stage_width: f64,
stage_height: f64,
) {
ctx.clear_rect(0.0, 0.0, stage_width, stage_height);
self.balls.iter().for_each(|ball| {
// log("each".to_string());
render::draw_wasm_ball_to_ctx(ball, ctx, color);
})
}
#[wasm_bindgen(js_name=drawToHtml)]
pub fn draw_to_html(&self, color: &JsValue) -> String {
let mut markup = String::new();
for &ref ball in self.balls.iter() {
markup.push_str(&render::draw_wasm_ball_to_html(ball, color));
}
return markup;
}
#[wasm_bindgen(js_name=setRandomPositionAndSpeedInBounds)]
pub fn set_random_position_and_speed_in_bounds(&mut self, stage_width: f64, stage_height: f64) {
for ball in self.balls.iter_mut() {
ball.set_random_position_and_speed_in_bounds(stage_width, stage_height);
}
}
pub fn format(&self) -> String {
format!("{:?}", self)
}
}