wip rails

This commit is contained in:
Matthew Deville 2026-09-26 17:38:36 +02:00
parent e6f69c8cd8
commit 800f03b668

View file

@ -22,7 +22,10 @@ fn main() {
)) ))
.insert_resource(Time::<Physics>::default().with_relative_speed(5.0)) .insert_resource(Time::<Physics>::default().with_relative_speed(5.0))
.insert_resource(DefaultRestitution( .insert_resource(DefaultRestitution(
Restitution::PERFECTLY_ELASTIC.with_combine_rule(CoefficientCombine::Max), Restitution {
coefficient: 0.5,
combine_rule: CoefficientCombine::Average,
}
)) ))
.add_systems(Startup, setup) .add_systems(Startup, setup)
.add_systems( .add_systems(
@ -51,11 +54,50 @@ fn setup(
) { ) {
commands.spawn(Camera2d); commands.spawn(Camera2d);
setup_pachinko_rail(&mut commands, &mut meshes, &mut materials);
if let Ok(window) = window.single() { if let Ok(window) = window.single() {
spawn_screen_edges(&mut commands, &mut meshes, &mut materials, window.size()); spawn_screen_edges(&mut commands, &mut meshes, &mut materials, window.size());
} }
} }
#[derive(Component)]
pub struct PachinkoRail {
pub points: Vec<Vec2>,
}
fn setup_pachinko_rail(commands: &mut Commands, meshes: &mut Assets<Mesh>, materials: &mut Assets<ColorMaterial>) {
// Control points in world space (y up). The spline passes through each one.
// Bottom-left entry -> straight up the left wall -> arc over the top -> into the pin zone.
let control_points = [
Vec2::new(-320.0, -260.0), // rail entry (launch point)
Vec2::new(-330.0, -120.0),
Vec2::new(-330.0, 60.0),
Vec2::new(-320.0, 200.0),
Vec2::new(-260.0, 280.0), // start of the top arc
Vec2::new(-160.0, 310.0),
Vec2::new(-60.0, 290.0), // crest, curving down
Vec2::new(0.0, 240.0), // exit: ball drops into the pins here
];
// Catmull-Rom is a cardinal spline with tension 0.5.
// Lower tension = rounder, higher = tighter corners.
let curve = CubicCardinalSpline::new(0.5, control_points)
.to_curve()
.expect("need at least 2 control points");
let points: Vec<Vec2> = curve.iter_positions(128).collect();
commands.spawn((
RigidBody::Static,
Collider::polyline(points.clone(), None),
Mesh2d(meshes.add(Polyline2d::new(points.iter().copied()))),
MeshMaterial2d(materials.add(Color::srgb_u8(255, 255, 255))),
Transform::from_xyz(0.0, 0.0, 0.0),
PachinkoRail { points },
));
}
#[derive(Component, Clone, Copy)] #[derive(Component, Clone, Copy)]
struct Ball; struct Ball;
@ -75,10 +117,12 @@ fn spawn_ball(
&& let Some(cursor_position) = window.cursor_position() && let Some(cursor_position) = window.cursor_position()
&& let Ok(world_position) = camera.viewport_to_world_2d(camera_transform, cursor_position) && let Ok(world_position) = camera.viewport_to_world_2d(camera_transform, cursor_position)
{ {
println!("world_position: {:?}", world_position);
commands.spawn(( commands.spawn((
RigidBody::Dynamic, RigidBody::Dynamic,
Collider::circle(CIRCLE_RADIUS), Collider::circle(CIRCLE_RADIUS),
LinearVelocity(Vec2::new(time.elapsed_secs().sin(), time.elapsed_secs().cos()) * 100.0), LinearVelocity(Vec2::new(-100.0, 200.0)),
Mesh2d(meshes.add(Circle::new(CIRCLE_RADIUS))), Mesh2d(meshes.add(Circle::new(CIRCLE_RADIUS))),
MeshMaterial2d(materials.add(Color::hsl(time.elapsed_secs().sin() * 360.0, 1.0, 0.5))), MeshMaterial2d(materials.add(Color::hsl(time.elapsed_secs().sin() * 360.0, 1.0, 0.5))),
Transform::from_xyz(world_position.x, world_position.y, 0.0), Transform::from_xyz(world_position.x, world_position.y, 0.0),