Skip to content

Instantly share code, notes, and snippets.

@zesterer
Created January 26, 2019 00:46
Show Gist options
  • Save zesterer/48b831144d1a594ac6a9978243d3b048 to your computer and use it in GitHub Desktop.
Save zesterer/48b831144d1a594ac6a9978243d3b048 to your computer and use it in GitHub Desktop.
// Library
use vek::*;
use quicksilver::{
Result,
geom::{Line, Circle, Transform, Vector},
graphics::{Background::Col, Color},
lifecycle::{Settings, State, Window, run},
};
struct Point {
pos: Vec2<f32>,
vel: Vec2<f32>,
}
impl Point {
pub fn tick(&mut self) {
self.pos += self.vel;
self.vel.y += 0.5;
if self.pos.y >= 600.0 {
self.pos.y = 600.0;
self.vel.y = 0.0;
self.vel.x *= 0.9;
}
}
}
struct Body {
points: Vec<Point>,
joints: Vec<(usize, usize, f32)>,
}
impl Body {
pub fn new() -> Self {
Self {
points: vec![],
joints: vec![],
}
}
pub fn tick(&mut self) {
for point in &mut self.points {
point.tick();
}
for (a, b, dist) in &self.joints {
let a_pos = self.points[*a].pos;
let b_pos = self.points[*b].pos;
let rdist = (a_pos - b_pos).magnitude() - dist;
let atob = (b_pos - a_pos).normalized();
self.points[*a].vel += atob * rdist * 0.1;
self.points[*b].vel -= atob * rdist * 0.1;
}
}
}
struct World {
bodies: Vec<Body>,
}
impl State for World {
fn new() -> Result<Self> {
let mut body = Body::new();
body.points.push(Point { pos: Vec2::new(32.0, 32.0), vel: Vec2::new(5.0, 0.0) }); // top left
body.points.push(Point { pos: Vec2::new(128.0, 32.0), vel: Vec2::zero() }); // top right
body.points.push(Point { pos: Vec2::new(32.0, 128.0), vel: Vec2::zero() }); // bottom left
body.points.push(Point { pos: Vec2::new(128.0, 128.0), vel: Vec2::zero() }); // bottom right
body.points.push(Point { pos: Vec2::new(250.0, 32.0), vel: Vec2::zero() }); // top right right
body.points.push(Point { pos: Vec2::new(250.0, 128.0), vel: Vec2::zero() }); // bottom right right
body.joints.push((0, 1, 100.0));
body.joints.push((2, 3, 100.0));
body.joints.push((0, 2, 100.0));
body.joints.push((1, 3, 100.0));
body.joints.push((0, 3, 141.0));
body.joints.push((1, 2, 141.0));
body.joints.push((1, 4, 122.0));
body.joints.push((3, 5, 122.0));
body.joints.push((4, 5, 100.0));
body.joints.push((4, 3, 161.0));
body.joints.push((1, 5, 161.0));
Ok(Self {
bodies: vec![body],
})
}
fn draw(&mut self, window: &mut Window) -> Result<()> {
window.clear(Color::BLACK);
for body in &self.bodies {
for (a, b, _) in &body.joints {
let a_pos = body.points[*a].pos;
let b_pos = body.points[*b].pos;
window.draw_ex(
&Line::new((a_pos.x, a_pos.y), (b_pos.x, b_pos.y)).with_thickness(4.0),
Col(Color::RED),
Transform::IDENTITY,
5,
);
}
for point in &body.points {
window.draw(&Circle::new((point.pos.x, point.pos.y), 5), Col(Color::GREEN));
}
}
for body in &mut self.bodies {
body.tick();
}
Ok(())
}
}
fn main() {
run::<World>("Darwin", Vector::new(800, 600), Settings::default());
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment