Skip to content

Commit f472630

Browse files
committed
ran 'cargo fmt' + move spacebar reset hint to after fps counter
1 parent 6f371d5 commit f472630

File tree

1 file changed

+138
-63
lines changed

1 file changed

+138
-63
lines changed

examples/confetti

Lines changed: 138 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,25 @@
1-
use std::u8;
21
use macroquad::prelude::*;
2+
extern crate micromath;
3+
use micromath::F32Ext;
4+
5+
fn clip(pos: f32, bound: f32, velocity: f32) -> f32 {
6+
if pos > bound {
7+
let delta = (pos - bound).abs();
8+
let mut new_velocity = velocity;
9+
if velocity > 0.0 {
10+
new_velocity = -velocity
11+
}
12+
if (new_velocity.abs() + BALL_RADIUS) < delta {
13+
return -delta / get_fps() as f32 * 60.0;
14+
}
15+
return new_velocity * FLOOR_LOSS;
16+
}
17+
velocity
18+
}
19+
20+
fn clip_minus(pos: f32, bound: f32, velocity: f32) -> f32 {
21+
return -clip(bound, pos, -velocity);
22+
}
323

424
#[derive(Debug, Clone, Copy)]
525
pub struct Ball {
@@ -12,109 +32,144 @@ pub struct Ball {
1232
}
1333

1434
// Customizable
15-
const FLOOR_LOSS: f32 = 0.98;
35+
const FLOOR_LOSS: f32 = 0.9;
1636
const DRAG: f32 = 0.998;
1737
const GRAVITY: f32 = 1.0;
38+
const MAX_VEL: f32 = 40.0;
1839

19-
const BALL_RADIUS: f32 = 6.0;
40+
const BALL_RADIUS: f32 = 5.0;
2041

2142
// Please, don't change
22-
static mut BALL_ID : usize = 0;
23-
const BALL_RADIUS_SQR: f32= BALL_RADIUS * BALL_RADIUS;
43+
static mut BALL_ID: usize = 0;
44+
const BALL_RADIUS_SQR: f32 = BALL_RADIUS * BALL_RADIUS;
2445

2546
impl Ball {
26-
fn new(x: f32, y:f32, seed:usize) -> Ball{
47+
fn new(x: f32, y: f32, seed: usize) -> Ball {
2748
let id;
2849
unsafe {
2950
id = BALL_ID;
3051
BALL_ID += 1;
3152
}
3253

33-
let seed = seed % (usize::MAX/64);
34-
let random = (32_1239 * seed*seed*seed* 17 + id)% 1000 ;
54+
let seed = seed % (usize::MAX / 64);
55+
let random = (32_1239 * seed * seed * seed * 17 + id) % 1000;
3556
let x_vel = random % 9;
36-
let x_vel = (x_vel as f32 - 4.0) / 2.0;
37-
38-
return Ball{id, x, y, x_vel, y_vel:0.0, color:Color::from_rgba((random as usize*47%255) as u8, (random as usize*29%255) as u8, (random as usize*101%255) as u8, u8::MAX)}
57+
let x_vel = (x_vel as f32 - 4.0) / 1.5;
58+
59+
return Ball {
60+
id,
61+
x,
62+
y,
63+
x_vel,
64+
y_vel: 0.0,
65+
color: Color::from_rgba(
66+
(random as usize * 47 % 255) as u8,
67+
(random as usize * 29 % 255) as u8,
68+
(random as usize * 101 % 255) as u8,
69+
255,
70+
),
71+
};
3972
}
4073

41-
fn tick(&mut self){
74+
fn tick(&mut self) {
4275
self.x_vel *= DRAG;
4376
self.y_vel *= DRAG;
4477

4578
self.x += self.x_vel;
4679
self.y += self.y_vel;
4780

48-
if self.y > screen_height(){
49-
// self.y = screen_height();
50-
self.y_vel = -self.y_vel * FLOOR_LOSS;
51-
}else{
52-
self.y_vel += GRAVITY;
53-
}
54-
55-
if self.x < 0.0 || self.x > screen_width(){
56-
self.x_vel = -self.x_vel * FLOOR_LOSS;
57-
}
81+
self.x = self.x.clamp(-3000.0, 3000.0);
82+
self.x = if self.x.is_normal() { self.x } else { 0.0 };
83+
self.y = self.y.clamp(-3000.0, 3000.0);
84+
self.y = if self.y.is_normal() { self.y } else { 0.0 };
85+
self.y_vel = self.y_vel.clamp(-MAX_VEL, MAX_VEL);
86+
self.y_vel = if self.y_vel.is_normal() {
87+
self.y_vel
88+
} else {
89+
0.0
90+
};
91+
self.x_vel = self.x_vel.clamp(-MAX_VEL, MAX_VEL);
92+
self.x_vel = if self.x_vel.is_normal() {
93+
self.x_vel
94+
} else {
95+
0.0
96+
};
97+
98+
self.y_vel = clip(self.y, screen_height(), self.y_vel + GRAVITY);
99+
self.x_vel = clip(self.x, screen_width(), self.x_vel);
100+
self.x_vel = clip_minus(self.x, 0.0, self.x_vel);
101+
self.y_vel = clip_minus(self.y, -screen_height(), self.y_vel);
58102
}
59103

60-
fn draw(&self){
61-
draw_circle(self.x, self.y-BALL_RADIUS, BALL_RADIUS, self.color);
104+
fn draw(&self) {
105+
draw_circle(self.x, self.y - BALL_RADIUS, BALL_RADIUS, self.color);
62106
}
63107

64108
fn collide(&mut self, balls: &[Ball]) {
65-
for other in balls {
66-
if other.id == self.id {
67-
continue;
68-
}
109+
unsafe {
110+
let skip = (BALL_ID / 1000).max(8);
69111

70-
let dx = self.x - other.x;
71-
let dy = self.y - other.y;
72-
let distance_sqr = dx * dx + dy * dy;
112+
for other in balls {
113+
if other.id == self.id || other.id % 10 < skip {
114+
continue;
115+
}
73116

74-
if distance_sqr > BALL_RADIUS_SQR {
75-
continue;
76-
}
117+
let dx = self.x - other.x;
118+
let dy = self.y - other.y;
119+
let distance_sqr = dx * dx + dy * dy;
77120

78-
let distance = distance_sqr.sqrt();
79-
if distance == 0.0 {
80-
continue;
81-
}
82-
let nx = dx / distance;
83-
let ny = dy / distance;
121+
if distance_sqr > BALL_RADIUS_SQR {
122+
continue;
123+
}
84124

85-
let relative_velocity_x = self.x_vel - other.x_vel;
86-
let relative_velocity_y = self.y_vel - other.y_vel;
87-
let relative_velocity_normal = relative_velocity_x * nx + relative_velocity_y * ny;
125+
let distance = distance_sqr.sqrt();
126+
if distance == 0.0 {
127+
continue;
128+
}
129+
let nx = dx / distance;
130+
let ny = dy / distance;
88131

89-
if relative_velocity_normal > 0.0 {
90-
continue;
91-
}
132+
let relative_velocity_x = self.x_vel - other.x_vel;
133+
let relative_velocity_y = self.y_vel - other.y_vel;
134+
let relative_velocity_normal = relative_velocity_x * nx + relative_velocity_y * ny;
92135

93-
let impulse = (2.0 * relative_velocity_normal) / 2.0 * FLOOR_LOSS;
136+
if relative_velocity_normal > 0.0 {
137+
continue;
138+
}
94139

95-
self.x_vel -= impulse * nx;
96-
self.y_vel -= impulse * ny;
140+
let impulse = (2.0 * relative_velocity_normal) / 2.0 * FLOOR_LOSS;
141+
142+
self.x_vel -= (impulse * nx).clamp(-MAX_VEL, MAX_VEL);
143+
self.y_vel -= (impulse * ny).clamp(-MAX_VEL, MAX_VEL);
144+
}
97145
}
98146
}
99-
100147
}
101148

102149
#[macroquad::main("AM - Confetti")]
103150
async fn main() {
104-
105151
let mut balls: Vec<Ball> = Vec::new();
106152
let mut frame_count: usize = 0;
107153
loop {
108154
// Loop start
109155
frame_count += 1;
110-
clear_background(Color { r: 0.95, g: 0.9, b: 0.9, a: 1.0 });
156+
clear_background(Color {
157+
r: 0.95,
158+
g: 0.9,
159+
b: 0.9,
160+
a: 1.0,
161+
});
111162

112163
// Handle Inputs
113-
if is_mouse_button_down(MouseButton::Left) || is_mouse_button_pressed(MouseButton::Right) {
114-
let (mouse_x,mouse_y) = mouse_position();
115-
balls.push(Ball::new(mouse_x, mouse_y ,frame_count))
164+
if is_mouse_button_down(MouseButton::Left) {
165+
let (mouse_x, mouse_y) = mouse_position();
166+
balls.push(Ball::new(mouse_x, mouse_y, frame_count));
167+
balls.push(Ball::new(mouse_x, mouse_y, frame_count));
168+
}
169+
if is_mouse_button_pressed(MouseButton::Right) {
170+
let (mouse_x, mouse_y) = mouse_position();
171+
balls.push(Ball::new(mouse_x, mouse_y, frame_count))
116172
}
117-
118173
if is_key_pressed(KeyCode::Space) {
119174
unsafe {
120175
BALL_ID = 0;
@@ -123,24 +178,44 @@ async fn main() {
123178
}
124179

125180
// Handle Tick
126-
let balls_prev = balls.to_vec();
181+
let balls_prev = balls.to_vec();
127182
for ball in &mut balls {
128183
ball.collide(&balls_prev);
129184
ball.tick();
130185
ball.draw();
131-
}
186+
}
132187

133188
unsafe {
134189
if BALL_ID == 0 {
135-
draw_text("Click anywhere to begin!", screen_width()/2.0 - 240.0, screen_height()/2.0, 48.0, RED);
136-
}else{
137-
draw_text(&format!("Balls{}: {}", if BALL_ID > 999 {" (Press Space to Reset)"} else {""}, BALL_ID), 15.0, 25.0, 32.0, BLACK);
138-
}
190+
draw_text(
191+
"Click anywhere to begin!",
192+
screen_width() / 2.0 - 240.0,
193+
screen_height() / 2.0,
194+
48.0,
195+
RED,
196+
);
197+
} else {
198+
draw_text(
199+
&format!(
200+
"Balls: {}\nFPS: {} {}",
201+
BALL_ID,
202+
get_fps(),
203+
if BALL_ID > 1000 {
204+
"(Press Space to Reset)"
205+
} else {
206+
""
207+
}
208+
),
209+
15.0,
210+
25.0,
211+
32.0,
212+
BLACK,
213+
);
214+
}
139215
}
140216

141217
next_frame().await
142218
}
143219
}
144-
145220
// Andrew McCall <3
146221
// https://github.com/Andrew-McCall/MacroquadConfetti

0 commit comments

Comments
 (0)