Skip to content

Commit 183d5c7

Browse files
committed
ran Cargo fmt + moved spacebar reset hit to after fps
1 parent 6f371d5 commit 183d5c7

File tree

2 files changed

+221
-146
lines changed

2 files changed

+221
-146
lines changed

examples/confetti

Lines changed: 0 additions & 146 deletions
This file was deleted.

examples/confetti.rs

Lines changed: 221 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,221 @@
1+
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+
}
23+
24+
#[derive(Debug, Clone, Copy)]
25+
pub struct Ball {
26+
id: usize,
27+
x: f32,
28+
y: f32,
29+
x_vel: f32,
30+
y_vel: f32,
31+
color: Color,
32+
}
33+
34+
// Customizable
35+
const FLOOR_LOSS: f32 = 0.9;
36+
const DRAG: f32 = 0.998;
37+
const GRAVITY: f32 = 1.0;
38+
const MAX_VEL: f32 = 40.0;
39+
40+
const BALL_RADIUS: f32 = 5.0;
41+
42+
// Please, don't change
43+
static mut BALL_ID: usize = 0;
44+
const BALL_RADIUS_SQR: f32 = BALL_RADIUS * BALL_RADIUS;
45+
46+
impl Ball {
47+
fn new(x: f32, y: f32, seed: usize) -> Ball {
48+
let id;
49+
unsafe {
50+
id = BALL_ID;
51+
BALL_ID += 1;
52+
}
53+
54+
let seed = seed % (usize::MAX / 64);
55+
let random = (32_1239 * seed * seed * seed * 17 + id) % 1000;
56+
let x_vel = random % 9;
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+
};
72+
}
73+
74+
fn tick(&mut self) {
75+
self.x_vel *= DRAG;
76+
self.y_vel *= DRAG;
77+
78+
self.x += self.x_vel;
79+
self.y += self.y_vel;
80+
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);
102+
}
103+
104+
fn draw(&self) {
105+
draw_circle(self.x, self.y - BALL_RADIUS, BALL_RADIUS, self.color);
106+
}
107+
108+
fn collide(&mut self, balls: &[Ball]) {
109+
unsafe {
110+
let skip = (BALL_ID / 1000).max(8);
111+
112+
for other in balls {
113+
if other.id == self.id || other.id % 10 < skip {
114+
continue;
115+
}
116+
117+
let dx = self.x - other.x;
118+
let dy = self.y - other.y;
119+
let distance_sqr = dx * dx + dy * dy;
120+
121+
if distance_sqr > BALL_RADIUS_SQR {
122+
continue;
123+
}
124+
125+
let distance = distance_sqr.sqrt();
126+
if distance == 0.0 {
127+
continue;
128+
}
129+
let nx = dx / distance;
130+
let ny = dy / distance;
131+
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;
135+
136+
if relative_velocity_normal > 0.0 {
137+
continue;
138+
}
139+
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+
}
145+
}
146+
}
147+
}
148+
149+
#[macroquad::main("AM - Confetti")]
150+
async fn main() {
151+
let mut balls: Vec<Ball> = Vec::new();
152+
let mut frame_count: usize = 0;
153+
loop {
154+
// Loop start
155+
frame_count += 1;
156+
clear_background(Color {
157+
r: 0.95,
158+
g: 0.9,
159+
b: 0.9,
160+
a: 1.0,
161+
});
162+
163+
// Handle Inputs
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))
172+
}
173+
if is_key_pressed(KeyCode::Space) {
174+
unsafe {
175+
BALL_ID = 0;
176+
balls.clear();
177+
}
178+
}
179+
180+
// Handle Tick
181+
let balls_prev = balls.to_vec();
182+
for ball in &mut balls {
183+
ball.collide(&balls_prev);
184+
ball.tick();
185+
ball.draw();
186+
}
187+
188+
unsafe {
189+
if BALL_ID == 0 {
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+
}
215+
}
216+
217+
next_frame().await
218+
}
219+
}
220+
// Andrew McCall <3
221+
// https://github.com/Andrew-McCall/MacroquadConfetti

0 commit comments

Comments
 (0)