
đ Rust Code
use nannou::prelude::*;
struct Particle {
position: Vec2,
velocity: Vec2,
}
struct Model {
particles: Vec<Particle>,
}
fn main() {
nannou::app(model).update(update).run();
}
fn model(app: &App) -> Model {
app.new_window().size(1000, 1000).view(view).build().unwrap();
let mut particles = Vec::new();
let window_rect = app.window_rect();
for _ in 0..5000 {
particles.push(Particle {
position: vec2(
random_f32() * window_rect.w() - window_rect.w() / 2.0,
random_f32() * window_rect.h() - window_rect.h() / 2.0
),
velocity: vec2(random_f32() - 0.5, random_f32() - 0.5) * 2.0,
});
}
Model { particles }
}
fn update(app: &App, model: &mut Model, _update: Update) {
let mouse_pos = app.mouse.position();
for p in &mut model.particles {
let distance_to_mouse = (mouse_pos - p.position).length();
if distance_to_mouse > 0.0 {
let force = (mouse_pos - p.position).normalize() * 0.1;
p.velocity += force;
}
p.position += p.velocity;
let bound = app.window_rect();
let mut bounce = false;
if p.position.x > bound.right() {
p.position.x = bound.right();
p.velocity.x *= -1.0;
bounce = true;
} else if p.position.x < bound.left() {
p.position.x = bound.left();
p.velocity.x *= -1.0;
bounce = true;
}
if p.position.y > bound.top() {
p.position.y = bound.top();
p.velocity.y *= -1.0;
bounce = true;
} else if p.position.y < bound.bottom() {
p.position.y = bound.bottom();
p.velocity.y *= -1.0;
bounce = true;
}
if bounce {
p.velocity *= 0.8;
}
}
}
fn view(app: &App, model: &Model, frame: Frame) {
let draw = app.draw();
draw.background().color(BLACK);
for p in &model.particles {
let speed = p.velocity.length();
let hue = (speed / 10.0).min(1.0);
draw.ellipse()
.xy(p.position)
.radius(1.5)
.color(hsla(hue, 1.0, 0.5, 1.0));
}
let mouse_pos = app.mouse.position();
draw.ellipse()
.xy(mouse_pos)
.radius(8.0)
.color(WHITE)
.stroke(WHITE)
.stroke_weight(2.0);
draw.to_frame(app, &frame).unwrap();
}