bleh no like
parent
a600ec9147
commit
5e5aec6c19
File diff suppressed because it is too large
Load Diff
|
@ -6,9 +6,12 @@ edition = "2021"
|
|||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
nalgebra = { version = "0.32.3", features = ["glam017"] }
|
||||
nannou = "0.19.0"
|
||||
rapier2d = "0.18.0"
|
||||
bevy = { version = "0.12.1" }
|
||||
bevy_dylib = "0.12.1"
|
||||
bevy_rapier2d = "*"
|
||||
|
||||
[profile.dev]
|
||||
opt-level = 1
|
||||
|
||||
[profile.dev.package."*"]
|
||||
opt-level = 3
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
[toolchain]
|
||||
channel = "nightly"
|
|
@ -1,30 +0,0 @@
|
|||
use nannou::prelude::*;
|
||||
|
||||
pub(crate) trait Drawable {
|
||||
fn draw(&self, draw: &Draw);
|
||||
}
|
||||
|
||||
impl<T> Drawable for Vec<T>
|
||||
where
|
||||
T: Drawable,
|
||||
{
|
||||
fn draw(&self, draw: &Draw) {
|
||||
self.iter().for_each(|s| s.draw(draw))
|
||||
}
|
||||
}
|
||||
|
||||
pub(crate) trait DrawShape<T>
|
||||
where
|
||||
T: Drawable,
|
||||
{
|
||||
fn draw(&self, drawable: &T);
|
||||
}
|
||||
|
||||
impl<T> DrawShape<T> for Draw
|
||||
where
|
||||
T: Drawable,
|
||||
{
|
||||
fn draw(&self, drawable: &T) {
|
||||
drawable.draw(self);
|
||||
}
|
||||
}
|
126
src/main.rs
126
src/main.rs
|
@ -1,88 +1,44 @@
|
|||
mod drawable;
|
||||
mod particle;
|
||||
|
||||
use drawable::DrawShape;
|
||||
use nannou::prelude::*;
|
||||
use particle::Particle;
|
||||
|
||||
const PARTICLE_COUNT: u32 = 200;
|
||||
const PARTICLE_SIZE: f32 = 10.0;
|
||||
|
||||
struct Model {
|
||||
// Store the window ID so we can refer to this specific window later if needed.
|
||||
_window: WindowId,
|
||||
particles: Vec<Particle>,
|
||||
}
|
||||
|
||||
fn fill_particles(app: &App, particles: &mut Vec<Particle>) {
|
||||
let boundary = app.window_rect();
|
||||
|
||||
for _ in 0..PARTICLE_COUNT {
|
||||
let x = random_range(boundary.left(), boundary.right());
|
||||
let y = random_range(boundary.top(), boundary.bottom());
|
||||
|
||||
let particle = Particle::new(Vec2::new(x, y));
|
||||
|
||||
particles.push(particle);
|
||||
}
|
||||
}
|
||||
|
||||
fn model(app: &App) -> Model {
|
||||
// One thing that tripped me up when begginning nannou was realizing
|
||||
// that view and event methods are per window, and update functions are
|
||||
// per app
|
||||
|
||||
// Create a new window! Store the ID so we can refer to it later.
|
||||
let _window = app
|
||||
.new_window()
|
||||
.size(512, 512)
|
||||
.title("nannou")
|
||||
.view(view) // The function that will be called for presenting graphics to a frame.
|
||||
.event(event) // The function that will be called when the window receives events.
|
||||
.build()
|
||||
.unwrap();
|
||||
|
||||
let mut particles = Vec::new();
|
||||
|
||||
fill_particles(app, &mut particles);
|
||||
|
||||
Model { _window, particles }
|
||||
}
|
||||
|
||||
// Handle events related to the window and update the model if necessary
|
||||
fn event(app: &App, model: &mut Model, event: WindowEvent) {
|
||||
if let KeyReleased(Key::Escape) = event {
|
||||
app.quit()
|
||||
}
|
||||
|
||||
if let Resized(_) = event {
|
||||
model.particles.clear();
|
||||
|
||||
fill_particles(app, &mut model.particles);
|
||||
}
|
||||
|
||||
println!("{:?}", event);
|
||||
}
|
||||
|
||||
// Update the state of your application here. By default, this gets called right before `view`.
|
||||
fn update(_app: &App, _model: &mut Model, _update: Update) {
|
||||
_model.particles.iter_mut().for_each(|particle| {
|
||||
let offset = (_app.time + particle.time_offset).sin() * 100.0;
|
||||
particle.pos.x = particle.start_pos.x + offset
|
||||
});
|
||||
}
|
||||
|
||||
// Draw the state of your `Model` into the given `Frame` here.
|
||||
fn view(app: &App, model: &Model, frame: Frame) {
|
||||
let canvas = app.draw();
|
||||
canvas.background().color(CORNFLOWERBLUE);
|
||||
|
||||
canvas.draw(&model.particles);
|
||||
|
||||
// I don't think there is even a fail condition in this function, but it returns a result?
|
||||
canvas.to_frame(app, &frame).unwrap();
|
||||
}
|
||||
use bevy::prelude::*;
|
||||
use bevy_rapier2d::prelude::*;
|
||||
|
||||
fn main() {
|
||||
nannou::app(model).update(update).run();
|
||||
App::new()
|
||||
.add_plugins(DefaultPlugins)
|
||||
.add_plugins(RapierPhysicsPlugin::<NoUserData>::pixels_per_meter(100.0))
|
||||
.add_plugins(RapierDebugRenderPlugin::default())
|
||||
.add_systems(Startup, setup_graphics)
|
||||
.add_systems(Startup, setup_physics)
|
||||
.add_systems(Update, print_ball_altitude)
|
||||
.run();
|
||||
}
|
||||
|
||||
fn setup_graphics(mut commands: Commands) {
|
||||
// Add a camera so we can see the debug-render.
|
||||
commands.spawn(Camera2dBundle::default());
|
||||
}
|
||||
|
||||
fn setup_physics(mut commands: Commands) {
|
||||
/* Create the ground. */
|
||||
commands
|
||||
.spawn(Collider::cuboid(500.0, 50.0))
|
||||
.insert(TransformBundle::from(Transform::from_xyz(0.0, -100.0, 0.0)));
|
||||
|
||||
/* Create the bouncing ball. */
|
||||
commands
|
||||
.spawn(RigidBody::Dynamic)
|
||||
.insert(Collider::ball(10.0))
|
||||
.insert(Restitution::coefficient(2.0))
|
||||
.insert(TransformBundle::from(Transform::from_xyz(0.0, 400.0, 0.0)));
|
||||
|
||||
commands
|
||||
.spawn(RigidBody::Dynamic)
|
||||
.insert(Collider::ball(10.0))
|
||||
.insert(Restitution::coefficient(2.0))
|
||||
.insert(TransformBundle::from(Transform::from_xyz(0.0, 600.0, 0.0)));
|
||||
}
|
||||
|
||||
fn print_ball_altitude(positions: Query<&Transform, With<RigidBody>>) {
|
||||
for transform in positions.iter() {
|
||||
println!("Ball altitude: {}", transform.translation.y);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,43 +0,0 @@
|
|||
use crate::drawable::Drawable;
|
||||
use crate::PARTICLE_SIZE;
|
||||
|
||||
use nannou::prelude::*;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub struct Particle {
|
||||
pub pos: Vec2,
|
||||
pub start_pos: Vec2,
|
||||
pub radius: f32,
|
||||
pub time_offset: f32,
|
||||
}
|
||||
|
||||
impl Particle {
|
||||
pub fn new(pos: Vec2) -> Self {
|
||||
Self {
|
||||
pos,
|
||||
start_pos: pos,
|
||||
..Default::default()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Particle {
|
||||
fn default() -> Self {
|
||||
Self {
|
||||
pos: Default::default(),
|
||||
radius: PARTICLE_SIZE,
|
||||
start_pos: Default::default(),
|
||||
time_offset: random_range(-PI, PI),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Drawable for Particle {
|
||||
fn draw(&self, draw: &Draw) {
|
||||
draw.ellipse()
|
||||
.color(RED)
|
||||
.stroke_weight(1.0)
|
||||
.radius(self.radius)
|
||||
.xy(self.pos);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue