Created
January 26, 2019 00:46
-
-
Save zesterer/48b831144d1a594ac6a9978243d3b048 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// 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