Skip to content

Instantly share code, notes, and snippets.

@qatoqat
Created October 1, 2022 08:02
Show Gist options
  • Save qatoqat/1e02c1ac03d1cd24cc778a403ec601ea to your computer and use it in GitHub Desktop.
Save qatoqat/1e02c1ac03d1cd24cc778a403ec601ea to your computer and use it in GitHub Desktop.
particle collision
use macroquad::{prelude::*, rand::gen_range};
pub const COUNT: usize = 200;
pub const RADIUS: f32 = 20.0;
#[macroquad::main("Collision")]
async fn main() {
let mut particle_hd = ParticleHandler::new();
let clear_color: Color = Color::from_rgba(25, 30, 50, 255);
loop {
clear_background(clear_color);
particle_hd.update();
particle_hd.draw();
next_frame().await
}
}
#[derive(Clone, Copy)]
struct Particle {
position: [f32; 2],
velocity: [f32; 2],
}
impl Particle {
fn new() -> Particle {
Particle {
position: [0.0, 0.0],
velocity: [0.0, 0.0],
}
}
fn resolve_collision(&mut self, other: Particle) {
let between = [
other.position[0] - self.position[0],
other.position[1] - self.position[1],
];
let length = ((between[0] * between[0]) + (between[1] * between[1])).sqrt();
if length - RADIUS * 2.0 < 0.0 {
let reciprocal_length = 1.0 / length;
let normal = [
between[0] * reciprocal_length,
between[1] * reciprocal_length,
];
let collision_depth = (length - RADIUS * 2.0).abs() * 0.5;
self.position[0] -= normal[0] * collision_depth;
self.position[1] -= normal[1] * collision_depth;
}
}
fn update(&mut self) {
if self.position[0] - RADIUS < 0.0 || self.position[0] + RADIUS > screen_width() {
self.velocity[0] -= self.velocity[0] * 2.0;
}
if self.position[1] - RADIUS < 0.0 || self.position[1] + RADIUS > screen_height() {
self.velocity[1] -= self.velocity[1] * 2.0;
}
self.position[0] += self.velocity[0];
self.position[1] += self.velocity[1];
}
fn draw(&self) {
draw_circle(self.position[0], self.position[1], RADIUS, WHITE)
}
}
struct ParticleHandler {
particles: [Particle; COUNT],
}
impl ParticleHandler {
fn new() -> Self {
let mut particles: [Particle; COUNT] = [Particle::new(); COUNT];
for i in 0..COUNT {
particles[i].position = [
gen_range(RADIUS, screen_width() - RADIUS),
gen_range(RADIUS, screen_height() - RADIUS),
];
particles[i].velocity = [gen_range(-1.0, 1.0), gen_range(-1.0, 1.0)];
}
Self { particles }
}
fn update(&mut self) {
for i in 0..COUNT {
let other = self.particles[i];
for j in 0..COUNT {
if i != j {
let current = self.particles.get_mut(j).unwrap();
current.resolve_collision(other);
}
}
}
for current in &mut self.particles {
current.update();
}
}
fn draw(&self) {
for now in &self.particles {
now.draw();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment